All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Benny Halevy <bhalevy@panasas.com>
Cc: linux-nfs@vger.kernel.org, Alexandros Batsakis <batsakis@netapp.com>
Subject: Re: [PATCH 12/14] nfsd4: remove use of mutex for file_hashtable
Date: Fri, 13 Mar 2009 13:18:31 -0400	[thread overview]
Message-ID: <20090313171831.GA26916@fieldses.org> (raw)
In-Reply-To: <49B8E8B5.4010205@panasas.com>

On Thu, Mar 12, 2009 at 12:49:25PM +0200, Benny Halevy wrote:
> On Mar. 12, 2009, 2:05 +0200, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> > On Wed, Mar 11, 2009 at 08:52:14PM +0200, Benny Halevy wrote:
> >> On Mar. 11, 2009, 2:27 +0200, "J. Bruce Fields" <bfields@fieldses.org> wrote:
> >>> From: J. Bruce Fields <bfields@citi.umich.edu>
> >>>
> >>> As part of reducing the scope of the client_mutex, and in order to
> >>> remove the need for mutexes from the callback code (so that callbacks
> >>> can be done as asynchronous rpc calls), move manipulations of the
> >>> file_hashtable under the recall_lock.
> >>>
> >>> Update the relevant comments while we're here.
> >>>
> >>> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
> >>> Cc: Alexandros Batsakis <batsakis@netapp.com>
> >>> ---
> >>>  fs/nfsd/nfs4callback.c |    2 --
> >>>  fs/nfsd/nfs4state.c    |   29 +++++++++++++++++------------
> >>>  2 files changed, 17 insertions(+), 14 deletions(-)
> >>>
> >>> diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
> >>> index 3fd7136..5dcd38e 100644
> >>> --- a/fs/nfsd/nfs4callback.c
> >>> +++ b/fs/nfsd/nfs4callback.c
> >>> @@ -491,8 +491,6 @@ out_put_cred:
> >>>  	 * or deleg_return.
> >>>  	 */
> >>>  	put_nfs4_client(clp);
> >>> -	nfs4_lock_state();
> >>>  	nfs4_put_delegation(dp);
> >>> -	nfs4_unlock_state();
> >>>  	return;
> >>>  }
> >>> diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
> >>> index 56e81f9..2f4cb9a 100644
> >>> --- a/fs/nfsd/nfs4state.c
> >>> +++ b/fs/nfsd/nfs4state.c
> >>> @@ -78,14 +78,18 @@ static struct nfs4_delegation * find_delegation_stateid(struct inode *ino, state
> >>>  static char user_recovery_dirname[PATH_MAX] = "/var/lib/nfs/v4recovery";
> >>>  static void nfs4_set_recdir(char *recdir);
> >>>  
> >>> -/* Locking:
> >>> - *
> >>> - * client_mutex:
> >>> - * 	protects clientid_hashtbl[], clientstr_hashtbl[],
> >>> - * 	unconfstr_hashtbl[], uncofid_hashtbl[].
> >>> - */
> >>> +/* Locking: */
> >>> +
> >>> +/* Currently used for almost all code touching nfsv4 state: */
> >>>  static DEFINE_MUTEX(client_mutex);
> >>>  
> >>> +/*
> >>> + * Currently used for the del_recall_lru and file hash table.  In an
> >>> + * effort to decrease the scope of the client_mutex, this spinlock may
> >>> + * eventually cover more:
> >>> + */
> >>> +static DEFINE_SPINLOCK(recall_lock);
> >>> +
> >>>  static struct kmem_cache *stateowner_slab = NULL;
> >>>  static struct kmem_cache *file_slab = NULL;
> >>>  static struct kmem_cache *stateid_slab = NULL;
> >>> @@ -116,19 +120,15 @@ opaque_hashval(const void *ptr, int nbytes)
> >>>  	return x;
> >>>  }
> >>>  
> >>> -/*
> >>> - * Delegation state
> >>> - */
> >>> -
> >>> -/* recall_lock protects the del_recall_lru */
> >>> -static DEFINE_SPINLOCK(recall_lock);
> >>>  static struct list_head del_recall_lru;
> >>>  
> >>>  static void
> >>>  free_nfs4_file(struct kref *kref)
> >>>  {
> >>>  	struct nfs4_file *fp = container_of(kref, struct nfs4_file, fi_ref);
> >>> +	spin_lock(&recall_lock);
> >>>  	list_del(&fp->fi_hash);
> >>> +	spin_unlock(&recall_lock);
> >>>  	iput(fp->fi_inode);
> >>>  	kmem_cache_free(file_slab, fp);
> >>>  }
> >>> @@ -1004,7 +1004,9 @@ alloc_init_file(struct inode *ino)
> >>>  		INIT_LIST_HEAD(&fp->fi_hash);
> >>>  		INIT_LIST_HEAD(&fp->fi_stateids);
> >>>  		INIT_LIST_HEAD(&fp->fi_delegations);
> >>> +		spin_lock(&recall_lock);
> >>>  		list_add(&fp->fi_hash, &file_hashtbl[hashval]);
> >>> +		spin_unlock(&recall_lock);
> >>>  		fp->fi_inode = igrab(ino);
> >>>  		fp->fi_id = current_fileid++;
> >>>  		fp->fi_had_conflict = false;
> >>> @@ -1177,12 +1179,15 @@ find_file(struct inode *ino)
> >>>  	unsigned int hashval = file_hashval(ino);
> >>>  	struct nfs4_file *fp;
> >>>  
> >>> +	spin_lock(&recall_lock);
> >>>  	list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
> >>>  		if (fp->fi_inode == ino) {
> >>> +			spin_unlock(&recall_lock);
> >> Hmm, I'm afraid there's a race here since potentially
> >> you could take the reference on the file after it has been freed.
> >> find_file should call get_nfs4_file if and only if it's still hashed,
> >> i.e. atomically with looking it up on the list.
> >>
> >> On the same lines, the lock should be taken in put_nfs4_file
> >> rather than in free_nfs4_file.
> >>
> >> That being said, I'm not sure we're unhashing the file in the right
> >> place... it's too late for me right now but my hunch is that open
> >> should alloc_init the nfs4_file as done today and close should unhash
> >> it (under the recall spinlock), and then put it.
> >> put_nfs4_file can stay the same and free_nfs4_file should just do the
> >> iput and kmem_cache_free.
> >>
> >> The main difference is that find_file will fail finding the nfs4_file
> >> struct after close.  (get_nfs4_file in find_file should still happen
> >> under the lock though)
> > 
> > It's probably better for the nfs4_file to be visible longer, but either
> > is correct.
> 
> I see. What matters is the stateids associated with the file.

Right.  So for now I'm taking your first suggestion.  Thanks again for
the review.

--b.

  reply	other threads:[~2009-03-13 17:18 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-03-11  0:26 miscellaneous nfsd4 state changes J. Bruce Fields
2009-03-11  0:26 ` [PATCH 01/14] nfsd4: trivial preprocess_stateid_op cleanup J. Bruce Fields
2009-03-11  0:26   ` [PATCH 02/14] nfsd4: move check_stateid_generation check J. Bruce Fields
2009-03-11  0:26     ` [PATCH 03/14] nfsd4: remove redundant "if" in nfs4_preprocess_stateid_op J. Bruce Fields
2009-03-11  0:26       ` [PATCH 04/14] nfsd4: remove unneeded local variable J. Bruce Fields
2009-03-11  0:26         ` [PATCH 05/14] nfsd4: remove some dprintk's J. Bruce Fields
2009-03-11  0:26           ` [PATCH 06/14] nfsd4: add a helper function to decide if stateid is delegation J. Bruce Fields
2009-03-11  0:26             ` [PATCH 07/14] nfsd4: separate delegreturn case from preprocess_stateid_op J. Bruce Fields
2009-03-11  0:26               ` [PATCH 08/14] nfsd4: fail when delegreturn gets a non-delegation stateid J. Bruce Fields
2009-03-11  0:26                 ` [PATCH 09/14] nfsd4: remove unused CHECK_FH flag J. Bruce Fields
2009-03-11  0:26                   ` [PATCH 10/14] nfsd4: rename io_during_grace_disallowed J. Bruce Fields
2009-03-11  0:26                     ` [PATCH 11/14] nfsd4: put_nfs4_client does not require state lock J. Bruce Fields
2009-03-11  0:27                       ` [PATCH 12/14] nfsd4: remove use of mutex for file_hashtable J. Bruce Fields
2009-03-11  0:27                         ` [PATCH 13/14] nfsd4: fix do_probe_callback errors J. Bruce Fields
2009-03-11  0:27                           ` [PATCH 14/14] nfsd4: move rpc_client setup to a separate function J. Bruce Fields
2009-03-12 10:59                             ` Benny Halevy
2009-03-12 10:55                           ` [PATCH 13/14] nfsd4: fix do_probe_callback errors Benny Halevy
2009-03-12 21:41                             ` J. Bruce Fields
2009-03-11 18:52                         ` [PATCH 12/14] nfsd4: remove use of mutex for file_hashtable Benny Halevy
2009-03-12  0:05                           ` J. Bruce Fields
2009-03-12 10:49                             ` Benny Halevy
2009-03-13 17:18                               ` J. Bruce Fields [this message]
2009-03-18 20:28                                 ` J. Bruce Fields
2009-03-18 20:40                                   ` Benny Halevy
2009-03-18 21:03                                     ` J. Bruce Fields
2009-03-18 21:07                                       ` Benny Halevy
2009-03-11  1:52                 ` [PATCH 08/14] nfsd4: fail when delegreturn gets a non-delegation stateid Yang Hongyang
2009-03-11 20:07                   ` J. Bruce Fields
2009-03-11 18:29                 ` Benny Halevy
2009-03-12  0:03                   ` J. Bruce Fields
2009-03-11  1:47               ` [PATCH 07/14] nfsd4: separate delegreturn case from preprocess_stateid_op Yang Hongyang
2009-03-11 19:51                 ` J. Bruce Fields
2009-03-11  1:12       ` [PATCH 03/14] nfsd4: remove redundant "if" in nfs4_preprocess_stateid_op Yang Hongyang
2009-03-11  1:23         ` J. Bruce Fields
2009-03-11  1:26           ` Yang Hongyang
2009-03-11 18:05             ` Benny Halevy
2009-03-11 19:49               ` J. Bruce Fields
2009-03-11  2:09   ` [PATCH 01/14] nfsd4: trivial preprocess_stateid_op cleanup Yang Hongyang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090313171831.GA26916@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=batsakis@netapp.com \
    --cc=bhalevy@panasas.com \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.