• L
    workqueue: avoid false negative WARN_ON() in destroy_workqueue() · 5c529597
    Lai Jiangshan 提交于
    destroy_workqueue() performs several sanity checks before proceeding
    with destruction of a workqueue.  One of the checks verifies that
    refcnt of each pwq (pool_workqueue) is over 1 as at that point there
    should be no in-flight work items and the only holder of pwq refs is
    the workqueue itself.
    
    This worked fine as a workqueue used to hold only one reference to its
    pwqs; however, since 4c16bd32 ("workqueue: implement NUMA affinity
    for unbound workqueues"), a workqueue may hold multiple references to
    its default pwq triggering this sanity check spuriously.
    
    Fix it by not triggering the pwq->refcnt assertion on default pwqs.
    
    An example spurious WARN trigger follows.
    
     WARNING: at kernel/workqueue.c:4201 destroy_workqueue+0x6a/0x13e()
     Hardware name: 4286C12
     Modules linked in: sdhci_pci sdhci mmc_core usb_storage i915 drm_kms_helper drm i2c_algo_bit i2c_core video
     Pid: 361, comm: umount Not tainted 3.9.0-rc5+ #29
     Call Trace:
      [<c04314a7>] warn_slowpath_common+0x7c/0x93
      [<c04314e0>] warn_slowpath_null+0x22/0x24
      [<c044796a>] destroy_workqueue+0x6a/0x13e
      [<c056dc01>] ext4_put_super+0x43/0x2c4
      [<c04fb7b8>] generic_shutdown_super+0x4b/0xb9
      [<c04fb848>] kill_block_super+0x22/0x60
      [<c04fb960>] deactivate_locked_super+0x2f/0x56
      [<c04fc41b>] deactivate_super+0x2e/0x31
      [<c050f1e6>] mntput_no_expire+0x103/0x108
      [<c050fdce>] sys_umount+0x2a2/0x2c4
      [<c050fe0e>] sys_oldumount+0x1e/0x20
      [<c085ba4d>] sysenter_do_call+0x12/0x38
    
    tj: Rewrote description.
    Signed-off-by: NLai Jiangshan <laijs@cn.fujitsu.com>
    Signed-off-by: NTejun Heo <tj@kernel.org>
    Reported-by: NFengguang Wu <fengguang.wu@intel.com>
    5c529597
workqueue.c 134.6 KB