On Tue, Jan 02, 2018 at 02:54:49PM +0800, Sean Fu wrote:
> Modify write_page free_buffers and read_page to support circular buffer
> list.
> 
> Signed-off-by: Sean Fu <[email protected]>
> ---
>  drivers/md/md-bitmap.c | 36 +++++++++++++++++++-----------------
>  1 file changed, 19 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/md/md-bitmap.c b/drivers/md/md-bitmap.c
> index 239c7bb..b8412c2 100644
> --- a/drivers/md/md-bitmap.c
> +++ b/drivers/md/md-bitmap.c
> @@ -286,7 +286,7 @@ static void bitmap_file_kick(struct bitmap *bitmap);
>   */
>  static void write_page(struct bitmap *bitmap, struct page *page, int wait)
>  {
> -     struct buffer_head *bh;
> +     struct buffer_head *bh, *head;
>  
>       if (bitmap->storage.file == NULL) {
>               switch (write_sb_page(bitmap, page, wait)) {
> @@ -295,15 +295,16 @@ static void write_page(struct bitmap *bitmap, struct 
> page *page, int wait)
>               }
>       } else {
>  
> -             bh = page_buffers(page);
> +             bh = head = page_buffers(page);
>  
> -             while (bh && bh->b_blocknr) {
> -                     atomic_inc(&bitmap->pending_writes);
> -                     set_buffer_locked(bh);
> -                     set_buffer_mapped(bh);
> -                     submit_bh(REQ_OP_WRITE, REQ_SYNC, bh);
> -                     bh = bh->b_this_page;
> -             }
> +             do {
> +                     if (bh && bh->b_blocknr) {
> +                             atomic_inc(&bitmap->pending_writes);
> +                             set_buffer_locked(bh);
> +                             set_buffer_mapped(bh);
> +                             submit_bh(REQ_OP_WRITE, REQ_SYNC, bh);
> +                     }
> +             } while ((bh = bh->b_this_page) != head);
>  
>               if (wait)
>                       wait_event(bitmap->write_wait,
> @@ -333,17 +334,18 @@ __clear_page_buffers(struct page *page)
>  }
>  static void free_buffers(struct page *page)
>  {
> -     struct buffer_head *bh;
> +     struct buffer_head *bh, *head;
>  
>       if (!PagePrivate(page))
>               return;
>  
> -     bh = page_buffers(page);
> -     while (bh) {
> +     bh = head = page_buffers(page);
> +     do {
>               struct buffer_head *next = bh->b_this_page;
>               free_buffer_head(bh);
>               bh = next;
> -     }
> +     } while (bh != head);
> +
>       __clear_page_buffers(page);
>       put_page(page);
>  }
> @@ -362,20 +364,20 @@ static int read_page(struct file *file, unsigned long 
> index,
>  {
>       int ret = 0;
>       struct inode *inode = file_inode(file);
> -     struct buffer_head *bh;
> +     struct buffer_head *bh, *head;
>       sector_t block;
>  
>       pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
>                (unsigned long long)index << PAGE_SHIFT);
>  
> -     bh = alloc_page_buffers(page, 1<<inode->i_blkbits, false);
> +     bh = head = alloc_page_buffers(page, 1<<inode->i_blkbits, false);
>       if (!bh) {
>               ret = -ENOMEM;
>               goto out;
>       }
>       attach_page_buffers(page, bh);
>       block = index << (PAGE_SHIFT - inode->i_blkbits);
> -     while (bh) {
> +     do {
>               if (count == 0)
>                       bh->b_blocknr = 0;
>               else {
> @@ -400,7 +402,7 @@ static int read_page(struct file *file, unsigned long 
> index,
>               }
>               block++;
>               bh = bh->b_this_page;
> -     }
> +     } while (bh != head);
>       page->index = index;
>  
>       wait_event(bitmap->write_wait,
> -- 
> 2.6.2
>
Before
sean@linux-zmni:~/sda5/source/linus_repo/linux> size fs/buffer.o
   text    data     bss     dec     hex filename
  33693    1466      16   35175    8967 fs/buffer.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size drivers/md/md-bitmap.o
   text    data     bss     dec     hex filename
  28149    2168       0   30317    766d drivers/md/md-bitmap.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size fs/ntfs/mft.o 
   text    data     bss     dec     hex filename
   2133      36       0    2169     879 fs/ntfs/mft.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size fs/ntfs/aops.o
   text    data     bss     dec     hex filename
   6125     168       0    6293    1895 fs/ntfs/aops.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size vmlinux
   text    data     bss     dec     hex filename
11480260        5730762 1646084 18857106        11fbc92 vmlinux
sean@linux-zmni:~/sda5/source/linus_repo/linux> size ./arch/x86/boot/bzImage
size: ./arch/x86/boot/bzImage: Warning: Ignoring section flag 
IMAGE_SCN_MEM_NOT_PAGED in section .bss
   text    data     bss     dec     hex filename
6571744       0 16975648        23547392        1674e00 ./arch/x86/boot/bzImage


After
sean@linux-zmni:~/sda5/source/linus_repo/linux> size fs/buffer.o 
   text    data     bss     dec     hex filename
  33687    1466      16   35169    8961 fs/buffer.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size drivers/md/md-bitmap.o 
   text    data     bss     dec     hex filename
  28221    2168       0   30389    76b5 drivers/md/md-bitmap.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size fs/ntfs/mft.o 
   text    data     bss     dec     hex filename
   2133      36       0    2169     879 fs/ntfs/mft.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size fs/ntfs/aops.o
   text    data     bss     dec     hex filename
   6125     168       0    6293    1895 fs/ntfs/aops.o
sean@linux-zmni:~/sda5/source/linus_repo/linux> size vmlinux
   text    data     bss     dec     hex filename
11480270        5730762 1646084 18857116        11fbc9c vmlinux
sean@linux-zmni:~/sda5/source/linus_repo/linux> size ./arch/x86/boot/bzImage
size: ./arch/x86/boot/bzImage: Warning: Ignoring section flag 
IMAGE_SCN_MEM_NOT_PAGED in section .bss
   text    data     bss     dec     hex filename
6571488       0 16975904        23547392        1674e00 ./arch/x86/boot/bzImage

Only patch #3 increases the text section size of drivers/md/md-bitmap.o
The actual text section increment should be several bytes. Duo to compiler 
align-functions option, the total increment is increased to 72 bytes.

Why is circular list traversal more complex than linear list traversal in this 
situation?  
How to optimize it? 

Reply via email to