Thread (46 messages) 46 messages, 6 authors, 2011-09-22

Re: [PATCH -rt] ipc/sem: Rework semaphore wakeups

From: Mike Galbraith <hidden>
Date: 2011-09-14 13:02:25
Also in: lkml

All better.

On Wed, 2011-09-14 at 11:57 +0200, Peter Zijlstra wrote:
quoted hunk ↗ jump to hunk
Subject: ipc/sem: Rework semaphore wakeups
From: Peter Zijlstra <redacted>
Date: Tue Sep 13 15:09:40 CEST 2011

Current sysv sems have a weird ass wakeup scheme that involves keeping
preemption disabled over a potential O(n^2) loop and busy waiting on
that on other CPUs.

Kill this and simply wake the task directly from under the sem_lock.

This was discovered by a migrate_disable() debug feature that
disallows:

  spin_lock();
  preempt_disable();
  spin_unlock()
  preempt_enable();

Cc: Manfred Spraul <redacted>
Suggested-by: Thomas Gleixner <redacted>
Reported-by: Mike Galbraith <redacted>
Signed-off-by: Peter Zijlstra <redacted>
---
 ipc/sem.c |   10 ++++++++++
 1 file changed, 10 insertions(+)

Index: linux-rt/ipc/sem.c
===================================================================
--- linux-rt.orig/ipc/sem.c
+++ linux-rt/ipc/sem.c
@@ -415,6 +415,13 @@ static int try_atomic_semop (struct sem_
 static void wake_up_sem_queue_prepare(struct list_head *pt,
 				struct sem_queue *q, int error)
 {
+#ifdef CONFIG_PREEMPT_RT_BASE
+	struct task_struct *p = q->sleeper;
+	get_task_struct(p);
+	q->status = error;
+	wake_up_process(p);
+	put_task_struct(p);
+#else
 	if (list_empty(pt)) {
 		/*
 		 * Hold preempt off so that we don't get preempted and have the
@@ -426,6 +433,7 @@ static void wake_up_sem_queue_prepare(st
 	q->pid = error;
 
 	list_add_tail(&q->simple_list, pt);
+#endif
 }
 
 /**
@@ -439,6 +447,7 @@ static void wake_up_sem_queue_prepare(st
  */
 static void wake_up_sem_queue_do(struct list_head *pt)
 {
+#ifndef CONFIG_PREEMPT_RT_BASE
 	struct sem_queue *q, *t;
 	int did_something;
 
@@ -451,6 +460,7 @@ static void wake_up_sem_queue_do(struct
 	}
 	if (did_something)
 		preempt_enable();
+#endif
 }
 
 static void unlink_queue(struct sem_array *sma, struct sem_queue *q)
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help