if flush_scheduled_work() is allegedly overkill, why do drivers use it?
Greg Freemyer
greg.freemyer at gmail.com
Fri Oct 19 11:06:08 EDT 2012
On Fri, Oct 19, 2012 at 10:12 AM, Robert P. J. Day
<rpjday at crashcourse.ca> wrote:
>
> working my way through work queues and read this in workqueue.h:
>
> /**
> * flush_scheduled_work - ensure that any scheduled work has run to completion.
> *
> * Forces execution of the kernel-global workqueue and blocks until its
> * completion.
> *
> * Think twice before calling this function! It's very easy to get into
> * trouble if you don't take great care. Either of the following situations
> * will lead to deadlock:
> *
> * One of the work items currently on the workqueue needs to acquire
> * a lock held by your code or its caller.
> *
> * Your code is running in the context of a work routine.
> *
> * They will be detected by lockdep when they occur, but the first might not
> * occur very often. It depends on what work items are on the workqueue and
> * what locks they need, which you have no control over.
> *
> * In most situations flushing the entire workqueue is overkill; you merely
> * need to know that a particular work item isn't queued and isn't running.
> * In such cases you should use cancel_delayed_work_sync() or
> * cancel_work_sync() instead.
> */
>
> and yet, there are quite a few drivers that do just that:
>
> $ grep -rw flush_scheduled_work drivers
> drivers/scsi/scsi_scan.c: flush_scheduled_work();
> drivers/scsi/qla2xxx/qla_target.c: flush_scheduled_work();
> drivers/leds/leds-blinkm.c: flush_scheduled_work();
> drivers/acpi/osl.c: * which invoke flush_scheduled_work/acpi_os_wait_events_complete
> drivers/staging/olpc_dcon/olpc_dcon.c: flush_scheduled_work();
> drivers/staging/rtl8192u/r8192U_core.c:// flush_scheduled_work();
> drivers/staging/wlan-ng/prism2usb.c: flush_scheduled_work();
> drivers/staging/iio/light/tsl2563.c: flush_scheduled_work();
> drivers/staging/iio/light/tsl2563.c: flush_scheduled_work();
> drivers/staging/rtl8712/usb_intf.c: flush_scheduled_work();
> drivers/message/fusion/mptscsih.c: flush_scheduled_work();
> drivers/rtc/rtc-dev.c: flush_scheduled_work();
> drivers/rtc/rtc-88pm860x.c: flush_scheduled_work();
> drivers/misc/mei/main.c: flush_scheduled_work();
> drivers/misc/mei/main.c: flush_scheduled_work();
> ... snip, even more after this ...
>
> so what's up with that? it seems inconsistent to describe that
> kernel-wide routine as "overkill" while a number of drivers continue
> to use it.
>
> rday
Robert,
I saw a thread about disk i/o that may relate. At least with disk
buffers in the block layer, it appeared it was an all or nothing
situation for flushing the queues. So if a upper level wanted to
ensure write A completed prior to write B, the only option was:
- write A (places data in the block queue)
- flush buffers and write all data in the block queue regardless of source
- write B (places data in the block queue)
I gathered that several of the people in the thread were surprised at
the lack of granularity, but no better solution was offered, nor even
proposed for the future.
Thus, I "assume" the calls you see in the block i/o stack are truly needed.
Greg
More information about the Kernelnewbies
mailing list