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