mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/xiang/erofs.git
synced 2026-11-01 06:46:35 +01:00
fs: buffer: do not use unnecessary atomic operations when discarding buffers
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. [[email protected]: move BUFFER_FLAGS_DISCARD into the .c file] Signed-off-by: Mel Gorman <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Jan Kara <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Hugh Dickins <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Theodore Ts'o <[email protected]> Cc: "Paul E. McKenney" <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Peter Zijlstra <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
1 parent
6fb81a17d2
commit
e7470ee89f
1 file changed
+16
-5
+16
-5
@@ -1483,16 +1483,27 @@ 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user