zfsonlinux/spl — pull request #74 by Prakash-Surya (2011-12-16 19:25:14+00:00)
Title: Swap taskq_ent_t with taskqid_t in taskq_thread_t

The taskq_t's active thread list is sorted based on it's
tqt_ent->tqent_id field. The list is kept sorted solely by inserting new
taskq_thread_t's in their correct sorted location; no other means are
used. This means that once inserted, if a taskq_thread_t's
tqt_ent->tqent_id field changes, the list runs the risk of no longer
being sorted.

Prior to the introduction of the taskq_dispatch_prealloc() interface,
this was not a problem as a taskq_ent_t actively being serviced under
the old interface should always have a static tqent_id field. Thus, once
the taskq_thread_t is added to the taskq_t's active thread list, the
taskq_thread_t's tqt_ent->tqent_id field would remain constant.

Now, this is no longer the case. Currently, if using the
taskq_dispatch_prealloc() interface, any given taskq_ent_t actively
being serviced _may_ have it's tqent_id value incremented. This happens
when the preallocated taskq_ent_t structure is recursively dispatched.
Thus, a taskq_thread_t could potentially have it's tqt_ent->tqent_id
field silently modified from under it's feet. If this were to happen to
a taskq_thread_t on a taskq_t's active thread list, this would
compromise the integrity of the order of the list (as the list _may_ no
longer be sorted).

To get around this, the taskq_thread_t's taskq_ent_t pointer was
replaced with it's own static copy of the tqent_id. So, as a taskq_ent_t
is pulled off of the taskq_t's pending list, a static copy of it's
tqent_id is made and this copy is used to sort the active thread list.
Using a static copy is key in ensuring the integrity of the order of the
active thread list. Even if the underlying taskq_ent_t is recursively
dispatched (as has it's tqent_id modified), this static copy stored
inside the taskq_thread_t will remain constant.

Signed-off-by: Prakash Surya
Issue #71