How to convert drivers/gpu/drm/i915/ to use local workqueue?

Rodrigo Vivi rodrigo.vivi at intel.com
Thu Jun 30 13:59:00 UTC 2022


On Thu, Jun 30, 2022 at 02:09:02PM +0100, Tvrtko Ursulin wrote:
> 
> On 30/06/2022 12:19, Tetsuo Handa wrote:
> > On 2022/06/30 19:17, Tvrtko Ursulin wrote:
> > > Could you give more context on reasoning here please? What is the difference
> > > between using the system_wq and flushing it from a random context? Or concern
> > > is about flushing from specific contexts?
> > 
> > Excuse me, but I couldn't catch what you want. Thus, I show three patterns of
> > problems with an example.
> > 
> > Commit c4f135d643823a86 ("workqueue: Wrap flush_workqueue() using a macro") says:
> > 
> >    Tejun Heo commented that it makes no sense at all to call flush_workqueue()
> >    on the shared WQs as the caller has no idea what it's gonna end up waiting for.
> > 
> >    The "Think twice before calling this function! It's very easy to get into trouble
> >    if you don't take great care." warning message does not help avoiding problems.
> > 
> >    Let's change the direction to that developers had better use their local WQs
> >    if flush_scheduled_work()/flush_workqueue(system_*_wq) is inevitable.
> > 
> > Three patterns of problems are:
> > 
> >    (a) Flushing from specific contexts (e.g. GFP_NOFS/GFP_NOIO) can cause deadlock
> >        (circular locking dependency) problem.
> > 
> >    (b) Flushing with specific locks (e.g. module_mutex) held can cause deadlock
> >        (circular locking dependency) problem.
> > 
> >    (c) Even if there is no possibility of deadlock, flushing with specific locks
> >        held can cause khungtaskd to complain.
> > 
> > An example of (a):
> > 
> >    ext4 filesystem called flush_scheduled_work(), which meant to wait for only
> >    work item scheduled by ext4 filesystem, tried to also wait for work item
> >    scheduled by 9p filesystem.
> >    https://syzkaller.appspot.com/bug?extid=bde0f89deacca7c765b8
> > 
> >    Fixed by reverting the problematic patch.
> > 
> > An example of (b):
> > 
> >    It is GFP_KERNEL context when module's __exit function is called. But whether
> >    flush_workqueue() is called from restricted context depends on what locks does
> >    the module's __exit function hold.
> > 
> >    If request_module() is called from some work function using one of system-wide WQs,
> >    and flush_workqueue() is called on that WQ from module's __exit function, the kernel
> >    might deadlock on module_mutex lock. Making sure that flush_workqueue() is not called
> >    on system-wide WQs is the safer choice.
> > 
> >    Commit 1b3ce51dde365296 ("Input: psmouse-smbus - avoid flush_scheduled_work() usage")
> >    is for drivers/input/mouse/psmouse-smbus.c .
> > 
> > An example of (c):
> > 
> >    ath9k driver calls schedule_work() via request_firmware_nowait().
> >    https://syzkaller.appspot.com/bug?id=78a242c8f1f4d15752c8ef4efc22974e2c52c833
> > 
> >    ath6kl driver calls flush_scheduled_work() which needlessly waits for completion
> >    of works scheduled by ath9k driver (i.e. loading firmware used by ath9k driver).
> >    https://syzkaller.appspot.com/bug?id=10a1cba59c42d11e12f897644341156eac9bb7ee
> > 
> >    Commit 4b2b8e748467985c ("ath6kl: avoid flush_scheduled_work() usage") in linux-next.git
> >    might be able to mitigate these problems. (Waiting for next merge window...)
> 
> Okay, from 1b3ce51dde365296:
> 
>  "Flushing system-wide workqueues is dangerous and will be forbidden."
> 
> Thank you, this exactly explains the motivation which is what I was after. I
> certainly agree there is a possibility for lock coupling via the shared wq
> so that is fine by me.
> 
> > > On the i915 specifics, the caller in drivers/gpu/drm/i915/gt/selftest_execlists.c
> > > I am pretty sure can be removed. It is synchronized with the error capture side of
> > > things which is not required for the test to work.
> > > 
> > > I can send a patch for that or you can, as you prefer?
> > 
> > OK. Please send a patch for that, for that patch will go linux-next.git tree via
> > a tree for gpu/drm/i915 driver.
> 
> Patch sent. If I am right the easiest solution was just to remove the flush.
> If I was wrong though I'll need to create a dedicated wq so we will see what
> our automated CI will say.

But besides of flush_scheduled_work() it looks like
we also need to take care of the flush_workqueue() calls, no?!

* i915_gem_drain_workqueue()
* intel_ggtt.c:   flush_workqueue(ggtt->vm.i915->wq);
* i915_gem_pm.c: flush_workqueue(i915->wq);

and the display ones for
dev_priv->modeset_wq
i915->flip_wq

besides the flush_scheduled_work in intel_modeset_driver_remove_noirq

> 
> Regards,
> 
> Tvrtko


More information about the dri-devel mailing list