[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1402403359-6023-2-git-send-email-linux@rasmusvillemoes.dk>
Date: Tue, 10 Jun 2014 14:29:18 +0200
From: Rasmus Villemoes <linux@...musvillemoes.dk>
To: Linus Torvalds <torvalds@...ux-foundation.org>,
Ingo Molnar <mingo@...hat.com>,
Peter Zijlstra <peterz@...radead.org>,
Andrew Morton <akpm@...ux-foundation.org>,
Oleg Nesterov <oleg@...hat.com>,
Rik van Riel <riel@...hat.com>,
David Rientjes <rientjes@...gle.com>,
"Eric W. Biederman" <ebiederm@...ssion.com>,
Davidlohr Bueso <davidlohr@...com>,
Michal Simek <michal.simek@...inx.com>
Cc: linux-kernel@...r.kernel.org,
Rasmus Villemoes <linux@...musvillemoes.dk>
Subject: [PATCH 1/2] wait: Introduce per-task wait_queue_t
This introduces a single wait_queue_t into the task structure.
Functions which need to wait, but which do not call other functions
that might wait while on the wait queue, may use current->__wq for
bookkeeping instead of allocating an instance on the stack. To help
ensure that the users are indeed "leaf waiters", make all access
through two helper functions.
Signed-off-by: Rasmus Villemoes <linux@...musvillemoes.dk>
---
include/linux/sched.h | 23 +++++++++++++++++++++++
include/linux/wait.h | 1 +
kernel/fork.c | 1 +
3 files changed, 25 insertions(+)
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 221b2bd..c7c97fe 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1303,6 +1303,15 @@ struct task_struct {
struct list_head thread_group;
struct list_head thread_node;
+ /*
+ * "Leaf" waiters may use this instead of allocating a
+ * wait_queue_t on the stack. To help ensure exclusive use of
+ * __wq, one should use the helper functions current_wq_get(),
+ * current_wq_put() below. Leaf waiters include the
+ * wait_event_* macros.
+ */
+ wait_queue_t __wq;
+
struct completion *vfork_done; /* for vfork() */
int __user *set_child_tid; /* CLONE_CHILD_SETTID */
int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
@@ -1612,6 +1621,20 @@ struct task_struct {
#endif
};
+static inline wait_queue_t *current_wq_get(void)
+{
+ wait_queue_t *wq = ¤t->__wq;
+ BUG_ON(wq->flags != WQ_FLAG_AVAILABLE);
+ wq->flags = 0;
+ return wq;
+}
+static inline void current_wq_put(wait_queue_t *wq)
+{
+ BUG_ON(wq != ¤t->__wq);
+ wq->flags = WQ_FLAG_AVAILABLE;
+}
+
+
/* Future-safe accessor for struct task_struct's cpus_allowed. */
#define tsk_cpus_allowed(tsk) (&(tsk)->cpus_allowed)
diff --git a/include/linux/wait.h b/include/linux/wait.h
index bd68819..94279be 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -16,6 +16,7 @@ int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *ke
struct __wait_queue {
unsigned int flags;
#define WQ_FLAG_EXCLUSIVE 0x01
+#define WQ_FLAG_AVAILABLE 0x80000000U
void *private;
wait_queue_func_t func;
struct list_head task_list;
diff --git a/kernel/fork.c b/kernel/fork.c
index 54a8d26..7166955 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -1315,6 +1315,7 @@ static struct task_struct *copy_process(unsigned long clone_flags,
p->sequential_io = 0;
p->sequential_io_avg = 0;
#endif
+ p->__wq.flags = WQ_FLAG_AVAILABLE;
/* Perform scheduler related setup. Assign this task to a CPU. */
retval = sched_fork(clone_flags, p);
--
1.9.2
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists