1 From ab3b7df5658a5fdaa17d183eeab4acfe26f2f935 Mon Sep 17 00:00:00 2001
2 From: Peter Zijlstra <peterz@infradead.org>
3 Date: Wed, 14 Sep 2011 11:57:04 +0200
4 Subject: [PATCH 205/366] ipc/sem: Rework semaphore wakeups
6 Current sysv sems have a weird ass wakeup scheme that involves keeping
7 preemption disabled over a potential O(n^2) loop and busy waiting on
10 Kill this and simply wake the task directly from under the sem_lock.
12 This was discovered by a migrate_disable() debug feature that
20 Cc: Manfred Spraul <manfred@colorfullife.com>
21 Suggested-by: Thomas Gleixner <tglx@linutronix.de>
22 Reported-by: Mike Galbraith <efault@gmx.de>
23 Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
24 Cc: Manfred Spraul <manfred@colorfullife.com>
25 Link: http://lkml.kernel.org/r/1315994224.5040.1.camel@twins
26 Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
28 ipc/sem.c | 10 ++++++++++
29 1 file changed, 10 insertions(+)
31 diff --git a/ipc/sem.c b/ipc/sem.c
32 index 9862c3d..ef34d73 100644
35 @@ -708,6 +708,13 @@ undo:
36 static void wake_up_sem_queue_prepare(struct list_head *pt,
37 struct sem_queue *q, int error)
39 +#ifdef CONFIG_PREEMPT_RT_BASE
40 + struct task_struct *p = q->sleeper;
48 * Hold preempt off so that we don't get preempted and have the
49 @@ -719,6 +726,7 @@ static void wake_up_sem_queue_prepare(struct list_head *pt,
52 list_add_tail(&q->list, pt);
57 @@ -732,6 +740,7 @@ static void wake_up_sem_queue_prepare(struct list_head *pt,
59 static void wake_up_sem_queue_do(struct list_head *pt)
61 +#ifndef CONFIG_PREEMPT_RT_BASE
62 struct sem_queue *q, *t;
65 @@ -744,6 +753,7 @@ static void wake_up_sem_queue_do(struct list_head *pt)
72 static void unlink_queue(struct sem_array *sma, struct sem_queue *q)