Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+16 −1
Original line number Diff line number Diff line
@@ -155,9 +155,12 @@ nfs_page_group_lock(struct nfs_page *req, bool nonblock)
	if (!test_and_set_bit(PG_HEADLOCK, &head->wb_flags))
		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,
				TASK_UNINTERRUPTIBLE);
	}

	return -EAGAIN;
}
@@ -175,6 +178,10 @@ nfs_page_group_lock_wait(struct nfs_page *req)

	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,
		TASK_UNINTERRUPTIBLE);
}
@@ -193,6 +200,8 @@ nfs_page_group_unlock(struct nfs_page *req)
	smp_mb__before_atomic();
	clear_bit(PG_HEADLOCK, &head->wb_flags);
	smp_mb__after_atomic();
	if (!test_bit(PG_CONTENDED1, &head->wb_flags))
		return;
	wake_up_bit(&head->wb_flags, PG_HEADLOCK);
}

@@ -383,6 +392,8 @@ void nfs_unlock_request(struct nfs_page *req)
	smp_mb__before_atomic();
	clear_bit(PG_BUSY, &req->wb_flags);
	smp_mb__after_atomic();
	if (!test_bit(PG_CONTENDED2, &req->wb_flags))
		return;
	wake_up_bit(&req->wb_flags, PG_BUSY);
}

@@ -465,6 +476,10 @@ void nfs_release_request(struct nfs_page *req)
int
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,
			      TASK_UNINTERRUPTIBLE);
}
+2 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@ enum {
	PG_UPTODATE,		/* page group sync bit in read path */
	PG_WB_END,		/* 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;