staging: lustre: ptlrpc: move thread creation out of module initialization
authorNeilBrown <neilb@suse.com>
Thu, 1 Mar 2018 23:31:25 +0000 (10:31 +1100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 6 Mar 2018 12:20:23 +0000 (04:20 -0800)
When the ptlrpc module is loaded, it starts the pinger thread and
calls LNetNIInit which starts various threads.

We don't need these threads until the module is actually being
used, such as when a lustre filesystem is mounted.

So move the thread creation into new ptlrpc_inc_ref() (modeled on
ptlrpcd_inc_ref()), and call that when needed, such as at mount time.

Signed-off-by: NeilBrown <neilb@suse.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/lustre/lustre/include/lustre_net.h
drivers/staging/lustre/lustre/ldlm/ldlm_lockd.c
drivers/staging/lustre/lustre/llite/llite_lib.c
drivers/staging/lustre/lustre/ptlrpc/ptlrpc_module.c

index 108683c54127a3883dc66a4d691b1a9f78c9aa9f..d35ae0cda8d28fa7d3beb2dc0ec8b43814230b56 100644 (file)
@@ -1804,6 +1804,9 @@ int ptlrpc_register_rqbd(struct ptlrpc_request_buffer_desc *rqbd);
  */
 void ptlrpc_request_committed(struct ptlrpc_request *req, int force);
 
+int ptlrpc_inc_ref(void);
+void ptlrpc_dec_ref(void);
+
 void ptlrpc_init_client(int req_portal, int rep_portal, char *name,
                        struct ptlrpc_client *);
 struct ptlrpc_connection *ptlrpc_uuid_to_connection(struct obd_uuid *uuid);
index 58913e6281240748e66f7f023767ba4ce7cf9e01..c772c68e5a4978acb5568d4e05bb68aa1a48fbe2 100644 (file)
@@ -869,6 +869,10 @@ int ldlm_get_ref(void)
 {
        int rc = 0;
 
+       rc = ptlrpc_inc_ref();
+       if (rc)
+               return rc;
+
        mutex_lock(&ldlm_ref_mutex);
        if (++ldlm_refcount == 1) {
                rc = ldlm_setup();
@@ -877,14 +881,18 @@ int ldlm_get_ref(void)
        }
        mutex_unlock(&ldlm_ref_mutex);
 
+       if (rc)
+               ptlrpc_dec_ref();
+
        return rc;
 }
 
 void ldlm_put_ref(void)
 {
+       int rc = 0;
        mutex_lock(&ldlm_ref_mutex);
        if (ldlm_refcount == 1) {
-               int rc = ldlm_cleanup();
+               rc = ldlm_cleanup();
 
                if (rc)
                        CERROR("ldlm_cleanup failed: %d\n", rc);
@@ -894,6 +902,8 @@ void ldlm_put_ref(void)
                ldlm_refcount--;
        }
        mutex_unlock(&ldlm_ref_mutex);
+       if (!rc)
+               ptlrpc_dec_ref();
 }
 
 static ssize_t cancel_unused_locks_before_replay_show(struct kobject *kobj,
index bc5d6b6ac42951082d4535857e656dfa5b02aacc..e7500c53fafc84157b8ee2d3f517d94ef0ec6462 100644 (file)
@@ -879,9 +879,15 @@ int ll_fill_super(struct super_block *sb)
 
        CDEBUG(D_VFSTRACE, "VFS Op: sb %p\n", sb);
 
+       err = ptlrpc_inc_ref();
+       if (err)
+               return err;
+
        cfg = kzalloc(sizeof(*cfg), GFP_NOFS);
-       if (!cfg)
-               return -ENOMEM;
+       if (!cfg) {
+               err = -ENOMEM;
+               goto out_put;
+       }
 
        try_module_get(THIS_MODULE);
 
@@ -891,7 +897,8 @@ int ll_fill_super(struct super_block *sb)
        if (!sbi) {
                module_put(THIS_MODULE);
                kfree(cfg);
-               return -ENOMEM;
+               err = -ENOMEM;
+               goto out_put;
        }
 
        err = ll_options(lsi->lsi_lmd->lmd_opts, &sbi->ll_flags);
@@ -958,6 +965,9 @@ out_free:
                LCONSOLE_WARN("Mounted %s\n", profilenm);
 
        kfree(cfg);
+out_put:
+       if (err)
+               ptlrpc_dec_ref();
        return err;
 } /* ll_fill_super */
 
@@ -1028,6 +1038,8 @@ void ll_put_super(struct super_block *sb)
        cl_env_cache_purge(~0);
 
        module_put(THIS_MODULE);
+
+       ptlrpc_dec_ref();
 } /* client_put_super */
 
 struct inode *ll_inode_from_resource_lock(struct ldlm_lock *lock)
index 131fc6d9646ebefe2357a05a29093d49f58ec2dd..38923418669f53f7540ad8c495cc0998791be347 100644 (file)
@@ -45,6 +45,42 @@ extern spinlock_t ptlrpc_last_xid_lock;
 extern spinlock_t ptlrpc_rs_debug_lock;
 #endif
 
+DEFINE_MUTEX(ptlrpc_startup);
+static int ptlrpc_active = 0;
+
+int ptlrpc_inc_ref(void)
+{
+       int rc = 0;
+
+       mutex_lock(&ptlrpc_startup);
+       if (ptlrpc_active++ == 0) {
+               ptlrpc_put_connection_superhack = ptlrpc_connection_put;
+
+               rc = ptlrpc_init_portals();
+               if (!rc) {
+                       rc= ptlrpc_start_pinger();
+                       if (rc)
+                               ptlrpc_exit_portals();
+               }
+               if (rc)
+                       ptlrpc_active--;
+       }
+       mutex_unlock(&ptlrpc_startup);
+       return rc;
+}
+EXPORT_SYMBOL(ptlrpc_inc_ref);
+
+void ptlrpc_dec_ref(void)
+{
+       mutex_lock(&ptlrpc_startup);
+       if (--ptlrpc_active == 0) {
+               ptlrpc_stop_pinger();
+               ptlrpc_exit_portals();
+       }
+       mutex_unlock(&ptlrpc_startup);
+}
+EXPORT_SYMBOL(ptlrpc_dec_ref);
+
 static int __init ptlrpc_init(void)
 {
        int rc, cleanup_phase = 0;
@@ -71,24 +107,12 @@ static int __init ptlrpc_init(void)
        if (rc)
                goto cleanup;
 
-       cleanup_phase = 2;
-       rc = ptlrpc_init_portals();
-       if (rc)
-               goto cleanup;
-
        cleanup_phase = 3;
 
        rc = ptlrpc_connection_init();
        if (rc)
                goto cleanup;
 
-       cleanup_phase = 4;
-       ptlrpc_put_connection_superhack = ptlrpc_connection_put;
-
-       rc = ptlrpc_start_pinger();
-       if (rc)
-               goto cleanup;
-
        cleanup_phase = 5;
        rc = ldlm_init();
        if (rc)
@@ -122,15 +146,9 @@ cleanup:
                ldlm_exit();
                /* Fall through */
        case 5:
-               ptlrpc_stop_pinger();
-               /* Fall through */
-       case 4:
                ptlrpc_connection_fini();
                /* Fall through */
        case 3:
-               ptlrpc_exit_portals();
-               /* Fall through */
-       case 2:
                ptlrpc_request_cache_fini();
                /* Fall through */
        case 1:
@@ -150,8 +168,6 @@ static void __exit ptlrpc_exit(void)
        ptlrpc_nrs_fini();
        sptlrpc_fini();
        ldlm_exit();
-       ptlrpc_stop_pinger();
-       ptlrpc_exit_portals();
        ptlrpc_request_cache_fini();
        ptlrpc_hr_fini();
        ptlrpc_connection_fini();