Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

RDMA/core: Avoid flush_workqueue(system_unbound_wq) usage

Flushing system-wide workqueues is dangerous and will be forbidden.
Replace system_unbound_wq with local ib_unreg_wq.

Link: https://lore.kernel.org/r/252cefb0-a400-83f6-2032-333d69f52c1b@I-love.SAKURA.ne.jp
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>

authored by

Tetsuo Handa and committed by
Jason Gunthorpe
ff815a89 0f328c70

+14 -10
+14 -10
drivers/infiniband/core/device.c
··· 58 58 struct workqueue_struct *ib_comp_unbound_wq; 59 59 struct workqueue_struct *ib_wq; 60 60 EXPORT_SYMBOL_GPL(ib_wq); 61 + static struct workqueue_struct *ib_unreg_wq; 61 62 62 63 /* 63 64 * Each of the three rwsem locks (devices, clients, client_data) protects the ··· 1603 1602 WARN_ON(!refcount_read(&ib_dev->refcount)); 1604 1603 WARN_ON(!ib_dev->ops.dealloc_driver); 1605 1604 get_device(&ib_dev->dev); 1606 - if (!queue_work(system_unbound_wq, &ib_dev->unregistration_work)) 1605 + if (!queue_work(ib_unreg_wq, &ib_dev->unregistration_work)) 1607 1606 put_device(&ib_dev->dev); 1608 1607 } 1609 1608 EXPORT_SYMBOL(ib_unregister_device_queued); ··· 2752 2751 2753 2752 static int __init ib_core_init(void) 2754 2753 { 2755 - int ret; 2754 + int ret = -ENOMEM; 2756 2755 2757 2756 ib_wq = alloc_workqueue("infiniband", 0, 0); 2758 2757 if (!ib_wq) 2759 2758 return -ENOMEM; 2760 2759 2760 + ib_unreg_wq = alloc_workqueue("ib-unreg-wq", WQ_UNBOUND, 2761 + WQ_UNBOUND_MAX_ACTIVE); 2762 + if (!ib_unreg_wq) 2763 + goto err; 2764 + 2761 2765 ib_comp_wq = alloc_workqueue("ib-comp-wq", 2762 2766 WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_SYSFS, 0); 2763 - if (!ib_comp_wq) { 2764 - ret = -ENOMEM; 2765 - goto err; 2766 - } 2767 + if (!ib_comp_wq) 2768 + goto err_unbound; 2767 2769 2768 2770 ib_comp_unbound_wq = 2769 2771 alloc_workqueue("ib-comp-unb-wq", 2770 2772 WQ_UNBOUND | WQ_HIGHPRI | WQ_MEM_RECLAIM | 2771 2773 WQ_SYSFS, WQ_UNBOUND_MAX_ACTIVE); 2772 - if (!ib_comp_unbound_wq) { 2773 - ret = -ENOMEM; 2774 + if (!ib_comp_unbound_wq) 2774 2775 goto err_comp; 2775 - } 2776 2776 2777 2777 ret = class_register(&ib_class); 2778 2778 if (ret) { ··· 2833 2831 destroy_workqueue(ib_comp_unbound_wq); 2834 2832 err_comp: 2835 2833 destroy_workqueue(ib_comp_wq); 2834 + err_unbound: 2835 + destroy_workqueue(ib_unreg_wq); 2836 2836 err: 2837 2837 destroy_workqueue(ib_wq); 2838 2838 return ret; ··· 2856 2852 destroy_workqueue(ib_comp_wq); 2857 2853 /* Make sure that any pending umem accounting work is done. */ 2858 2854 destroy_workqueue(ib_wq); 2859 - flush_workqueue(system_unbound_wq); 2855 + destroy_workqueue(ib_unreg_wq); 2860 2856 WARN_ON(!xa_empty(&clients)); 2861 2857 WARN_ON(!xa_empty(&devices)); 2862 2858 }