Commit b4f937cf authored by Trond Myklebust's avatar Trond Myklebust Committed by Anna Schumaker

NFS: Don't run wake_up_bit() when nobody is waiting...

"perf lock" shows fairly heavy contention for the bit waitqueue locks
when doing an I/O heavy workload.
Use a bit to tell whether or not there has been contention for a lock
so that we can optimise away the bit waitqueue options in those cases.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 20fa1902
...@@ -155,9 +155,12 @@ nfs_page_group_lock(struct nfs_page *req, bool nonblock) ...@@ -155,9 +155,12 @@ nfs_page_group_lock(struct nfs_page *req, bool nonblock)
if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags)) if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags))
return 0; return 0;
if (!nonblock) if (!nonblock) {
set_bit(PG_CONTENDED1, &head->wb_flags);
smp_mb__after_atomic();
return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK, return wait_on_bit_lock(&head->wb_flags, PG_HEADLOCK,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
}
return -EAGAIN; return -EAGAIN;
} }
...@@ -175,6 +178,10 @@ nfs_page_group_lock_wait(struct nfs_page *req) ...@@ -175,6 +178,10 @@ nfs_page_group_lock_wait(struct nfs_page *req)
WARN_ON_ONCE(head != head->wb_head); WARN_ON_ONCE(head != head->wb_head);
if (!test_bit(PG_HEADLOCK, &head->wb_flags))
return;
set_bit(PG_CONTENDED1, &head->wb_flags);
smp_mb__after_atomic();
wait_on_bit(&head->wb_flags, PG_HEADLOCK, wait_on_bit(&head->wb_flags, PG_HEADLOCK,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
} }
...@@ -193,6 +200,8 @@ nfs_page_group_unlock(struct nfs_page *req) ...@@ -193,6 +200,8 @@ nfs_page_group_unlock(struct nfs_page *req)
smp_mb__before_atomic(); smp_mb__before_atomic();
clear_bit(PG_HEADLOCK, &head->wb_flags); clear_bit(PG_HEADLOCK, &head->wb_flags);
smp_mb__after_atomic(); smp_mb__after_atomic();
if (!test_bit(PG_CONTENDED1, &head->wb_flags))
return;
wake_up_bit(&head->wb_flags, PG_HEADLOCK); wake_up_bit(&head->wb_flags, PG_HEADLOCK);
} }
...@@ -383,6 +392,8 @@ void nfs_unlock_request(struct nfs_page *req) ...@@ -383,6 +392,8 @@ void nfs_unlock_request(struct nfs_page *req)
smp_mb__before_atomic(); smp_mb__before_atomic();
clear_bit(PG_BUSY, &req->wb_flags); clear_bit(PG_BUSY, &req->wb_flags);
smp_mb__after_atomic(); smp_mb__after_atomic();
if (!test_bit(PG_CONTENDED2, &req->wb_flags))
return;
wake_up_bit(&req->wb_flags, PG_BUSY); wake_up_bit(&req->wb_flags, PG_BUSY);
} }
...@@ -465,6 +476,10 @@ void nfs_release_request(struct nfs_page *req) ...@@ -465,6 +476,10 @@ void nfs_release_request(struct nfs_page *req)
int int
nfs_wait_on_request(struct nfs_page *req) nfs_wait_on_request(struct nfs_page *req)
{ {
if (!test_bit(PG_BUSY, &req->wb_flags))
return 0;
set_bit(PG_CONTENDED2, &req->wb_flags);
smp_mb__after_atomic();
return wait_on_bit_io(&req->wb_flags, PG_BUSY, return wait_on_bit_io(&req->wb_flags, PG_BUSY,
TASK_UNINTERRUPTIBLE); TASK_UNINTERRUPTIBLE);
} }
......
...@@ -33,6 +33,8 @@ enum { ...@@ -33,6 +33,8 @@ enum {
PG_UPTODATE, /* page group sync bit in read path */ PG_UPTODATE, /* page group sync bit in read path */
PG_WB_END, /* page group sync bit in write path */ PG_WB_END, /* page group sync bit in write path */
PG_REMOVE, /* page group sync bit in write path */ PG_REMOVE, /* page group sync bit in write path */
PG_CONTENDED1, /* Is someone waiting for a lock? */
PG_CONTENDED2, /* Is someone waiting for a lock? */
}; };
struct nfs_inode; struct nfs_inode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment