From: Xiaotian Feng <xtfeng@gmail.com>
To: Changli Gao <xiaosuo@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Andrew Morton <akpm@linux-foundation.org>,
"Eric W. Biederman" <ebiederm@xmission.com>,
Davide Libenzi <davidel@xmailserver.org>,
Roland Dreier <rolandd@cisco.com>,
Stefan Richter <stefanr@s5r6.in-berlin.de>,
Peter Zijlstra <a.p.zijlstra@chello.nl>,
"David S. Miller" <davem@davemloft.net>,
Eric Dumazet <dada1@cosmosbay.com>,
Christoph Lameter <cl@linux.com>,
Andreas Herrmann <andreas.herrmann3@amd.com>,
Thomas Gleixner <tglx@linutronix.de>,
David Howells <dhowells@redhat.com>, Takashi Iwai <tiwai@suse.de>,
linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC] sched: implement the exclusive wait queue as a LIFO queue
Date: Wed, 28 Apr 2010 15:47:54 +0800 [thread overview]
Message-ID: <u2w7b6bb4a51004280047s8748cbfbi7ed8e2a238121fa9@mail.gmail.com> (raw)
In-Reply-To: <1272430986-20436-1-git-send-email-xiaosuo@gmail.com>
On Wed, Apr 28, 2010 at 1:03 PM, Changli Gao <xiaosuo@gmail.com> wrote:
> implement the exclusive wait queue as a LIFO queue
>
> If the exclusive wait queue is also a LIFO queue as the normal wait queue, the
> process who goes to sleep recently, will be woke up first. As its memory is
> more likely in cache, we will get better performance. And when there are many
> processes waiting on a exclusive wait queue, some of them may not be woke up,
> if the others can handle the workload, and it will reduce the load of
> the scheduler.
>
Starve some processes for performance?
> Note: before applying this patch, you need my previous patch patched first.
> https://patchwork.kernel.org/patch/95600/
>
> Signed-off-by: Changli Gao <xiaosuo@gmail.com>
> ----
> fs/eventpoll.c | 3 +--
> include/linux/wait.h | 17 +++++++----------
> kernel/sched.c | 8 ++++----
> kernel/wait.c | 9 +++------
> 4 files changed, 15 insertions(+), 22 deletions(-)
> diff --git a/fs/eventpoll.c b/fs/eventpoll.c
> index bd056a5..e9b3ebe 100644
> --- a/fs/eventpoll.c
> +++ b/fs/eventpoll.c
> @@ -1140,8 +1140,7 @@ retry:
> * ep_poll_callback() when events will become available.
> */
> init_waitqueue_entry(&wait, current);
> - wait.flags |= WQ_FLAG_EXCLUSIVE;
> - __add_wait_queue(&ep->wq, &wait);
> + __add_wait_queue_ex(&ep->wq, &wait);
>
> for (;;) {
> /*
> diff --git a/include/linux/wait.h b/include/linux/wait.h
> index a48e16b..95c127d 100644
> --- a/include/linux/wait.h
> +++ b/include/linux/wait.h
> @@ -30,8 +30,6 @@ typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, v
> int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key);
>
> struct __wait_queue {
> - unsigned int flags;
> -#define WQ_FLAG_EXCLUSIVE 0x01
> void *private;
> wait_queue_func_t func;
> struct list_head task_list;
> @@ -50,6 +48,7 @@ struct wait_bit_queue {
> struct __wait_queue_head {
> spinlock_t lock;
> struct list_head task_list;
> + struct list_head task_list_ex;
> };
> typedef struct __wait_queue_head wait_queue_head_t;
>
> @@ -69,7 +68,8 @@ struct task_struct;
>
> #define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \
> .lock = __SPIN_LOCK_UNLOCKED(name.lock), \
> - .task_list = { &(name).task_list, &(name).task_list } }
> + .task_list = { &(name).task_list, &(name).task_list }, \
> + .task_list_ex = { &(name).task_list_ex, &(name).task_list_ex } }
>
> #define DECLARE_WAIT_QUEUE_HEAD(name) \
> wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
> @@ -97,7 +97,6 @@ extern void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *)
>
> static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
> {
> - q->flags = 0;
> q->private = p;
> q->func = default_wake_function;
> }
> @@ -105,14 +104,13 @@ static inline void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p)
> static inline void init_waitqueue_func_entry(wait_queue_t *q,
> wait_queue_func_t func)
> {
> - q->flags = 0;
> q->private = NULL;
> q->func = func;
> }
>
> static inline int waitqueue_active(wait_queue_head_t *q)
> {
> - return !list_empty(&q->task_list);
> + return !list_empty(&q->task_list) || !list_empty(&q->task_list);
> }
>
> extern void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait);
> @@ -127,10 +125,10 @@ static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
> /*
> * Used for wake-one threads:
> */
> -static inline void __add_wait_queue_tail(wait_queue_head_t *head,
> +static inline void __add_wait_queue_ex(wait_queue_head_t *head,
> wait_queue_t *new)
> {
> - list_add_tail(&new->task_list, &head->task_list);
> + list_add(&new->task_list, &head->task_list_ex);
> }
>
> static inline void __remove_wait_queue(wait_queue_head_t *head,
> @@ -409,8 +407,7 @@ do { \
> static inline void add_wait_queue_exclusive_locked(wait_queue_head_t *q,
> wait_queue_t * wait)
> {
> - wait->flags |= WQ_FLAG_EXCLUSIVE;
> - __add_wait_queue_tail(q, wait);
> + __add_wait_queue_ex(q, wait);
> }
>
> /*
> diff --git a/kernel/sched.c b/kernel/sched.c
> index be5ab70..59b1534 100644
> --- a/kernel/sched.c
> +++ b/kernel/sched.c
> @@ -3903,11 +3903,11 @@ static void __wake_up_common(wait_queue_head_t *q, unsigned int mode,
> {
> wait_queue_t *curr, *next;
>
> - list_for_each_entry_safe(curr, next, &q->task_list, task_list) {
> - unsigned flags = curr->flags;
> + list_for_each_entry_safe(curr, next, &q->task_list, task_list)
> + curr->func(curr, mode, wake_flags, key);
>
> - if (curr->func(curr, mode, wake_flags, key) &&
> - (flags & WQ_FLAG_EXCLUSIVE) && !--nr_exclusive)
> + list_for_each_entry_safe(curr, next, &q->task_list_ex, task_list) {
> + if (curr->func(curr, mode, wake_flags, key) && !--nr_exclusive)
> break;
> }
> }
> diff --git a/kernel/wait.c b/kernel/wait.c
> index c4bd3d8..a0559df 100644
> --- a/kernel/wait.c
> +++ b/kernel/wait.c
> @@ -15,6 +15,7 @@ void __init_waitqueue_head(wait_queue_head_t *q, struct lock_class_key *key)
> spin_lock_init(&q->lock);
> lockdep_set_class(&q->lock, key);
> INIT_LIST_HEAD(&q->task_list);
> + INIT_LIST_HEAD(&q->task_list_ex);
> }
>
> EXPORT_SYMBOL(__init_waitqueue_head);
> @@ -23,7 +24,6 @@ void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
> {
> unsigned long flags;
>
> - wait->flags &= ~WQ_FLAG_EXCLUSIVE;
> spin_lock_irqsave(&q->lock, flags);
> __add_wait_queue(q, wait);
> spin_unlock_irqrestore(&q->lock, flags);
> @@ -34,9 +34,8 @@ void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait)
> {
> unsigned long flags;
>
> - wait->flags |= WQ_FLAG_EXCLUSIVE;
> spin_lock_irqsave(&q->lock, flags);
> - __add_wait_queue_tail(q, wait);
> + __add_wait_queue_ex(q, wait);
> spin_unlock_irqrestore(&q->lock, flags);
> }
> EXPORT_SYMBOL(add_wait_queue_exclusive);
> @@ -69,7 +68,6 @@ prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
> {
> unsigned long flags;
>
> - wait->flags &= ~WQ_FLAG_EXCLUSIVE;
> spin_lock_irqsave(&q->lock, flags);
> if (list_empty(&wait->task_list))
> __add_wait_queue(q, wait);
> @@ -83,10 +81,9 @@ prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)
> {
> unsigned long flags;
>
> - wait->flags |= WQ_FLAG_EXCLUSIVE;
> spin_lock_irqsave(&q->lock, flags);
> if (list_empty(&wait->task_list))
> - __add_wait_queue_tail(q, wait);
> + __add_wait_queue_ex(q, wait);
> set_current_state(state);
> spin_unlock_irqrestore(&q->lock, flags);
> }
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2010-04-28 7:47 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-04-28 5:03 [RFC] sched: implement the exclusive wait queue as a LIFO queue Changli Gao
2010-04-28 6:22 ` Changli Gao
2010-04-28 8:05 ` Changli Gao
2010-04-28 7:47 ` Xiaotian Feng [this message]
2010-04-28 7:52 ` Changli Gao
2010-04-28 8:15 ` Yong Zhang
2010-04-28 8:23 ` Changli Gao
2010-04-28 9:25 ` Johannes Weiner
2010-04-28 9:29 ` David Howells
2010-04-28 11:17 ` Changli Gao
2010-04-28 13:21 ` Jamie Lokier
2010-04-28 13:42 ` Changli Gao
2010-04-28 15:25 ` Jamie Lokier
2010-04-28 15:49 ` Changli Gao
2010-04-28 18:57 ` Davide Libenzi
2010-04-28 13:21 ` David Howells
2010-04-28 9:32 ` David Howells
2010-04-28 13:56 ` Changli Gao
2010-04-28 14:06 ` David Howells
2010-04-28 14:53 ` Changli Gao
2010-04-28 15:00 ` David Howells
2010-04-28 15:33 ` Changli Gao
2010-04-28 9:34 ` David Howells
2010-04-28 13:47 ` Changli Gao
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=u2w7b6bb4a51004280047s8748cbfbi7ed8e2a238121fa9@mail.gmail.com \
--to=xtfeng@gmail.com \
--cc=a.p.zijlstra@chello.nl \
--cc=akpm@linux-foundation.org \
--cc=andreas.herrmann3@amd.com \
--cc=cl@linux.com \
--cc=dada1@cosmosbay.com \
--cc=davem@davemloft.net \
--cc=davidel@xmailserver.org \
--cc=dhowells@redhat.com \
--cc=ebiederm@xmission.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rolandd@cisco.com \
--cc=stefanr@s5r6.in-berlin.de \
--cc=tglx@linutronix.de \
--cc=tiwai@suse.de \
--cc=viro@zeniv.linux.org.uk \
--cc=xiaosuo@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).