Subject: Re: [PATCH] flush_work_sync vs. flush_scheduled_work Re: [PATCH] PHYLIB: IRQ event workqueue handling fixes

From: Jarek Poplawski <[email-masked]>
Date: Mon, 22 Oct 2007 08:11:43 +0200

On Fri, Oct 19, 2007 at 09:50:14AM +0200, Jarek Poplawski wrote:
> On Thu, Oct 18, 2007 at 07:48:19PM +0400, Oleg Nesterov wrote:
> > On 10/18, Jarek Poplawski wrote:
> > >
> > > +/**
> > > + * flush_work_sync - block until a work_struct's callback has terminated
> >                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > Hmm...
> > 
> > > + * Similar to cancel_work_sync() but will only busy wait (without cancel)
> > > + * if the work is queued.
> > 
> > Yes, it won't block, but will spin in busy-wait loop until all other works
> > scheduled before this work are finished. Not good. After that it really
> > blocks waiting for this work to complete.
> > 
> > And I am a bit confused. We can't use flush_workqueue() because some of the
> > queued work_structs may take rtnl_lock, yes? But in that case we can't use
> > the new flush_work_sync() helper as well, no?

OK, I know I'm dumber and dumber everyday, but it seems in a hurry I
got it wrong again or miss something (as usual): these all flushes are
rtnl lockup vulnerable wrt. other work functions, but cancel_work_sync
looks perfectly fine... (Or am I wrong because: ...?)

Then, if by any chance I'm right, something like flush_work_sync
(or changed flush_scheduled_work, if there is no problem with such
a change of implementation) could be safely (if it's called without
locks used by flushed work only) done cancel_work_sync() way, by
running a work function after try_to_grab_pending() returns 1 (after
list_del_init - of course without respecting a queue order).

Regards,
Jarek P.