nlm_shutdown_hosts();
        cancel_delayed_work_sync(&ln->grace_period_end);
        locks_end_grace(&ln->lockd_manager);
 -      return 0;
 +
 +      dprintk("lockd_down: service stopped\n");
 +
 +      svc_exit_thread(rqstp);
 +
-       module_put_and_exit(0);
++      module_put_and_kthread_exit(0);
  }
  
  static int create_lockd_listener(struct svc_serv *serv, const char *name,
 
        /* Release the thread */
        svc_exit_thread(rqstp);
  
 -      nfsd_destroy(net);
 +      /* We need to drop a ref, but may not drop the last reference
 +       * without holding nfsd_mutex, and we cannot wait for nfsd_mutex as that
 +       * could deadlock with nfsd_shutdown_threads() waiting for us.
 +       * So three options are:
 +       * - drop a non-final reference,
 +       * - get the mutex without waiting
 +       * - sleep briefly andd try the above again
 +       */
 +      while (!svc_put_not_last(nn->nfsd_serv)) {
 +              if (mutex_trylock(&nfsd_mutex)) {
 +                      nfsd_put(net);
 +                      mutex_unlock(&nfsd_mutex);
 +                      break;
 +              }
 +              msleep(20);
 +      }
  
        /* Release module */
-       module_put_and_exit(0);
 -      mutex_unlock(&nfsd_mutex);
+       module_put_and_kthread_exit(0);
        return 0;
  }
  
 
        /* queue up a transport for servicing */
        void            (*svo_enqueue_xprt)(struct svc_xprt *);
  
 -      /* set up thread (or whatever) execution context */
 -      int             (*svo_setup)(struct svc_serv *, struct svc_pool *, int);
 -
 -      /* optional module to count when adding threads (pooled svcs only) */
 +      /* optional module to count when adding threads.
-        * Thread function must call module_put_and_exit() to exit.
++       * Thread function must call module_put_and_kthread_exit() to exit.
 +       */
        struct module   *svo_module;
  };