lkml.org 
[lkml]   [2014]   [May]   [13]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH 17/19] fs: buffer: Do not use unnecessary atomic operations when discarding buffers
    On Tue, 13 May 2014 10:45:48 +0100 Mel Gorman <mgorman@suse.de> wrote:

    > Discarding buffers uses a bunch of atomic operations when discarding buffers
    > because ...... I can't think of a reason. Use a cmpxchg loop to clear all the
    > necessary flags. In most (all?) cases this will be a single atomic operations.
    >
    > --- a/fs/buffer.c
    > +++ b/fs/buffer.c
    > @@ -1485,14 +1485,18 @@ EXPORT_SYMBOL(set_bh_page);
    > */
    > static void discard_buffer(struct buffer_head * bh)
    > {
    > + unsigned long b_state, b_state_old;
    > +
    > lock_buffer(bh);
    > clear_buffer_dirty(bh);
    > bh->b_bdev = NULL;
    > - clear_buffer_mapped(bh);
    > - clear_buffer_req(bh);
    > - clear_buffer_new(bh);
    > - clear_buffer_delay(bh);
    > - clear_buffer_unwritten(bh);
    > + b_state = bh->b_state;
    > + for (;;) {
    > + b_state_old = cmpxchg(&bh->b_state, b_state, (b_state & ~BUFFER_FLAGS_DISCARD));
    > + if (b_state_old == b_state)
    > + break;
    > + b_state = b_state_old;
    > + }
    > unlock_buffer(bh);
    > }
    >
    > --- a/include/linux/buffer_head.h
    > +++ b/include/linux/buffer_head.h
    > @@ -77,6 +77,11 @@ struct buffer_head {
    > atomic_t b_count; /* users using this buffer_head */
    > };
    >
    > +/* Bits that are cleared during an invalidate */
    > +#define BUFFER_FLAGS_DISCARD \
    > + (1 << BH_Mapped | 1 << BH_New | 1 << BH_Req | \
    > + 1 << BH_Delay | 1 << BH_Unwritten)
    > +

    There isn't much point in having this in the header file is there?

    --- a/fs/buffer.c~fs-buffer-do-not-use-unnecessary-atomic-operations-when-discarding-buffers-fix
    +++ a/fs/buffer.c
    @@ -1483,6 +1483,12 @@ EXPORT_SYMBOL(set_bh_page);
    /*
    * Called when truncating a buffer on a page completely.
    */
    +
    +/* Bits that are cleared during an invalidate */
    +#define BUFFER_FLAGS_DISCARD \
    + (1 << BH_Mapped | 1 << BH_New | 1 << BH_Req | \
    + 1 << BH_Delay | 1 << BH_Unwritten)
    +
    static void discard_buffer(struct buffer_head * bh)
    {
    unsigned long b_state, b_state_old;
    @@ -1492,7 +1498,8 @@ static void discard_buffer(struct buffer
    bh->b_bdev = NULL;
    b_state = bh->b_state;
    for (;;) {
    - b_state_old = cmpxchg(&bh->b_state, b_state, (b_state & ~BUFFER_FLAGS_DISCARD));
    + b_state_old = cmpxchg(&bh->b_state, b_state,
    + (b_state & ~BUFFER_FLAGS_DISCARD));
    if (b_state_old == b_state)
    break;
    b_state = b_state_old;
    --- a/include/linux/buffer_head.h~fs-buffer-do-not-use-unnecessary-atomic-operations-when-discarding-buffers-fix
    +++ a/include/linux/buffer_head.h
    @@ -77,11 +77,6 @@ struct buffer_head {
    atomic_t b_count; /* users using this buffer_head */
    };

    -/* Bits that are cleared during an invalidate */
    -#define BUFFER_FLAGS_DISCARD \
    - (1 << BH_Mapped | 1 << BH_New | 1 << BH_Req | \
    - 1 << BH_Delay | 1 << BH_Unwritten)
    -
    /*
    * macro tricks to expand the set_buffer_foo(), clear_buffer_foo()
    * and buffer_foo() functions.
    _


    \
     
     \ /
      Last update: 2014-05-14 01:01    [W:3.396 / U:0.036 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site