Date: Wed, 6 Jan 2016 09:08:42 -0800 From: Alfred Perlstein <bright@mu.org> To: John Baldwin <jhb@freebsd.org>, freebsd-arch@freebsd.org Subject: Re: Expected taskqueue behavior Message-ID: <568D4A1A.5080204@mu.org> In-Reply-To: <9174153.lS3QljxB7A@ralph.baldwin.cx> References: <9174153.lS3QljxB7A@ralph.baldwin.cx>
next in thread | previous in thread | raw e-mail | index | archive | help
On 1/5/16 7:19 AM, John Baldwin wrote: > Given this bit of code: > > void > cpu_hog(void *context, int pending) > { > > for (;;) > ; > } > > static struct taskqueue *tq; > static struct task t; > > void > mod_init(void) > { > int i; > > TASK_INIT(&t, 0, cpu_hog, NULL); > tq = taskqueue_create("test", M_WAITOK, taskqueue_thread_enqueue, > &tq); > taskqueue_start_threads(&tq, mp_ncpu, PRI_MAX_IDLE, "test taskq"); > > for (i = 0; i < mp_ncpu; i++) { > taskqueue_enqueue(tq, &t); > pause("foo", 1); > } > } > > How many threads would you expect to be busy? The taskqueue(9) manpage > does not describe what happens when you queue a task that is already > executing. Currently our implementation will allow the task to execute > on a second thread (or a third, fourth, fifth, etc.). I think this > behavior is probably "surprising" as I expect most folks assume that > a task won't be executed concurrently and rely on this assumption to > avoid the need for certain types of serialization in task handlers. > > Linux workqueues explicitly document work-items as being non-reentrant. > > From https://www.kernel.org/doc/Documentation/workqueue.txt > > <quote> > Note that the flag WQ_NON_REENTRANT no longer exists as all workqueues > are now non-reentrant - any work item is guaranteed to be executed by > at most one worker system-wide at any given time. > </quote> > > Windows work queues also forbid this though indirectly becuase they > forbid extra queueing (which bumps 'pending' on FreeBSD) outright. > > From https://msdn.microsoft.com/en-us/library/windows/hardware/ff564587%28v=vs.85%29.aspx > > <quote> > Do not call IoQueueWorkItem or IoQueueWorkItemEx to queue a work item that > is already in the queue. In checked builds, this error causes a bug check. In > retail builds, the error is not detected but can cause corruption of system > data structures. > </quote> > > I think our current behavior is "surprising" and is a bug from when > taskqueue thread pools were added (the case simply wasn't handled). > > At a minimum we should document the expected behavior (and fix it if > its wrong). If we don't change our current behavior then the Linux > KPI workqueue implementation will need additional changes as it can > no longer simply call taskqueue_enqueue(). > Agreed. I had to debug numerous problems due to this in a Javascript application where the behavior was similar. -Alfred
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?568D4A1A.5080204>