1. 13 Dec, 2021 11 commits
    • NeilBrown's avatar
      NFSD: simplify locking for network notifier. · d057cfec
      NeilBrown authored
      nfsd currently maintains an open-coded read/write semaphore (refcount
      and wait queue) for each network namespace to ensure the nfs service
      isn't shut down while the notifier is running.
      
      This is excessive.  As there is unlikely to be contention between
      notifiers and they run without sleeping, a single spinlock is sufficient
      to avoid problems.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      [ cel: ensure nfsd_notifier_lock is static ]
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      d057cfec
    • NeilBrown's avatar
      SUNRPC: discard svo_setup and rename svc_set_num_threads_sync() · 3ebdbe52
      NeilBrown authored
      The ->svo_setup callback serves no purpose.  It is always called from
      within the same module that chooses which callback is needed.  So
      discard it and call the relevant function directly.
      
      Now that svc_set_num_threads() is no longer used remove it and rename
      svc_set_num_threads_sync() to remove the "_sync" suffix.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      3ebdbe52
    • NeilBrown's avatar
      NFSD: Make it possible to use svc_set_num_threads_sync · 3409e4f1
      NeilBrown authored
      nfsd cannot currently use svc_set_num_threads_sync.  It instead
      uses svc_set_num_threads which does *not* wait for threads to all
      exit, and has a separate mechanism (nfsd_shutdown_complete) to wait
      for completion.
      
      The reason that nfsd is unlike other services is that nfsd threads can
      exit separately from svc_set_num_threads being called - they die on
      receipt of SIGKILL.  Also, when the last thread exits, the service must
      be shut down (sockets closed).
      
      For this, the nfsd_mutex needs to be taken, and as that mutex needs to
      be held while svc_set_num_threads is called, the one cannot wait for
      the other.
      
      This patch changes the nfsd thread so that it can drop the ref on the
      service without blocking on nfsd_mutex, so that svc_set_num_threads_sync
      can be used:
       - if it can drop a non-last reference, it does that.  This does not
         trigger shutdown and does not require a mutex.  This will likely
         happen for all but the last thread signalled, and for all threads
         being shut down by nfsd_shutdown_threads()
       - if it can get the mutex without blocking (trylock), it does that
         and then drops the reference.  This will likely happen for the
         last thread killed by SIGKILL
       - Otherwise there might be an unrelated task holding the mutex,
         possibly in another network namespace, or nfsd_shutdown_threads()
         might be just about to get a reference on the service, after which
         we can drop ours safely.
         We cannot conveniently get wakeup notifications on these events,
         and we are unlikely to need to, so we sleep briefly and check again.
      
      With this we can discard nfsd_shutdown_complete and
      nfsd_complete_shutdown(), and switch to svc_set_num_threads_sync.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      3409e4f1
    • NeilBrown's avatar
      NFSD: narrow nfsd_mutex protection in nfsd thread · 9d3792ae
      NeilBrown authored
      There is nothing happening in the start of nfsd() that requires
      protection by the mutex, so don't take it until shutting down the thread
      - which does still require protection - but only for nfsd_put().
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      9d3792ae
    • NeilBrown's avatar
      SUNRPC: use sv_lock to protect updates to sv_nrthreads. · 2a36395f
      NeilBrown authored
      Using sv_lock means we don't need to hold the service mutex over these
      updates.
      
      In particular,  svc_exit_thread() no longer requires synchronisation, so
      threads can exit asynchronously.
      
      Note that we could use an atomic_t, but as there are many more read
      sites than writes, that would add unnecessary noise to the code.
      Some reads are already racy, and there is no need for them to not be.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      2a36395f
    • NeilBrown's avatar
      nfsd: make nfsd_stats.th_cnt atomic_t · 9b6c8c9b
      NeilBrown authored
      This allows us to move the updates for th_cnt out of the mutex.
      This is a step towards reducing mutex coverage in nfsd().
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      9b6c8c9b
    • NeilBrown's avatar
      SUNRPC: stop using ->sv_nrthreads as a refcount · ec52361d
      NeilBrown authored
      The use of sv_nrthreads as a general refcount results in clumsy code, as
      is seen by various comments needed to explain the situation.
      
      This patch introduces a 'struct kref' and uses that for reference
      counting, leaving sv_nrthreads to be a pure count of threads.  The kref
      is managed particularly in svc_get() and svc_put(), and also nfsd_put();
      
      svc_destroy() now takes a pointer to the embedded kref, rather than to
      the serv.
      
      nfsd allows the svc_serv to exist with ->sv_nrhtreads being zero.  This
      happens when a transport is created before the first thread is started.
      To support this, a 'keep_active' flag is introduced which holds a ref on
      the svc_serv.  This is set when any listening socket is successfully
      added (unless there are running threads), and cleared when the number of
      threads is set.  So when the last thread exits, the nfs_serv will be
      destroyed.
      The use of 'keep_active' replaces previous code which checked if there
      were any permanent sockets.
      
      We no longer clear ->rq_server when nfsd() exits.  This was done
      to prevent svc_exit_thread() from calling svc_destroy().
      Instead we take an extra reference to the svc_serv to prevent
      svc_destroy() from being called.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      ec52361d
    • NeilBrown's avatar
      SUNRPC/NFSD: clean up get/put functions. · 8c62d127
      NeilBrown authored
      svc_destroy() is poorly named - it doesn't necessarily destroy the svc,
      it might just reduce the ref count.
      nfsd_destroy() is poorly named for the same reason.
      
      This patch:
       - removes the refcount functionality from svc_destroy(), moving it to
         a new svc_put().  Almost all previous callers of svc_destroy() now
         call svc_put().
       - renames nfsd_destroy() to nfsd_put() and improves the code, using
         the new svc_destroy() rather than svc_put()
       - removes a few comments that explain the important for balanced
         get/put calls.  This should be obvious.
      
      The only non-trivial part of this is that svc_destroy() would call
      svc_sock_update() on a non-final decrement.  It can no longer do that,
      and svc_put() isn't really a good place of it.  This call is now made
      from svc_exit_thread() which seems like a good place.  This makes the
      call *before* sv_nrthreads is decremented rather than after.  This
      is not particularly important as the call just sets a flag which
      causes sv_nrthreads set be checked later.  A subsequent patch will
      improve the ordering.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      8c62d127
    • NeilBrown's avatar
      SUNRPC: change svc_get() to return the svc. · df5e49c8
      NeilBrown authored
      It is common for 'get' functions to return the object that was 'got',
      and there are a couple of places where users of svc_get() would be a
      little simpler if svc_get() did that.
      
      Make it so.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      df5e49c8
    • NeilBrown's avatar
      NFSD: handle errors better in write_ports_addfd() · 89b24336
      NeilBrown authored
      If write_ports_add() fails, we shouldn't destroy the serv, unless we had
      only just created it.  So if there are any permanent sockets already
      attached, leave the serv in place.
      Signed-off-by: default avatarNeilBrown <neilb@suse.de>
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      89b24336
    • Chuck Lever's avatar
      NFSD: Fix sparse warning · c2f1c4bd
      Chuck Lever authored
      /home/cel/src/linux/linux/fs/nfsd/nfs4proc.c:1539:24: warning: incorrect type in assignment (different base types)
      /home/cel/src/linux/linux/fs/nfsd/nfs4proc.c:1539:24:    expected restricted __be32 [usertype] status
      /home/cel/src/linux/linux/fs/nfsd/nfs4proc.c:1539:24:    got int
      Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
      c2f1c4bd
  2. 12 Dec, 2021 14 commits
  3. 11 Dec, 2021 15 commits