Re: net/bluetooth: workqueue destruction WARNING in hci_unregister_dev

From: Tejun Heo
Date: Thu Feb 18 2016 - 12:44:37 EST


Hello,

Can you please do the followings?

1. Remove WQ_MEM_RECLAIM from the affected workqueue and see whether
the problem is reproducible. WQ_MEM_RECLAIM on anything bluetooth
doesn't make sense btw. Why is it there?

2. If WQ_MEM_RECLAIM makes the issue go away, see whether the attached
patch works too.

Thanks.

--
tejun
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 7ff5dc7..9824d4f 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4012,7 +4012,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
/* drain it before proceeding with destruction */
drain_workqueue(wq);

- /* sanity checks */
+ /* nothing should be in flight */
mutex_lock(&wq->mutex);
for_each_pwq(pwq, wq) {
int i;
@@ -4024,8 +4024,7 @@ void destroy_workqueue(struct workqueue_struct *wq)
}
}

- if (WARN_ON((pwq != wq->dfl_pwq) && (pwq->refcnt > 1)) ||
- WARN_ON(pwq->nr_active) ||
+ if (WARN_ON(pwq->nr_active) ||
WARN_ON(!list_empty(&pwq->delayed_works))) {
mutex_unlock(&wq->mutex);
return;
@@ -4046,6 +4045,13 @@ void destroy_workqueue(struct workqueue_struct *wq)
if (wq->rescuer)
kthread_stop(wq->rescuer->task);

+ /* rescuer is gone, everything should be quiescent now */
+ WARN_ON(!list_empty(&wq->maydays));
+ mutex_lock(&wq->mutex);
+ for_each_pwq(pwq, wq)
+ WARN_ON((pwq != wq->dfl_pwq) && (pwq->refcnt > 1));
+ mutex_unlock(&wq->mutex);
+
if (!(wq->flags & WQ_UNBOUND)) {
/*
* The base ref is never dropped on per-cpu pwqs. Directly