On Tue, May 5, 2015 at 10:58 AM, Dan McDonald <[email protected]> wrote:

>
> > On May 5, 2015, at 1:51 PM, Matthew Ahrens <[email protected]> wrote:
> >
> > I take this to mean taskq callbacks should not call taskq_dispatch()?
> What is your concern here and do you have a suggestion of how to implement
> what Arne is trying to do?  I could see creating our own queue of things to
> do, but if managed similarly (adding things to the queue from the cb) I'm
> not sure how it's substantively different.
>
>
> From the man page:
>
>        The ddi_taskq_destroy() function waits for any scheduled tasks to
>        complete, then destroys the taskq. The caller should guarantee that
> no
>        new tasks are scheduled for the closing taskq.
>
>        The ddi_taskq_wait() function waits for all previously scheduled
> tasks
>        to complete. Note that this function does not stop any new task
>        dispatches.
>
> So it appears neither call has safety for new tasks being added to the
> queue.
>
> Consider this simple tree:
>
>                         a
>                      |     |
>                     b     c
>                  |    |   |  |
>                  d  e  f  g
>
> So we enter and schedule 'a', which completes after scheduling 'b' and
> 'c'.  'a' returns, and we taskq_wait().  Tasks 'b' and 'c' will SCHEDULE
> 'd' through 'g', but then return, and if I understand the man page,
> taskq_wait() will return once 'b' and 'c'  (and ONLY 'b' and 'c' as
> "previously scheduled tasks") are done.
>
> If the man page is wrong, and that taskq_wait() will wait until the whole
> damned taskq is EMPTY, even if existing tasks add new ones, than my
> objection is moot, modulo perhaps a man page bug to explain this more
> clearly.
>

The manpage is wrong (or at least, incompletely describes the behavior).
Here's the source:

/*
 * Wait for all pending tasks to complete.
 * Calling taskq_wait from a task will cause deadlock.
 */
void
taskq_wait(taskq_t *tq)
....
  while (tq->tq_task.tqent_next != &tq->tq_task || tq->tq_active != 0)
cv_wait(&tq->tq_wait_cv, &tq->tq_lock);

The check for tq_active is what makes this usage possible (dispatch from a
callback, taskq_wait() waits until the entire queue is drained).

--matt

Dan
>
>
>
> -------------------------------------------
> illumos-zfs
> Archives: https://www.listbox.com/member/archive/182191/=now
> RSS Feed:
> https://www.listbox.com/member/archive/rss/182191/21635000-ebd1d460
> Modify Your Subscription:
> https://www.listbox.com/member/?member_id=21635000&id_secret=21635000-73dc201a
> Powered by Listbox: http://www.listbox.com
>
_______________________________________________
developer mailing list
[email protected]
http://lists.open-zfs.org/mailman/listinfo/developer

Reply via email to