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

Reply via email to