Commit Graph

78 Commits

Author SHA1 Message Date
Andriy Gapon
73f82099ea add taskqueue_drain_all
This API has semantics similar to that of taskqueue_drain but acts on
all tasks that might be queued or running on a taskqueue.
A caller must ensure that no new tasks are being enqueued otherwise this
call would be totally meaningless.  For example, if the tasks are
enqueued by an interrupt filter then its interrupt must be disabled.

MFC after:	10 days
2013-11-28 18:56:34 +00:00
Andriy Gapon
4c47024ce0 taskqueue_cancel: garbage collect a write-only variable
MFC after:	3 days
2013-11-19 18:45:29 +00:00
Alexander Motin
18093155a3 Add comments that taskqueue_enqueue_locked() returns without the lock. 2013-10-21 21:16:50 +00:00
Gleb Smirnoff
a9355dbe82 Revert r256587.
Requested by:	zec
2013-10-18 11:26:40 +00:00
Alexander Motin
6d545f4c8d MFprojects/camlock r254763:
Move tq_enqueue() call out of the queue lock for known handlers (actually
I have found no others in the base system).  This reduces queue lock hold
time and congestion spinning under active multithreaded enqueuing.
2013-10-16 09:52:59 +00:00
Alexander Motin
1d1e92f102 MFprojects/camlock r254685:
Remove TQ_FLAGS_PENDING flag, softly duplicating queue emptiness status.
2013-10-16 09:48:23 +00:00
Gleb Smirnoff
348298b1a3 For VIMAGE kernels store vnet in the struct task, and set vnet context
during task processing.

Reported & tested by:	mm
2013-10-16 05:02:01 +00:00
Alexander Motin
596d33e923 MFprojects/camlock r254460:
Remove locking from taskqueue_member().  The list of threads is static
during the taskqueue life cycle, so there is no need to protect it,
taking quite congested lock several more times for each ZFS I/O.
2013-08-24 14:41:49 +00:00
Will Andrews
fdbc71742b Extend taskqueue(9) to enable per-taskqueue callbacks.
The scope of these callbacks is primarily to support actions that affect the
taskqueue's thread environments.  They are entirely optional, and
consequently are introduced as a new API: taskqueue_set_callback().

This interface allows the caller to specify that a taskqueue requires a
callback and optional context pointer for a given callback type.

The callback types included in this commit can be used to register a
constructor and destructor for thread-local storage using osd(9).  This
allows a particular taskqueue to define that its threads require a specific
type of TLS, without the need for a specially-orchestrated task-based
mechanism for startup and shutdown in order to accomplish it.

Two callback types are supported at this point:

- TASKQUEUE_CALLBACK_TYPE_INIT, called by every thread when it starts, prior
  to processing any tasks.
- TASKQUEUE_CALLBACK_TYPE_SHUTDOWN, called by every thread when it exits,
  after it has processed its last task but before the taskqueue is
  reclaimed.

While I'm here:

- Add two new macros, TQ_ASSERT_LOCKED and TQ_ASSERT_UNLOCKED, and use them
  in appropriate locations.
- Fix taskqueue.9 to mention taskqueue_start_threads(), which is a required
  interface for all consumers of taskqueue(9).

Reviewed by:	kib (all), eadler (taskqueue.9), brd (taskqueue.9)
Approved by:	ken (mentor)
Sponsored by:	Spectra Logic
MFC after:	1 month
2013-03-23 15:11:53 +00:00
Konstantin Belousov
b7c8d2f2f5 Add a special meaning to the negative ticks argument for
taskqueue_enqueue_timeout().  Do not rearm the callout if it is
already armed and the ticks is negative.  Otherwise rearm it to fire
in abs(ticks) ticks in the future.

The intended use is to call taskqueue_enqueue_timeout() for the given
timeout_task with the same negative ticks argument.  As result, the
task is scheduled to execute not further than abs(ticks) ticks in
future, and the consequent enqueues are coalesced until the already
scheduled task is finished.

Reviewed by:	rwatson
Tested by:	Markus Gebert <markus.gebert@hostpoint.ch>
MFC after:	2 weeks
2012-11-20 15:33:48 +00:00
John Baldwin
10f0ab3933 Shorten the name of the fast SWI taskqueue to "fast taskq" so that
it fits.

Reported by:	lev
MFC after:	1 week
2012-08-28 13:35:37 +00:00
Adrian Chadd
d2849f27bc Ensure that ta_pending doesn't overflow u_short by capping its value at USHRT_MAX.
If it overflows before the taskqueue can run, the task will be
re-added to the taskqueue and cause a loop in the task list.

Reported by:	Arnaud Lacombe <lacombar@gmail.com>
Submitted by:	Ryan Stone <rysto32@gmail.com>
Reviewed by:	jhb
Approved by:	re (kib)
MFC after:	1 day
2011-09-15 08:42:06 +00:00
Konstantin Belousov
b2ad91f26b Implement the delayed task execution extension to the taskqueue
mechanism. The caller may specify a timeout in ticks after which the
task will be scheduled.

Sponsored by:	The FreeBSD Foundation
Reviewed by:	jeff, jhb
MFC after:	1 month
2011-04-26 11:39:56 +00:00
Andriy Gapon
706b0d31bb taskqueue: drop unused tq_name field
tq_name was used write-only and besides it was just a pointer, so it
could point to some garbage in a temporary buffer that's gone.
This change shouldn't change KPI/KBI as struct taskqueue is private to
subr_taskqueue.c.
If we find a need for tq_name it can be resurrected at any moment.
taskqueue_create() interface is preserved for this purpose.

Suggested by:	jhb
MFC after:	10 days
2010-11-23 14:30:22 +00:00
Juli Mallett
b79b28b69d Use macros rather than inline functions to lock and unlock mutexes, so that
line number information is preserved in witness.

Reviewed by:	jhb
2010-11-08 22:12:25 +00:00
Matthew D Fleming
f46276a9b0 Add a taskqueue_cancel(9) to cancel a pending task without waiting for
it to run as taskqueue_drain(9) does.

Requested by:	hselasky
Original code:	jeff
Reviewed by:	jhb
MFC after:	2 weeks
2010-11-08 20:56:31 +00:00
Matthew D Fleming
bf73d4d28e Use a safer mechanism for determining if a task is currently running,
that does not rely on the lifetime of pointers being the same. This also
restores the task KBI.

Suggested by:	jhb
MFC after:	1 month
2010-10-13 22:59:04 +00:00
Matthew D Fleming
a92f0ee866 Re-expose and briefly document taskqueue_run(9). The function is used
in at least one 3rd party driver.

Requested by:	jhb
2010-10-12 18:36:03 +00:00
Pawel Jakub Dawidek
646c3b21ae Run all tasks from a proper context, with proper priority, etc.
Reviewed by:	jhb
MFC after:	1 month
2010-08-28 08:38:03 +00:00
Pawel Jakub Dawidek
3d336cd03b Simplify taskqueue_drain() by using proved macros. 2010-08-13 19:20:35 +00:00
Matthew D Fleming
033459c8f1 Remove unused variable that snuck in during development.
Approved by:    zml (mentor)
2010-07-22 17:23:43 +00:00
Matthew D Fleming
242ed5d96c Fix taskqueue_drain(9) to not have false negatives. For threaded
taskqueues, more than one task can be running simultaneously.

Also make taskqueue_run(9) static to the file, since there are no
consumers in the base kernel and the function signature needs to change
with this fix.

Remove mention of taskqueue_run(9) and taskqueue_run_fast(9) from the
taskqueue(9) man page.

Reviewed by:    jhb
Approved by:    zml (mentor)
2010-07-22 16:41:09 +00:00
Andriy Gapon
1bdfff2252 fix a few cases where a string is passed via format argument instead of
via %s

Most of the cases looked harmless, but this is done for the sake of
correctness.  In one case it even allowed to drop an intermediate buffer.

Found by:	clang
MFC after:	2 week
2010-06-11 19:27:21 +00:00
Zachary Loafman
121e802b07 Revert taskqueue(9) related commits until mdf@ is approved and can
resolve issues.

This reverts commits r207439, r208623, r208624
2010-06-01 16:04:01 +00:00
Zachary Loafman
911de7741d Avoid a wakeup(9) if we can be sure no one is waiting on the task.
Submitted by:       Matthew Fleming <matthew.fleming@isilon.com>
Reviewed by:        zml, jhb
2010-05-28 18:15:34 +00:00
Zachary Loafman
6e86cdb85c Revert r207439 and solve the problem differently. The task handler
ta_func may free the task structure, so no references to its members
are valid after the handler has been called. Using a per-queue member
and having waits longer than strictly necessary was suggested by jhb.

Submitted by:       Matthew Fleming <matthew.fleming@isilon.com>
Reviewed by:        zml, jhb
2010-05-28 18:15:28 +00:00
Zachary Loafman
1dac222419 Handle taskqueue_drain(9) correctly on a threaded taskqueue:
taskqueue_drain(9) will not correctly detect whether a task is
currently running.  The check is against a field in the taskqueue
struct, but for a threaded queue with more than one thread, multiple
threads can simultaneously be running a task, thus stomping over the
tq_running field.

Submitted by:       Matthew Fleming <matthew.fleming@isilon.com>
Reviewed by:        jhb
Approved by:        dfr (mentor)
2010-04-30 16:29:05 +00:00
John Baldwin
5ca4819ddf - Fix several off-by-one errors when using MAXCOMLEN. The p_comm[] and
td_name[] arrays are actually MAXCOMLEN + 1 in size and a few places that
  created shadow copies of these arrays were just using MAXCOMLEN.
- Prefer using sizeof() of an array type to explicit constants for the
  array length in a few places.
- Ensure that all of p_comm[] and td_name[] is always zero'd during
  execve() to guard against any possible information leaks.  Previously
  trailing garbage in p_comm[] could be leaked to userland in ktrace
  record headers via td_name[].

Reviewed by:	bde
2009-10-23 15:14:54 +00:00
Pawel Jakub Dawidek
e477e4fe8e Remove unused taskqueue_find() function.
Reviewed by:	dfr
Approved by:	re (kib)
2009-08-18 13:55:48 +00:00
Pawel Jakub Dawidek
159ef108e1 Remove OpenSolaris taskq port (it performs very poorly in our kernel) and
replace it with wrappers around our taskqueue(9).
To make it possible implement taskqueue_member() function which returns 1
if the given thread was created by the given taskqueue.

Approved by:	re (kib)
2009-08-17 09:01:20 +00:00
Pawel Jakub Dawidek
6a3b289388 Because taskqueue_run() can drop tq_mutex, we need to check if the
TQ_FLAGS_ACTIVE flag wasn't removed in the meantime, which means we missed a
wakeup.

Approved by:	re (kib)
2009-08-17 08:42:34 +00:00
Andrew Thompson
a1797ef6c8 Remove semicolon left in the last commit
Spotted by:	csjp
2009-02-13 18:51:39 +00:00
Andrew Thompson
24ef070126 Check the exit flag at the start of the taskqueue loop rather than the end. It
is possible to tear down the taskqueue before the thread has run and the
taskqueue loop would sleep forever.

Reviewed by:	sam
MFC after:	1 week
2009-02-13 01:16:51 +00:00
Warner Losh
d710cae75a Use NULL in preference to 0 for pointers. 2009-02-03 07:51:41 +00:00
Kip Macy
694382c8eb revert local change 2008-07-18 07:10:33 +00:00
Kip Macy
4af83c8cff import vendor fixes to cxgb 2008-07-18 06:12:31 +00:00
John Baldwin
03c7442d75 Use kthread_exit() to terminate a taskqueue thread rather than kproc_exit()
now that the taskqueue threads are kthreads rather than kprocs.

Reported by:	kris
2008-04-11 17:35:54 +00:00
Sam Leffler
175611b668 change taskqueue_start_threads to create threads instead of proc's
Reviewed by:	jhb
2008-04-08 17:48:02 +00:00
Scott Long
478cfc7300 Implement taskqueue_block() and taskqueue_unblock(). These functions allow
the owner of a queue to block and unblock execution of the tasks in the
queue while allowing tasks to continue to be added queue.  Combining this
with taskqueue_drain() allows a queue to be safely disabled.  The unblock
function may run (or schedule to run) the queue when it is called, just as
calling taskqueue_enqueue() would.

Reviewed by: jhb, sam
2008-03-25 22:38:45 +00:00
Julian Elischer
3745c395ec Rename the kthread_xxx (e.g. kthread_create()) calls
to kproc_xxx as they actually make whole processes.
Thos makes way for us to add REAL kthread_create() and friends
that actually make theads. it turns out that most of these
calls actually end up being moved back to the thread version
when it's added. but we need to make this cosmetic change first.

I'd LOVE to do this rename in 7.0  so that we can eventually MFC the
new kthread_xxx() calls.
2007-10-20 23:23:23 +00:00
Jeff Roberson
982d11f836 Commit 14/14 of sched_lock decomposition.
- Use thread_lock() rather than sched_lock for per-thread scheduling
   sychronization.
 - Use the per-process spinlock rather than the sched_lock for per-process
   scheduling synchronization.

Tested by:      kris, current@
Tested on:      i386, amd64, ULE, 4BSD, libthr, libkse, PREEMPTION, etc.
Discussed with: kris, attilio, kmacy, jhb, julian, bde (small parts each)
2007-06-05 00:00:57 +00:00
Jeff Roberson
f0393f063a - Remove setrunqueue and replace it with direct calls to sched_add().
setrunqueue() was mostly empty.  The few asserts and thread state
   setting were moved to the individual schedulers.  sched_add() was
   chosen to displace it for naming consistency reasons.
 - Remove adjustrunqueue, it was 4 lines of code that was ifdef'd to be
   different on all three schedulers where it was only called in one place
   each.
 - Remove the long ifdef'd out remrunqueue code.
 - Remove the now redundant ts_state.  Inspect the thread state directly.
 - Don't set TSF_* flags from kern_switch.c, we were only doing this to
   support a feature in one scheduler.
 - Change sched_choose() to return a thread rather than a td_sched.  Also,
   rely on the schedulers to return the idlethread.  This simplifies the
   logic in choosethread().  Aside from the run queue links kern_switch.c
   mostly does not care about the contents of td_sched.

Discussed with:	julian

 - Move the idle thread loop into the per scheduler area.  ULE wants to
   do something different from the other schedulers.

Suggested by:	jhb

Tested on:	x86/amd64 sched_{4BSD, ULE, CORE}.
2007-01-23 08:46:51 +00:00
Sam Leffler
75b773ae3d When starting up threads in taskqueue_start_threads create them
stopped before adjusting their priority and setting them on the run
q so they cannot race for resources (pointed out by njl).

While here add a console printf on thread create fails; otherwise
noone may notice (e.g. return value is always 0 and caller has no
way to verify).

Reviewed by:	jhb, scottl
MFC after:	2 weeks
2006-05-24 22:11:07 +00:00
John Baldwin
0f180a7cce Change msleep() and tsleep() to not alter the calling thread's priority
if the specified priority is zero.  This avoids a race where the calling
thread could read a snapshot of it's current priority, then a different
thread could change the first thread's priority, then the original thread
would call sched_prio() inside msleep() undoing the change made by the
second thread.  I used a priority of zero as no thread that calls msleep()
or tsleep() should be specifying a priority of zero anyway.

The various places that passed 'curthread->td_priority' or some variant
as the priority now pass 0.
2006-04-17 18:20:38 +00:00
Sam Leffler
00537061dd fixup error handling in taskqueue_start_threads: check for kthread_create
failing, print a message when we fail for some reason as most callers do
not check the return value (e.g. 'cuz they're called from SYSINIT)

Reviewed by:	scottl
MFC after:	1 week
2006-03-30 23:06:59 +00:00
Scott Long
0f92108d32 Add the following to the taskqueue api:
taskqueue_start_threads(struct taskqueue **, int count, int pri,
			const char *name, ...);

This allows the creation of 1 or more threads that will service a single
taskqueue.  Also rework the taskqueue_create() API to remove the API change
that was introduced a while back.  Creating a taskqueue doesn't rely on
the presence of a process structure, and the proc mechanics are much better
encapsulated in taskqueue_start_threads().  Also clean up the
taskqueue_terminate() and taskqueue_free() functions to safely drain
pending tasks and remove all associated threads.

The TASKQUEUE_DEFINE and TASKQUEUE_DEFINE_THREAD macros have been changed
to use the new API, but drivers compiled against the old definitions will
still work.  Thus, recompiling drivers is not a strict requirement.
2006-01-14 01:55:24 +00:00
Scott Long
1c3a3b0bd0 The interlock in taskqueue_terminate() is completely wrong for taskqueues
that use spinlocks.  Remove it for now.
2006-01-11 00:37:13 +00:00
Scott Long
9df1a6dd61 Add functions and macros and refactor code to make it easier to manage
fast taskqueues.  The following have been added:

TASKQUEUE_FAST_DEFINE() - create a global task queue.
    an arbitrary execution context.
TASKQUEUE_FAST_DEFINE_THREAD() - create a global taskqueue that uses a
    dedicated kthread.
taskqueue_create_fast() - create a local/private taskqueue.

These are all complimentary of the standard taskqueue functions.  They are
primarily useful for fast interrupt handlers that can only use spinlock for
synchronization.

I personally think that the taskqueue API is starting to get too narrow and
hairy, but fixing it will require a major redesign on the API.  Such a
redesign would be good but would break compatibility with FreeBSD 6.x, so
it really isn't desirable at this time.

Submitted by: sam
2006-01-10 06:31:12 +00:00
Scott Long
d2a401cb70 Create the taskqueue_fast handler with INTR_MPSAFE so that it doesn't run
with Giant.

MFC After: 3 days
2005-12-23 06:18:33 +00:00
John Baldwin
6caf758e7c Use shorter names for the Giant and fast taskqueues so that their names
actually fit.
2005-10-25 19:29:02 +00:00