]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
3.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Jul 2014 00:11:24 +0000 (17:11 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 14 Jul 2014 00:11:24 +0000 (17:11 -0700)
added patches:
ahci-imx-manage-only-sata_ref_clk-in-imx_sata_enable.patch
cpuset-mempolicy-fix-sleeping-function-called-from-invalid-context.patch
i8k-fix-non-smp-operation.patch
workqueue-fix-dev_set_uevent_suppress-imbalance.patch
workqueue-zero-cpumask-of-wq_numa_possible_cpumask-on-init.patch

queue-3.15/ahci-imx-manage-only-sata_ref_clk-in-imx_sata_enable.patch [new file with mode: 0644]
queue-3.15/cpuset-mempolicy-fix-sleeping-function-called-from-invalid-context.patch [new file with mode: 0644]
queue-3.15/i8k-fix-non-smp-operation.patch [new file with mode: 0644]
queue-3.15/kernfs-introduce-kernfs_pin_sb.patch [deleted file]
queue-3.15/series
queue-3.15/workqueue-fix-dev_set_uevent_suppress-imbalance.patch [new file with mode: 0644]
queue-3.15/workqueue-zero-cpumask-of-wq_numa_possible_cpumask-on-init.patch [new file with mode: 0644]

diff --git a/queue-3.15/ahci-imx-manage-only-sata_ref_clk-in-imx_sata_enable.patch b/queue-3.15/ahci-imx-manage-only-sata_ref_clk-in-imx_sata_enable.patch
new file mode 100644 (file)
index 0000000..16f37aa
--- /dev/null
@@ -0,0 +1,157 @@
+From e6dd42a917e62d916c6e513dbf87a4dec8cf3a1c Mon Sep 17 00:00:00 2001
+From: Shawn Guo <shawn.guo@freescale.com>
+Date: Wed, 28 May 2014 23:05:39 +0800
+Subject: ahci: imx: manage only sata_ref_clk in imx_sata_enable[disable]
+
+From: Shawn Guo <shawn.guo@freescale.com>
+
+commit e6dd42a917e62d916c6e513dbf87a4dec8cf3a1c upstream.
+
+Doing suspend/resume on imx6q and imx53 boards with no SATA disk
+attached will trigger the following warning.
+
+------------[ cut here ]------------
+WARNING: CPU: 0 PID: 661 at drivers/ata/libahci.c:224 ahci_enable_ahci+0x74/0x8)
+Modules linked in:
+CPU: 0 PID: 661 Comm: sh Tainted: G        W     3.15.0-rc5-next-20140521-000027
+Backtrace:
+[<80011c90>] (dump_backtrace) from [<80011e2c>] (show_stack+0x18/0x1c)
+ r6:803a22f4 r5:00000000 r4:00000000 r3:00000000
+[<80011e14>] (show_stack) from [<80661e60>] (dump_stack+0x88/0xa4)
+[<80661dd8>] (dump_stack) from [<80028fdc>] (warn_slowpath_common+0x70/0x94)
+ r5:00000009 r4:00000000
+[<80028f6c>] (warn_slowpath_common) from [<80029024>] (warn_slowpath_null+0x24/)
+ r8:808f68c4 r7:00000000 r6:00000000 r5:00000000 r4:e0810004
+[<80029000>] (warn_slowpath_null) from [<803a22f4>] (ahci_enable_ahci+0x74/0x80)
+[<803a2280>] (ahci_enable_ahci) from [<803a2324>] (ahci_reset_controller+0x24/0)
+ r8:ddcd9410 r7:80351178 r6:ddcd9444 r5:dde8b850 r4:e0810000 r3:ddf35e90
+[<803a2300>] (ahci_reset_controller) from [<803a2c68>] (ahci_platform_resume_ho)
+ r7:80351178 r6:ddcd9444 r5:dde8b850 r4:ddcd9410
+[<803a2c30>] (ahci_platform_resume_host) from [<803a38f0>] (imx_ahci_resume+0x2)
+ r5:00000000 r4:ddcd9410
+[<803a38c4>] (imx_ahci_resume) from [<803511ac>] (platform_pm_resume+0x34/0x54)
+....
+
+The reason is that the SATA controller has no working clock at this
+point, and thus ahci_enable_ahci() fails to enable the controller.  In
+case that there is no SATA disk attached, the imx_sata_disable() gets
+called in ahci_imx_error_handler(), and both sata_clk and sata_ref_clk
+will be disabled there.  Because all the imx_sata_enable() calls
+afterward will return immediately due to imxpriv->no_device check, the
+SATA controller working clock sata_clk will never get any chance to be
+enabled again.
+
+This is a regression caused by commit 90870d79d4f2 (ahci-imx: Port to
+library-ised ahci_platform).  Before the commit, only sata_ref_clk is
+managed by the driver in enable/disable function.  But after the commit,
+all the clocks are enabled/disabled in a row by ahci platform helpers
+ahci_platform_enable[disable]_clks.  Since ahb_clk is a bus clock which
+does not have gate at all, and i.MX low-power hardware module already
+manages sata_clk across suspend/resume cycle, the only clock that needs
+to be managed by software is sata_ref_clk.
+
+So instead of using ahci_platform_enable[disable]_clks to manage all
+the clocks in a row from imx_sata_enable[disable], we should manage
+only sata_ref_clk in there.
+
+Reported-by: Fabio Estevam <fabio.estevam@freescale.com>
+Fixes: 90870d79d4f2 (ahci-imx: Port to library-ised ahci_platform)
+Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
+Acked-by: Hans de Goede <hdegoede@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/ata/ahci_imx.c |   35 +++++++++++++++++++++++++++++++----
+ 1 file changed, 31 insertions(+), 4 deletions(-)
+
+--- a/drivers/ata/ahci_imx.c
++++ b/drivers/ata/ahci_imx.c
+@@ -58,6 +58,8 @@ enum ahci_imx_type {
+ struct imx_ahci_priv {
+       struct platform_device *ahci_pdev;
+       enum ahci_imx_type type;
++      struct clk *sata_clk;
++      struct clk *sata_ref_clk;
+       struct clk *ahb_clk;
+       struct regmap *gpr;
+       bool no_device;
+@@ -224,7 +226,7 @@ static int imx_sata_enable(struct ahci_h
+                       return ret;
+       }
+-      ret = ahci_platform_enable_clks(hpriv);
++      ret = clk_prepare_enable(imxpriv->sata_ref_clk);
+       if (ret < 0)
+               goto disable_regulator;
+@@ -291,7 +293,7 @@ static void imx_sata_disable(struct ahci
+                                  !IMX6Q_GPR13_SATA_MPLL_CLK_EN);
+       }
+-      ahci_platform_disable_clks(hpriv);
++      clk_disable_unprepare(imxpriv->sata_ref_clk);
+       if (hpriv->target_pwr)
+               regulator_disable(hpriv->target_pwr);
+@@ -385,6 +387,19 @@ static int imx_ahci_probe(struct platfor
+       imxpriv->no_device = false;
+       imxpriv->first_time = true;
+       imxpriv->type = (enum ahci_imx_type)of_id->data;
++
++      imxpriv->sata_clk = devm_clk_get(dev, "sata");
++      if (IS_ERR(imxpriv->sata_clk)) {
++              dev_err(dev, "can't get sata clock.\n");
++              return PTR_ERR(imxpriv->sata_clk);
++      }
++
++      imxpriv->sata_ref_clk = devm_clk_get(dev, "sata_ref");
++      if (IS_ERR(imxpriv->sata_ref_clk)) {
++              dev_err(dev, "can't get sata_ref clock.\n");
++              return PTR_ERR(imxpriv->sata_ref_clk);
++      }
++
+       imxpriv->ahb_clk = devm_clk_get(dev, "ahb");
+       if (IS_ERR(imxpriv->ahb_clk)) {
+               dev_err(dev, "can't get ahb clock.\n");
+@@ -407,10 +422,14 @@ static int imx_ahci_probe(struct platfor
+       hpriv->plat_data = imxpriv;
+-      ret = imx_sata_enable(hpriv);
++      ret = clk_prepare_enable(imxpriv->sata_clk);
+       if (ret)
+               return ret;
++      ret = imx_sata_enable(hpriv);
++      if (ret)
++              goto disable_clk;
++
+       /*
+        * Configure the HWINIT bits of the HOST_CAP and HOST_PORTS_IMPL,
+        * and IP vendor specific register IMX_TIMER1MS.
+@@ -434,16 +453,24 @@ static int imx_ahci_probe(struct platfor
+       ret = ahci_platform_init_host(pdev, hpriv, &ahci_imx_port_info, 0, 0);
+       if (ret)
+-              imx_sata_disable(hpriv);
++              goto disable_sata;
++
++      return 0;
++disable_sata:
++      imx_sata_disable(hpriv);
++disable_clk:
++      clk_disable_unprepare(imxpriv->sata_clk);
+       return ret;
+ }
+ static void ahci_imx_host_stop(struct ata_host *host)
+ {
+       struct ahci_host_priv *hpriv = host->private_data;
++      struct imx_ahci_priv *imxpriv = hpriv->plat_data;
+       imx_sata_disable(hpriv);
++      clk_disable_unprepare(imxpriv->sata_clk);
+ }
+ #ifdef CONFIG_PM_SLEEP
diff --git a/queue-3.15/cpuset-mempolicy-fix-sleeping-function-called-from-invalid-context.patch b/queue-3.15/cpuset-mempolicy-fix-sleeping-function-called-from-invalid-context.patch
new file mode 100644 (file)
index 0000000..40df42d
--- /dev/null
@@ -0,0 +1,100 @@
+From 391acf970d21219a2a5446282d3b20eace0c0d7a Mon Sep 17 00:00:00 2001
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Date: Wed, 25 Jun 2014 09:57:18 +0800
+Subject: cpuset,mempolicy: fix sleeping function called from invalid context
+
+From: Gu Zheng <guz.fnst@cn.fujitsu.com>
+
+commit 391acf970d21219a2a5446282d3b20eace0c0d7a upstream.
+
+When runing with the kernel(3.15-rc7+), the follow bug occurs:
+[ 9969.258987] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:586
+[ 9969.359906] in_atomic(): 1, irqs_disabled(): 0, pid: 160655, name: python
+[ 9969.441175] INFO: lockdep is turned off.
+[ 9969.488184] CPU: 26 PID: 160655 Comm: python Tainted: G       A      3.15.0-rc7+ #85
+[ 9969.581032] Hardware name: FUJITSU-SV PRIMEQUEST 1800E/SB, BIOS PRIMEQUEST 1000 Series BIOS Version 1.39 11/16/2012
+[ 9969.706052]  ffffffff81a20e60 ffff8803e941fbd0 ffffffff8162f523 ffff8803e941fd18
+[ 9969.795323]  ffff8803e941fbe0 ffffffff8109995a ffff8803e941fc58 ffffffff81633e6c
+[ 9969.884710]  ffffffff811ba5dc ffff880405c6b480 ffff88041fdd90a0 0000000000002000
+[ 9969.974071] Call Trace:
+[ 9970.003403]  [<ffffffff8162f523>] dump_stack+0x4d/0x66
+[ 9970.065074]  [<ffffffff8109995a>] __might_sleep+0xfa/0x130
+[ 9970.130743]  [<ffffffff81633e6c>] mutex_lock_nested+0x3c/0x4f0
+[ 9970.200638]  [<ffffffff811ba5dc>] ? kmem_cache_alloc+0x1bc/0x210
+[ 9970.272610]  [<ffffffff81105807>] cpuset_mems_allowed+0x27/0x140
+[ 9970.344584]  [<ffffffff811b1303>] ? __mpol_dup+0x63/0x150
+[ 9970.409282]  [<ffffffff811b1385>] __mpol_dup+0xe5/0x150
+[ 9970.471897]  [<ffffffff811b1303>] ? __mpol_dup+0x63/0x150
+[ 9970.536585]  [<ffffffff81068c86>] ? copy_process.part.23+0x606/0x1d40
+[ 9970.613763]  [<ffffffff810bf28d>] ? trace_hardirqs_on+0xd/0x10
+[ 9970.683660]  [<ffffffff810ddddf>] ? monotonic_to_bootbased+0x2f/0x50
+[ 9970.759795]  [<ffffffff81068cf0>] copy_process.part.23+0x670/0x1d40
+[ 9970.834885]  [<ffffffff8106a598>] do_fork+0xd8/0x380
+[ 9970.894375]  [<ffffffff81110e4c>] ? __audit_syscall_entry+0x9c/0xf0
+[ 9970.969470]  [<ffffffff8106a8c6>] SyS_clone+0x16/0x20
+[ 9971.030011]  [<ffffffff81642009>] stub_clone+0x69/0x90
+[ 9971.091573]  [<ffffffff81641c29>] ? system_call_fastpath+0x16/0x1b
+
+The cause is that cpuset_mems_allowed() try to take
+mutex_lock(&callback_mutex) under the rcu_read_lock(which was hold in
+__mpol_dup()). And in cpuset_mems_allowed(), the access to cpuset is
+under rcu_read_lock, so in __mpol_dup, we can reduce the rcu_read_lock
+protection region to protect the access to cpuset only in
+current_cpuset_is_being_rebound(). So that we can avoid this bug.
+
+This patch is a temporary solution that just addresses the bug
+mentioned above, can not fix the long-standing issue about cpuset.mems
+rebinding on fork():
+
+"When the forker's task_struct is duplicated (which includes
+ ->mems_allowed) and it races with an update to cpuset_being_rebound
+ in update_tasks_nodemask() then the task's mems_allowed doesn't get
+ updated. And the child task's mems_allowed can be wrong if the
+ cpuset's nodemask changes before the child has been added to the
+ cgroup's tasklist."
+
+Signed-off-by: Gu Zheng <guz.fnst@cn.fujitsu.com>
+Acked-by: Li Zefan <lizefan@huawei.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/cpuset.c |    8 +++++++-
+ mm/mempolicy.c  |    2 --
+ 2 files changed, 7 insertions(+), 3 deletions(-)
+
+--- a/kernel/cpuset.c
++++ b/kernel/cpuset.c
+@@ -1188,7 +1188,13 @@ done:
+ int current_cpuset_is_being_rebound(void)
+ {
+-      return task_cs(current) == cpuset_being_rebound;
++      int ret;
++
++      rcu_read_lock();
++      ret = task_cs(current) == cpuset_being_rebound;
++      rcu_read_unlock();
++
++      return ret;
+ }
+ static int update_relax_domain_level(struct cpuset *cs, s64 val)
+--- a/mm/mempolicy.c
++++ b/mm/mempolicy.c
+@@ -2136,7 +2136,6 @@ struct mempolicy *__mpol_dup(struct memp
+       } else
+               *new = *old;
+-      rcu_read_lock();
+       if (current_cpuset_is_being_rebound()) {
+               nodemask_t mems = cpuset_mems_allowed(current);
+               if (new->flags & MPOL_F_REBINDING)
+@@ -2144,7 +2143,6 @@ struct mempolicy *__mpol_dup(struct memp
+               else
+                       mpol_rebind_policy(new, &mems, MPOL_REBIND_ONCE);
+       }
+-      rcu_read_unlock();
+       atomic_set(&new->refcnt, 1);
+       return new;
+ }
diff --git a/queue-3.15/i8k-fix-non-smp-operation.patch b/queue-3.15/i8k-fix-non-smp-operation.patch
new file mode 100644 (file)
index 0000000..d1c10d3
--- /dev/null
@@ -0,0 +1,42 @@
+From 6d827fbcc370ca259a2905309f64161ab7b10596 Mon Sep 17 00:00:00 2001
+From: Guenter Roeck <linux@roeck-us.net>
+Date: Sat, 21 Jun 2014 08:08:08 -0700
+Subject: i8k: Fix non-SMP operation
+
+From: Guenter Roeck <linux@roeck-us.net>
+
+commit 6d827fbcc370ca259a2905309f64161ab7b10596 upstream.
+
+Commit f36fdb9f0266 (i8k: Force SMM to run on CPU 0) adds support
+for multi-core CPUs to the driver. Unfortunately, that causes it
+to fail loading if compiled without SMP support, at least on
+32 bit kernels. Kernel log shows "i8k: unable to get SMM Dell
+signature", and function i8k_smm is found to return -EINVAL.
+
+Testing revealed that the culprit is the missing return value check
+of set_cpus_allowed_ptr.
+
+Fixes: f36fdb9f0266 (i8k: Force SMM to run on CPU 0)
+Reported-by: Jim Bos <jim876@xs4all.nl>
+Tested-by: Jim Bos <jim876@xs4all.nl>
+Signed-off-by: Guenter Roeck <linux@roeck-us.net>
+Cc: Andreas Mohr <andi@lisas.de>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/char/i8k.c |    4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/char/i8k.c
++++ b/drivers/char/i8k.c
+@@ -138,7 +138,9 @@ static int i8k_smm(struct smm_regs *regs
+       if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
+               return -ENOMEM;
+       cpumask_copy(old_mask, &current->cpus_allowed);
+-      set_cpus_allowed_ptr(current, cpumask_of(0));
++      rc = set_cpus_allowed_ptr(current, cpumask_of(0));
++      if (rc)
++              goto out;
+       if (smp_processor_id() != 0) {
+               rc = -EBUSY;
+               goto out;
diff --git a/queue-3.15/kernfs-introduce-kernfs_pin_sb.patch b/queue-3.15/kernfs-introduce-kernfs_pin_sb.patch
deleted file mode 100644 (file)
index 58201a2..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-From 4e26445faad366d67d7723622bf6a60a6f0f5993 Mon Sep 17 00:00:00 2001
-From: Li Zefan <lizefan@huawei.com>
-Date: Mon, 30 Jun 2014 11:50:28 +0800
-Subject: kernfs: introduce kernfs_pin_sb()
-
-From: Li Zefan <lizefan@huawei.com>
-
-commit 4e26445faad366d67d7723622bf6a60a6f0f5993 upstream.
-
-kernfs_pin_sb() tries to get a refcnt of the superblock.
-
-This will be used by cgroupfs.
-
-v2:
-- make kernfs_pin_sb() return the superblock.
-- drop kernfs_drop_sb().
-
-tj: Updated the comment a bit.
-
-[ This is a prerequisite for a bugfix. ]
-Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-Signed-off-by: Li Zefan <lizefan@huawei.com>
-Signed-off-by: Tejun Heo <tj@kernel.org>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- fs/kernfs/mount.c      |   30 ++++++++++++++++++++++++++++++
- include/linux/kernfs.h |    1 +
- 2 files changed, 31 insertions(+)
-
---- a/fs/kernfs/mount.c
-+++ b/fs/kernfs/mount.c
-@@ -200,6 +200,36 @@ void kernfs_kill_sb(struct super_block *
-       kernfs_put(root_kn);
- }
-+/**
-+ * kernfs_pin_sb: try to pin the superblock associated with a kernfs_root
-+ * @kernfs_root: the kernfs_root in question
-+ * @ns: the namespace tag
-+ *
-+ * Pin the superblock so the superblock won't be destroyed in subsequent
-+ * operations.  This can be used to block ->kill_sb() which may be useful
-+ * for kernfs users which dynamically manage superblocks.
-+ *
-+ * Returns NULL if there's no superblock associated to this kernfs_root, or
-+ * -EINVAL if the superblock is being freed.
-+ */
-+struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns)
-+{
-+      struct kernfs_super_info *info;
-+      struct super_block *sb = NULL;
-+
-+      mutex_lock(&kernfs_mutex);
-+      list_for_each_entry(info, &root->supers, node) {
-+              if (info->ns == ns) {
-+                      sb = info->sb;
-+                      if (!atomic_inc_not_zero(&info->sb->s_active))
-+                              sb = ERR_PTR(-EINVAL);
-+                      break;
-+              }
-+      }
-+      mutex_unlock(&kernfs_mutex);
-+      return sb;
-+}
-+
- void __init kernfs_init(void)
- {
-       kernfs_node_cache = kmem_cache_create("kernfs_node_cache",
---- a/include/linux/kernfs.h
-+++ b/include/linux/kernfs.h
-@@ -300,6 +300,7 @@ struct dentry *kernfs_mount_ns(struct fi
-                              struct kernfs_root *root, unsigned long magic,
-                              bool *new_sb_created, const void *ns);
- void kernfs_kill_sb(struct super_block *sb);
-+struct super_block *kernfs_pin_sb(struct kernfs_root *root, const void *ns);
- void kernfs_init(void);
index 46ad9e0a9845c2f3df721bbd71e0837ae27f37c4..f4513fdb30ad01aceb7b85c46240043b8231f783 100644 (file)
@@ -6,4 +6,8 @@ iio-ti_am335x_adc-fix-use-same-step-id-at-fifos-both-ends.patch
 serial-test-for-no-tx-data-on-tx-restart.patch
 parisc-add-serial-ports-of-c8000-1ghz-machine-to-hardware-database.patch
 parisc-fix-fanotify_mark-syscall-on-32bit-compat-kernel.patch
-kernfs-introduce-kernfs_pin_sb.patch
+workqueue-fix-dev_set_uevent_suppress-imbalance.patch
+cpuset-mempolicy-fix-sleeping-function-called-from-invalid-context.patch
+workqueue-zero-cpumask-of-wq_numa_possible_cpumask-on-init.patch
+ahci-imx-manage-only-sata_ref_clk-in-imx_sata_enable.patch
+i8k-fix-non-smp-operation.patch
diff --git a/queue-3.15/workqueue-fix-dev_set_uevent_suppress-imbalance.patch b/queue-3.15/workqueue-fix-dev_set_uevent_suppress-imbalance.patch
new file mode 100644 (file)
index 0000000..9d2833a
--- /dev/null
@@ -0,0 +1,31 @@
+From bddbceb688c6d0decaabc7884fede319d02f96c8 Mon Sep 17 00:00:00 2001
+From: Maxime Bizon <mbizon@freebox.fr>
+Date: Mon, 23 Jun 2014 16:35:35 +0200
+Subject: workqueue: fix dev_set_uevent_suppress() imbalance
+
+From: Maxime Bizon <mbizon@freebox.fr>
+
+commit bddbceb688c6d0decaabc7884fede319d02f96c8 upstream.
+
+Uevents are suppressed during attributes registration, but never
+restored, so kobject_uevent() does nothing.
+
+Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Fixes: 226223ab3c4118ddd10688cc2c131135848371ab
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/workqueue.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -3422,6 +3422,7 @@ int workqueue_sysfs_register(struct work
+               }
+       }
++      dev_set_uevent_suppress(&wq_dev->dev, false);
+       kobject_uevent(&wq_dev->dev.kobj, KOBJ_ADD);
+       return 0;
+ }
diff --git a/queue-3.15/workqueue-zero-cpumask-of-wq_numa_possible_cpumask-on-init.patch b/queue-3.15/workqueue-zero-cpumask-of-wq_numa_possible_cpumask-on-init.patch
new file mode 100644 (file)
index 0000000..cd190fb
--- /dev/null
@@ -0,0 +1,86 @@
+From 5a6024f1604eef119cf3a6fa413fe0261a81a8f3 Mon Sep 17 00:00:00 2001
+From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
+Date: Mon, 7 Jul 2014 09:56:48 -0400
+Subject: workqueue: zero cpumask of wq_numa_possible_cpumask on init
+
+From: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
+
+commit 5a6024f1604eef119cf3a6fa413fe0261a81a8f3 upstream.
+
+When hot-adding and onlining CPU, kernel panic occurs, showing following
+call trace.
+
+  BUG: unable to handle kernel paging request at 0000000000001d08
+  IP: [<ffffffff8114acfd>] __alloc_pages_nodemask+0x9d/0xb10
+  PGD 0
+  Oops: 0000 [#1] SMP
+  ...
+  Call Trace:
+   [<ffffffff812b8745>] ? cpumask_next_and+0x35/0x50
+   [<ffffffff810a3283>] ? find_busiest_group+0x113/0x8f0
+   [<ffffffff81193bc9>] ? deactivate_slab+0x349/0x3c0
+   [<ffffffff811926f1>] new_slab+0x91/0x300
+   [<ffffffff815de95a>] __slab_alloc+0x2bb/0x482
+   [<ffffffff8105bc1c>] ? copy_process.part.25+0xfc/0x14c0
+   [<ffffffff810a3c78>] ? load_balance+0x218/0x890
+   [<ffffffff8101a679>] ? sched_clock+0x9/0x10
+   [<ffffffff81105ba9>] ? trace_clock_local+0x9/0x10
+   [<ffffffff81193d1c>] kmem_cache_alloc_node+0x8c/0x200
+   [<ffffffff8105bc1c>] copy_process.part.25+0xfc/0x14c0
+   [<ffffffff81114d0d>] ? trace_buffer_unlock_commit+0x4d/0x60
+   [<ffffffff81085a80>] ? kthread_create_on_node+0x140/0x140
+   [<ffffffff8105d0ec>] do_fork+0xbc/0x360
+   [<ffffffff8105d3b6>] kernel_thread+0x26/0x30
+   [<ffffffff81086652>] kthreadd+0x2c2/0x300
+   [<ffffffff81086390>] ? kthread_create_on_cpu+0x60/0x60
+   [<ffffffff815f20ec>] ret_from_fork+0x7c/0xb0
+   [<ffffffff81086390>] ? kthread_create_on_cpu+0x60/0x60
+
+In my investigation, I found the root cause is wq_numa_possible_cpumask.
+All entries of wq_numa_possible_cpumask is allocated by
+alloc_cpumask_var_node(). And these entries are used without initializing.
+So these entries have wrong value.
+
+When hot-adding and onlining CPU, wq_update_unbound_numa() is called.
+wq_update_unbound_numa() calls alloc_unbound_pwq(). And alloc_unbound_pwq()
+calls get_unbound_pool(). In get_unbound_pool(), worker_pool->node is set
+as follow:
+
+3592         /* if cpumask is contained inside a NUMA node, we belong to that node */
+3593         if (wq_numa_enabled) {
+3594                 for_each_node(node) {
+3595                         if (cpumask_subset(pool->attrs->cpumask,
+3596                                            wq_numa_possible_cpumask[node])) {
+3597                                 pool->node = node;
+3598                                 break;
+3599                         }
+3600                 }
+3601         }
+
+But wq_numa_possible_cpumask[node] does not have correct cpumask. So, wrong
+node is selected. As a result, kernel panic occurs.
+
+By this patch, all entries of wq_numa_possible_cpumask are allocated by
+zalloc_cpumask_var_node to initialize them. And the panic disappeared.
+
+Signed-off-by: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com>
+Reviewed-by: Lai Jiangshan <laijs@cn.fujitsu.com>
+Signed-off-by: Tejun Heo <tj@kernel.org>
+Fixes: bce903809ab3 ("workqueue: add wq_numa_tbl_len and wq_numa_possible_cpumask[]")
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ kernel/workqueue.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/kernel/workqueue.c
++++ b/kernel/workqueue.c
+@@ -5034,7 +5034,7 @@ static void __init wq_numa_init(void)
+       BUG_ON(!tbl);
+       for_each_node(node)
+-              BUG_ON(!alloc_cpumask_var_node(&tbl[node], GFP_KERNEL,
++              BUG_ON(!zalloc_cpumask_var_node(&tbl[node], GFP_KERNEL,
+                               node_online(node) ? node : NUMA_NO_NODE));
+       for_each_possible_cpu(cpu) {