Whamcloud - gitweb
LU-12561 kernel: Remove unused patches
[fs/lustre-release.git] / lustre / kernel_patches / patches / module-load-deadlock-rhel6.patch
diff --git a/lustre/kernel_patches/patches/module-load-deadlock-rhel6.patch b/lustre/kernel_patches/patches/module-load-deadlock-rhel6.patch
deleted file mode 100644 (file)
index 9ca6ec5..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-module: Fix a few concurrent module loading races
-
-Concurrently starting multiple OSTs on a single OSS frequently
-triggers 30s deadlocks on module_mutex.  This RHEL 6 kernel bug
-applies to any module that results in additional request_module()
-calls in its init callback.  In Lustre, at least ptlrpc and libcfs are
-affected.  This patch adapts fixes from the following upstream
-commits:
-
-  9bea7f2 module: fix bne2 "gave up waiting for init of module
-                 libcrc32c"
-  be593f4 module: verify_export_symbols under the lock
-  3bafeb6 module: move find_module check to end
-  80a3d1b module: move sysfs exposure to end of load_module
-
-diff -rNup linux-2.6.32-431.20.3.el6.orig/kernel/module.c linux-2.6.32-431.20.3.el6/kernel/module.c
---- linux-2.6.32-431.20.3.el6.orig/kernel/module.c     2014-06-07 05:42:39.000000000 +0800
-+++ linux-2.6.32-431.20.3.el6/kernel/module.c  2014-07-28 00:04:43.000000000 +0800
-@@ -658,6 +658,33 @@ static int already_uses(struct module *a
- }
- /* Module a uses b */
-+static int ref_module(struct module *a, struct module *b)
-+{
-+      struct module_use *use;
-+      int err;
-+
-+      if (b == NULL || already_uses(a, b))
-+              return 0;
-+
-+      /* If module isn't available, we fail. */
-+      err = strong_try_module_get(b);
-+      if (err)
-+              return err;
-+
-+      DEBUGP("Allocating new usage for %s.\n", a->name);
-+      use = kmalloc(sizeof(*use), GFP_ATOMIC);
-+      if (!use) {
-+              printk("%s: out of memory loading\n", a->name);
-+              module_put(b);
-+              return -ENOMEM;
-+      }
-+
-+      use->module_which_uses = a;
-+      list_add(&use->list, &b->modules_which_use_me);
-+      return 0;
-+}
-+
-+/* Module a uses b */
- int use_module(struct module *a, struct module *b)
- {
-       struct module_use *use;
-@@ -707,7 +734,6 @@ static void module_unload_free(struct mo
-                               module_put(i);
-                               list_del(&use->list);
-                               kfree(use);
--                              sysfs_remove_link(i->holders_dir, mod->name);
-                               /* There can be at most one match. */
-                               break;
-                       }
-@@ -962,6 +988,11 @@ static inline void module_unload_free(st
- {
- }
-+static inline int ref_module(struct module *a, struct module *b)
-+{
-+      return strong_try_module_get(b);
-+}
-+
- int use_module(struct module *a, struct module *b)
- {
-       return strong_try_module_get(b) == 0;
-@@ -1130,24 +1161,60 @@ static inline int same_magic(const char 
- static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
-                                                 unsigned int versindex,
-                                                 const char *name,
--                                                struct module *mod)
-+                                                struct module *mod,
-+                                                char ownername[])
- {
-       struct module *owner;
-       const struct kernel_symbol *sym;
-       const unsigned long *crc;
-+      int err;
-+      mutex_lock(&module_mutex);
-       sym = find_symbol(name, &owner, &crc,
-                         !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
--      /* use_module can fail due to OOM,
--         or module initialization or unloading */
--      if (sym) {
--              if (!check_version(sechdrs, versindex, name, mod, crc, owner)
--                  || !use_module(mod, owner))
--                      sym = NULL;
-+      if (!sym)
-+              goto unlock;
-+
-+      if (!check_version(sechdrs, versindex, name, mod, crc, owner)) {
-+              sym = ERR_PTR(-EINVAL);
-+              goto getname;
-       }
-+
-+      err = ref_module(mod, owner);
-+      if (err) {
-+              sym = ERR_PTR(err);
-+              goto getname;
-+      }
-+
-+getname:
-+      /* We must make copy under the lock if we failed to get ref. */
-+      strncpy(ownername, module_name(owner), MODULE_NAME_LEN);
-+unlock:
-+      mutex_unlock(&module_mutex);
-       return sym;
- }
-+static const struct kernel_symbol *resolve_symbol_wait(Elf_Shdr *sechdrs,
-+                                                     unsigned int versindex,
-+                                                     const char *name,
-+                                                     struct module *mod)
-+{
-+      const struct kernel_symbol *ksym;
-+      char ownername[MODULE_NAME_LEN];
-+
-+      mutex_unlock(&module_mutex);
-+      if (wait_event_interruptible_timeout(module_wq,
-+                      !IS_ERR(ksym = resolve_symbol(sechdrs, versindex, name,
-+                                                    mod, ownername)) ||
-+                      PTR_ERR(ksym) != -EBUSY,
-+                              msecs_to_jiffies(30 * MSEC_PER_SEC)) <= 0) {
-+              printk(KERN_WARNING "%s: gave up waiting for init of module %s.\n",
-+                     mod->name, ownername);
-+      }
-+      mutex_lock(&module_mutex);
-+      return ksym;
-+}
-+
- /*
-  * /sys/module/foo/sections stuff
-  * J. Corbet <corbet@lwn.net>
-@@ -1375,6 +1442,30 @@ static inline void remove_notes_attrs(st
- #endif
- #ifdef CONFIG_SYSFS
-+static void add_usage_links(struct module *mod)
-+{
-+#ifdef CONFIG_MODULE_UNLOAD
-+      struct module_use *use;
-+      int nowarn;
-+
-+      list_for_each_entry(use, &mod->modules_which_use_me, list) {
-+              nowarn = sysfs_create_link(use->module_which_uses->holders_dir,
-+                                         &mod->mkobj.kobj, mod->name);
-+      }
-+#endif
-+}
-+
-+static void del_usage_links(struct module *mod)
-+{
-+#ifdef CONFIG_MODULE_UNLOAD
-+      struct module_use *use;
-+
-+      list_for_each_entry(use, &mod->modules_which_use_me, list)
-+              sysfs_remove_link(use->module_which_uses->holders_dir, mod->name);
-+#endif
-+}
-+
-+
- int module_add_modinfo_attrs(struct module *mod)
- {
-       struct module_attribute *attr;
-@@ -1456,6 +1547,10 @@ int mod_sysfs_setup(struct module *mod,
- {
-       int err;
-+      err = mod_sysfs_init(mod);
-+      if (err)
-+              goto out;
-+
-       mod->holders_dir = kobject_create_and_add("holders", &mod->mkobj.kobj);
-       if (!mod->holders_dir) {
-               err = -ENOMEM;
-@@ -1470,6 +1565,8 @@ int mod_sysfs_setup(struct module *mod,
-       if (err)
-               goto out_unreg_param;
-+      add_usage_links(mod);
-+
-       kobject_uevent(&mod->mkobj.kobj, KOBJ_ADD);
-       return 0;
-@@ -1479,6 +1576,7 @@ out_unreg_holders:
-       kobject_put(mod->holders_dir);
- out_unreg:
-       kobject_put(&mod->mkobj.kobj);
-+out:
-       return err;
- }
-@@ -1493,10 +1591,15 @@ static void mod_sysfs_fini(struct module
- {
- }
-+static void del_usage_links(struct module *mod)
-+{
-+}
-+
- #endif /* CONFIG_SYSFS */
- static void mod_kobject_remove(struct module *mod)
- {
-+      del_usage_links(mod);
-       module_remove_modinfo_attrs(mod);
-       module_param_sysfs_remove(mod);
-       kobject_put(mod->mkobj.drivers_dir);
-@@ -1576,6 +1679,8 @@ EXPORT_SYMBOL_GPL(__symbol_get);
- /*
-  * Ensure that an exported symbol [global namespace] does not already exist
-  * in the kernel or in some other module's exported symbol table.
-+ *
-+ * You must hold the module_mutex.
-  */
- static int verify_export_symbols(struct module *mod)
- {
-@@ -1641,21 +1746,23 @@ static int simplify_symbols(Elf_Shdr *se
-                       break;
-               case SHN_UNDEF:
--                      ksym = resolve_symbol(sechdrs, versindex,
--                                            strtab + sym[i].st_name, mod);
-+                      ksym = resolve_symbol_wait(sechdrs, versindex,
-+                                                 strtab + sym[i].st_name,
-+                                                 mod);
-                       /* Ok if resolved.  */
--                      if (ksym) {
-+                      if (ksym && !IS_ERR(ksym)) {
-                               sym[i].st_value = ksym->value;
-                               break;
-                       }
-                       /* Ok if weak.  */
--                      if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
-+                      if (!ksym && ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
-                               break;
--                      printk(KERN_WARNING "%s: Unknown symbol %s\n",
--                             mod->name, strtab + sym[i].st_name);
--                      ret = -ENOENT;
-+                      printk(KERN_WARNING "%s: Unknown symbol %s (err %li)\n",
-+                             mod->name, strtab + sym[i].st_name,
-+                             PTR_ERR(ksym));
-+                      ret = PTR_ERR(ksym) ?: -ENOENT;
-                       break;
-               default:
-@@ -2240,11 +2347,6 @@ static noinline struct module *load_modu
-               goto free_mod;
-       }
--      if (find_module(mod->name)) {
--              err = -EEXIST;
--              goto free_mod;
--      }
--
-       mod->state = MODULE_STATE_COMING;
-       /* Allow arches to frob section contents and sizes.  */
-@@ -2338,11 +2440,6 @@ static noinline struct module *load_modu
-       /* Now we've moved module, initialize linked lists, etc. */
-       module_unload_init(mod);
--      /* add kobject, so we can reference it. */
--      err = mod_sysfs_init(mod);
--      if (err)
--              goto free_unload;
--
-       /* Set up license info based on the info section */
-       set_license(mod, get_modinfo(sechdrs, infoindex, "license"));
-@@ -2461,11 +2558,6 @@ static noinline struct module *load_modu
-                       goto cleanup;
-       }
--        /* Find duplicate symbols */
--      err = verify_export_symbols(mod);
--      if (err < 0)
--              goto cleanup;
--
-       /* Set up and sort exception table */
-       mod->extable = section_objs(hdr, sechdrs, secstrings, "__ex_table",
-                                   sizeof(*mod->extable), &mod->num_exentries);
-@@ -2521,6 +2613,16 @@ static noinline struct module *load_modu
-        * function to insert in a way safe to concurrent readers.
-        * The mutex protects against concurrent writers.
-        */
-+      if (find_module(mod->name)) {
-+              err = -EEXIST;
-+              goto already_exists;
-+      }
-+
-+        /* Find duplicate symbols */
-+      err = verify_export_symbols(mod);
-+      if (err < 0)
-+              goto already_exists;
-+
-       list_add_rcu(&mod->list, &modules);
-       err = parse_args(mod->name, mod->args, mod->kp, mod->num_kp, NULL);
-@@ -2530,6 +2632,7 @@ static noinline struct module *load_modu
-       err = mod_sysfs_setup(mod, mod->kp, mod->num_kp);
-       if (err < 0)
-               goto unlink;
-+
-       add_sect_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
-       add_notes_attrs(mod, hdr->e_shnum, secstrings, sechdrs);
-@@ -2544,15 +2647,13 @@ static noinline struct module *load_modu
-  unlink:
-       /* Unlink carefully: kallsyms could be walking list. */
-       list_del_rcu(&mod->list);
-+ already_exists:
-       synchronize_sched();
-       module_arch_cleanup(mod);
-  ddebug:
-       dynamic_debug_remove(debug);
-  cleanup:
-       free_modinfo(mod);
--      kobject_del(&mod->mkobj.kobj);
--      kobject_put(&mod->mkobj.kobj);
-- free_unload:
-       module_unload_free(mod);
- #if defined(CONFIG_MODULE_UNLOAD) && defined(CONFIG_SMP)
-       percpu_modfree(mod->refptr);