From: Jens Axboe <jens.axboe@oracle.com>
To: Frederic Weisbecker <fweisbec@gmail.com>
Cc: linux-kernel@vger.kernel.org, jeff@garzik.org,
benh@kernel.crashing.org, htejun@gmail.com, bzolnier@gmail.com,
alan@lxorguk.ukuu.org.uk
Subject: Re: [PATCH 2/6] workqueue: add support for lazy workqueues
Date: Thu, 20 Aug 2009 14:10:12 +0200 [thread overview]
Message-ID: <20090820121012.GK12579@kernel.dk> (raw)
In-Reply-To: <20090820120124.GB6069@nowhere>
On Thu, Aug 20 2009, Frederic Weisbecker wrote:
> On Thu, Aug 20, 2009 at 12:20:00PM +0200, Jens Axboe wrote:
> > Lazy workqueues are like normal workqueues, except they don't
> > start a thread per CPU by default. Instead threads are started
> > when they are needed, and exit when they have been idle for
> > some time.
> >
> > Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
> > ---
> > include/linux/workqueue.h | 5 ++
> > kernel/workqueue.c | 152 ++++++++++++++++++++++++++++++++++++++++++---
> > 2 files changed, 147 insertions(+), 10 deletions(-)
> >
> > diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
> > index f14e20e..b2dd267 100644
> > --- a/include/linux/workqueue.h
> > +++ b/include/linux/workqueue.h
> > @@ -32,6 +32,7 @@ struct work_struct {
> > #ifdef CONFIG_LOCKDEP
> > struct lockdep_map lockdep_map;
> > #endif
> > + unsigned int cpu;
> > };
> >
> > #define WORK_DATA_INIT() ATOMIC_LONG_INIT(0)
> > @@ -172,6 +173,7 @@ enum {
> > WQ_F_SINGLETHREAD = 1,
> > WQ_F_FREEZABLE = 2,
> > WQ_F_RT = 4,
> > + WQ_F_LAZY = 8,
> > };
> >
> > #ifdef CONFIG_LOCKDEP
> > @@ -198,6 +200,7 @@ enum {
> > __create_workqueue((name), WQ_F_SINGLETHREAD | WQ_F_FREEZABLE)
> > #define create_singlethread_workqueue(name) \
> > __create_workqueue((name), WQ_F_SINGLETHREAD)
> > +#define create_lazy_workqueue(name) __create_workqueue((name), WQ_F_LAZY)
> >
> > extern void destroy_workqueue(struct workqueue_struct *wq);
> >
> > @@ -211,6 +214,8 @@ extern int queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
> >
> > extern void flush_workqueue(struct workqueue_struct *wq);
> > extern void flush_scheduled_work(void);
> > +extern void workqueue_set_lazy_timeout(struct workqueue_struct *wq,
> > + unsigned long timeout);
> >
> > extern int schedule_work(struct work_struct *work);
> > extern int schedule_work_on(int cpu, struct work_struct *work);
> > diff --git a/kernel/workqueue.c b/kernel/workqueue.c
> > index 02ba7c9..d9ccebc 100644
> > --- a/kernel/workqueue.c
> > +++ b/kernel/workqueue.c
> > @@ -61,11 +61,17 @@ struct workqueue_struct {
> > struct list_head list;
> > const char *name;
> > unsigned int flags; /* WQ_F_* flags */
> > + unsigned long lazy_timeout;
> > + unsigned int core_cpu;
> > #ifdef CONFIG_LOCKDEP
> > struct lockdep_map lockdep_map;
> > #endif
> > };
> >
> > +/* Default lazy workqueue timeout */
> > +#define WQ_DEF_LAZY_TIMEOUT (60 * HZ)
> > +
> > +
> > /* Serializes the accesses to the list of workqueues. */
> > static DEFINE_SPINLOCK(workqueue_lock);
> > static LIST_HEAD(workqueues);
> > @@ -81,6 +87,8 @@ static const struct cpumask *cpu_singlethread_map __read_mostly;
> > */
> > static cpumask_var_t cpu_populated_map __read_mostly;
> >
> > +static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu);
> > +
> > /* If it's single threaded, it isn't in the list of workqueues. */
> > static inline bool is_wq_single_threaded(struct workqueue_struct *wq)
> > {
> > @@ -141,11 +149,29 @@ static void insert_work(struct cpu_workqueue_struct *cwq,
> > static void __queue_work(struct cpu_workqueue_struct *cwq,
> > struct work_struct *work)
> > {
> > + struct workqueue_struct *wq = cwq->wq;
> > unsigned long flags;
> >
> > - spin_lock_irqsave(&cwq->lock, flags);
> > - insert_work(cwq, work, &cwq->worklist);
> > - spin_unlock_irqrestore(&cwq->lock, flags);
> > + /*
> > + * This is a lazy workqueue and this particular CPU thread has
> > + * exited. We can't create it from here, so add this work on our
> > + * static thread. It will create this thread and move the work there.
> > + */
> > + if ((wq->flags & WQ_F_LAZY) && !cwq->thread) {
>
>
>
> Isn't this part racy? If a work has just been queued but the thread
> hasn't had yet enough time to start until we get there...?
Sure it is, see my initial description about holes and races :-)
Thread re-recreation and such need to ensure that one and only one gets
set up, of course. I just didn't want to spend a lot of time making it
air tight in case people had big complaints that means I have to rewrite
bits of it.
--
Jens Axboe
next prev parent reply other threads:[~2009-08-20 12:10 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-08-20 10:19 [PATCH 0/6] Lazy workqueues Jens Axboe
2009-08-20 10:19 ` [PATCH 1/6] workqueue: replace singlethread/freezable/rt parameters and variables with flags Jens Axboe
2009-08-20 10:20 ` [PATCH 2/6] workqueue: add support for lazy workqueues Jens Axboe
2009-08-20 12:01 ` Frederic Weisbecker
2009-08-20 12:10 ` Jens Axboe [this message]
2009-08-20 10:20 ` [PATCH 3/6] crypto: use " Jens Axboe
2009-08-20 10:20 ` [PATCH 4/6] libata: use lazy workqueues for the pio task Jens Axboe
2009-08-20 12:40 ` Stefan Richter
2009-08-20 12:48 ` Jens Axboe
2009-08-20 10:20 ` [PATCH 5/6] aio: use lazy workqueues Jens Axboe
2009-08-20 15:09 ` Jeff Moyer
2009-08-21 18:31 ` Zach Brown
2009-08-20 10:20 ` [PATCH 6/6] sunrpc: " Jens Axboe
2009-08-20 12:04 ` [PATCH 0/6] Lazy workqueues Peter Zijlstra
2009-08-20 12:08 ` Jens Axboe
2009-08-20 12:16 ` Peter Zijlstra
2009-08-23 2:42 ` Junio C Hamano
2009-08-24 7:04 ` git send-email defaults Peter Zijlstra
2009-08-24 8:04 ` [PATCH 0/6] Lazy workqueues Jens Axboe
2009-08-24 9:03 ` Junio C Hamano
2009-08-24 9:11 ` Peter Zijlstra
2009-08-20 12:22 ` Frederic Weisbecker
2009-08-20 12:41 ` Jens Axboe
2009-08-20 13:04 ` Tejun Heo
2009-08-20 12:59 ` Steven Whitehouse
2009-08-20 12:55 ` Tejun Heo
2009-08-21 6:58 ` Jens Axboe
-- strict thread matches above, loose matches on Subject: below --
2009-08-20 10:17 Jens Axboe
2009-08-20 10:17 ` [PATCH 1/4] direct-io: unify argument passing by adding a dio_args structure Jens Axboe
2009-08-20 10:17 ` [PATCH 1/6] workqueue: replace singlethread/freezable/rt parameters and variables with flags Jens Axboe
2009-08-20 10:17 ` [PATCH 2/4] direct-io: make O_DIRECT IO path be page based Jens Axboe
2009-08-20 10:17 ` [PATCH 2/6] workqueue: add support for lazy workqueues Jens Axboe
2009-08-21 0:20 ` Andrew Morton
2009-08-24 8:06 ` Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20090820121012.GK12579@kernel.dk \
--to=jens.axboe@oracle.com \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=benh@kernel.crashing.org \
--cc=bzolnier@gmail.com \
--cc=fweisbec@gmail.com \
--cc=htejun@gmail.com \
--cc=jeff@garzik.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.