Btrfs: Check for a blocking lock before taking the spin
This reduces contention on the extent buffer spin locks by testing for a blocking lock before trying to take the spinlock. Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
7f366cfecf
commit
66d7e85ea7
|
@ -71,12 +71,13 @@ void btrfs_clear_lock_blocking(struct extent_buffer *eb)
|
||||||
static int btrfs_spin_on_block(struct extent_buffer *eb)
|
static int btrfs_spin_on_block(struct extent_buffer *eb)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 512; i++) {
|
for (i = 0; i < 512; i++) {
|
||||||
cpu_relax();
|
|
||||||
if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
|
if (!test_bit(EXTENT_BUFFER_BLOCKING, &eb->bflags))
|
||||||
return 1;
|
return 1;
|
||||||
if (need_resched())
|
if (need_resched())
|
||||||
break;
|
break;
|
||||||
|
cpu_relax();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +103,7 @@ int btrfs_try_spin_lock(struct extent_buffer *eb)
|
||||||
|
|
||||||
/* spin for a bit on the BLOCKING flag */
|
/* spin for a bit on the BLOCKING flag */
|
||||||
for (i = 0; i < 2; i++) {
|
for (i = 0; i < 2; i++) {
|
||||||
|
cpu_relax();
|
||||||
if (!btrfs_spin_on_block(eb))
|
if (!btrfs_spin_on_block(eb))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -148,6 +150,9 @@ int btrfs_tree_lock(struct extent_buffer *eb)
|
||||||
DEFINE_WAIT(wait);
|
DEFINE_WAIT(wait);
|
||||||
wait.func = btrfs_wake_function;
|
wait.func = btrfs_wake_function;
|
||||||
|
|
||||||
|
if (!btrfs_spin_on_block(eb))
|
||||||
|
goto sleep;
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
spin_nested(eb);
|
spin_nested(eb);
|
||||||
|
|
||||||
|
@ -165,9 +170,10 @@ int btrfs_tree_lock(struct extent_buffer *eb)
|
||||||
* spin for a bit, and if the blocking flag goes away,
|
* spin for a bit, and if the blocking flag goes away,
|
||||||
* loop around
|
* loop around
|
||||||
*/
|
*/
|
||||||
|
cpu_relax();
|
||||||
if (btrfs_spin_on_block(eb))
|
if (btrfs_spin_on_block(eb))
|
||||||
continue;
|
continue;
|
||||||
|
sleep:
|
||||||
prepare_to_wait_exclusive(&eb->lock_wq, &wait,
|
prepare_to_wait_exclusive(&eb->lock_wq, &wait,
|
||||||
TASK_UNINTERRUPTIBLE);
|
TASK_UNINTERRUPTIBLE);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue