Thread (3 messages) 3 messages, 2 authors, 2012-10-19

if flush_scheduled_work() is allegedly overkill, why do drivers use it?

From: Greg Freemyer <hidden>
Date: 2012-10-19 15:06:08

On Fri, Oct 19, 2012 at 10:12 AM, Robert P. J. Day
[off-list ref] 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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help