diff options
author | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-09-02 15:11:57 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2018-09-30 15:35:16 -0400 |
commit | 1db97eaa0b482a738c715da6edb023d6f99e50b0 (patch) | |
tree | ab49a24c0d53e75780386dbbac1ab7c5531f047b /fs/nfs/inode.c | |
parent | 28ced9a84cd2f9fc68a081fb3b34e70c5d459be3 (diff) |
NFS: Convert lookups of the lock context to RCU
Speed up lookups of an existing lock context by avoiding the inode->i_lock,
and using RCU instead.
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index b65aee481d13..09b3b7146ff4 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -857,15 +857,14 @@ static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) | |||
857 | 857 | ||
858 | static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx) | 858 | static struct nfs_lock_context *__nfs_find_lock_context(struct nfs_open_context *ctx) |
859 | { | 859 | { |
860 | struct nfs_lock_context *head = &ctx->lock_context; | 860 | struct nfs_lock_context *pos; |
861 | struct nfs_lock_context *pos = head; | ||
862 | 861 | ||
863 | do { | 862 | list_for_each_entry_rcu(pos, &ctx->lock_context.list, list) { |
864 | if (pos->lockowner != current->files) | 863 | if (pos->lockowner != current->files) |
865 | continue; | 864 | continue; |
866 | refcount_inc(&pos->count); | 865 | if (refcount_inc_not_zero(&pos->count)) |
867 | return pos; | 866 | return pos; |
868 | } while ((pos = list_entry(pos->list.next, typeof(*pos), list)) != head); | 867 | } |
869 | return NULL; | 868 | return NULL; |
870 | } | 869 | } |
871 | 870 | ||
@@ -874,10 +873,10 @@ struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx) | |||
874 | struct nfs_lock_context *res, *new = NULL; | 873 | struct nfs_lock_context *res, *new = NULL; |
875 | struct inode *inode = d_inode(ctx->dentry); | 874 | struct inode *inode = d_inode(ctx->dentry); |
876 | 875 | ||
877 | spin_lock(&inode->i_lock); | 876 | rcu_read_lock(); |
878 | res = __nfs_find_lock_context(ctx); | 877 | res = __nfs_find_lock_context(ctx); |
878 | rcu_read_unlock(); | ||
879 | if (res == NULL) { | 879 | if (res == NULL) { |
880 | spin_unlock(&inode->i_lock); | ||
881 | new = kmalloc(sizeof(*new), GFP_KERNEL); | 880 | new = kmalloc(sizeof(*new), GFP_KERNEL); |
882 | if (new == NULL) | 881 | if (new == NULL) |
883 | return ERR_PTR(-ENOMEM); | 882 | return ERR_PTR(-ENOMEM); |
@@ -885,14 +884,14 @@ struct nfs_lock_context *nfs_get_lock_context(struct nfs_open_context *ctx) | |||
885 | spin_lock(&inode->i_lock); | 884 | spin_lock(&inode->i_lock); |
886 | res = __nfs_find_lock_context(ctx); | 885 | res = __nfs_find_lock_context(ctx); |
887 | if (res == NULL) { | 886 | if (res == NULL) { |
888 | list_add_tail(&new->list, &ctx->lock_context.list); | 887 | list_add_tail_rcu(&new->list, &ctx->lock_context.list); |
889 | new->open_context = ctx; | 888 | new->open_context = ctx; |
890 | res = new; | 889 | res = new; |
891 | new = NULL; | 890 | new = NULL; |
892 | } | 891 | } |
892 | spin_unlock(&inode->i_lock); | ||
893 | kfree(new); | ||
893 | } | 894 | } |
894 | spin_unlock(&inode->i_lock); | ||
895 | kfree(new); | ||
896 | return res; | 895 | return res; |
897 | } | 896 | } |
898 | EXPORT_SYMBOL_GPL(nfs_get_lock_context); | 897 | EXPORT_SYMBOL_GPL(nfs_get_lock_context); |
@@ -904,9 +903,9 @@ void nfs_put_lock_context(struct nfs_lock_context *l_ctx) | |||
904 | 903 | ||
905 | if (!refcount_dec_and_lock(&l_ctx->count, &inode->i_lock)) | 904 | if (!refcount_dec_and_lock(&l_ctx->count, &inode->i_lock)) |
906 | return; | 905 | return; |
907 | list_del(&l_ctx->list); | 906 | list_del_rcu(&l_ctx->list); |
908 | spin_unlock(&inode->i_lock); | 907 | spin_unlock(&inode->i_lock); |
909 | kfree(l_ctx); | 908 | kfree_rcu(l_ctx, rcu_head); |
910 | } | 909 | } |
911 | EXPORT_SYMBOL_GPL(nfs_put_lock_context); | 910 | EXPORT_SYMBOL_GPL(nfs_put_lock_context); |
912 | 911 | ||