From 8e97c3c5ecad68585ca6580cdf6b8a6f11d2ec8e Mon Sep 17 00:00:00 2001 From: Ashish Samant Date: Wed, 15 Apr 2015 10:44:46 -0700 Subject: [PATCH] fuse: add spinlock to protect fc reqctr fc->lock protects other members along with sequence counter. Since the change introduced by next few patches increases parallelism, it increases contention on fc->lock. Having a new seq_lock spinlock to protect unique sequence counter will reduce contention and also makes code simpler. Signed-off-by: Ashish Samant Reviewed-by: Srinivas Eeda --- fs/fuse/dev.c | 10 +++++++++- fs/fuse/fuse_i.h | 3 +++ fs/fuse/inode.c | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index afe409e4bd3c..7de45eaa38a8 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -337,12 +337,20 @@ static unsigned len_args(unsigned numargs, struct fuse_arg *args) static u64 fuse_get_unique(struct fuse_conn *fc) { + u64 ctr; + + /** Using a separate seq_lock will reduce contention for fc->lock + * and make the code cleaner. + */ + spin_lock(&fc->seq_lock); fc->reqctr++; /* zero is special */ if (fc->reqctr == 0) fc->reqctr = 1; + ctr = fc->reqctr; + spin_unlock(&fc->seq_lock); - return fc->reqctr; + return ctr; } static void queue_request(struct fuse_node *fn, struct fuse_req *req) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index adbca4ff267d..bb6df6ab90e4 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -498,6 +498,9 @@ struct fuse_conn { /** The next unique request id */ u64 reqctr; + /** Lock for protecting access to the reqctr */ + spinlock_t seq_lock; + /** Connection failed (version mismatch). Cannot race with setting other bitfields since it is only set once in INIT reply, before any other request, and never cleared */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 9c54b1f75502..86c97b0637ab 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -574,6 +574,7 @@ int fuse_conn_init(struct fuse_conn *fc) memset(fc, 0, sizeof(*fc)); spin_lock_init(&fc->lock); + spin_lock_init(&fc->seq_lock); init_rwsem(&fc->killsb); atomic_set(&fc->count, 1); init_waitqueue_head(&fc->reserved_req_waitq); -- 2.50.1