Messages in this thread | | | Subject | Re: single-threaded wq lockdep is broken | From | Johannes Berg <> | Date | Wed, 31 May 2017 10:36:36 +0200 |
| |
Hi,
> > #include <linux/kernel.h> > > #include <linux/mutex.h> > > #include <linux/workqueue.h> > > #include <linux/module.h> > > #include <linux/delay.h> > > > > DEFINE_MUTEX(mtx); > > static struct workqueue_struct *wq; > > static struct work_struct w1, w2; > > > > static void w1_wk(struct work_struct *w) > > { > > mutex_lock(&mtx); > > msleep(100); > > mutex_unlock(&mtx); > > } > > > > static void w2_wk(struct work_struct *w) > > { > > } > > > > /* > > * if not defined, then lockdep should warn only, > > I guess when DEADLOCK not defined, there is no > work is queued nor executed, therefore, no lock > dependence is recorded, and there is no warn > either. > > > * if defined, the system will really deadlock. > > */ > > > > //#define DEADLOCK > > > > static int init(void) > > { > > wq = create_singlethread_workqueue("test"); > > if (!wq) > > return -ENOMEM; > > INIT_WORK(&w1, w1_wk); > > INIT_WORK(&w2, w2_wk); > > > > /* add lock dependence, the lockdep should warn */ > queue_work(wq, &w1); > queue_work(wq, &w2); > flush_work(&w1); > > > #ifdef DEADLOCK > > queue_work(wq, &w1); > > queue_work(wq, &w2); > > #endif > > mutex_lock(&mtx); > > flush_work(&w2); > > mutex_unlock(&mtx); > > > > #ifndef DEADLOCK > > queue_work(wq, &w1); > > queue_work(wq, &w2); > > #endif
This was "ifndef", so it does in fact run here, just like you suggested. It doesn't warn though.
I don't think the order of queue/flush would matter, in fact, if you insert it like you did, with the flush outside the mutex, no issue exists (until the later flush)
johannes
| |