diff --git a/ipc/sem.c b/ipc/sem.c index add93d2..96aef6d 100644 --- a/ipc/sem.c +++ b/ipc/sem.c @@ -416,11 +416,13 @@ static void wake_up_sem_queue_prepare(struct list_head *pt, struct sem_queue *q, int error) { if (list_empty(pt)) { +#ifndef CONFIG_PREEMPT_RT_BASE /* * Hold preempt off so that we don't get preempted and have the * wakee busy-wait until we're scheduled back on. */ preempt_disable(); +#endif } q->status = IN_WAKEUP; q->pid = error; @@ -449,8 +451,10 @@ static void wake_up_sem_queue_do(struct list_head *pt) smp_wmb(); q->status = q->pid; } - if (did_something) + if (did_something) { +#ifndef CONFIG_PREEMPT_RT_BASE preempt_enable(); +#endif } static void unlink_queue(struct sem_array *sma, struct sem_queue *q) @@ -1280,6 +1284,13 @@ static int get_queue_result(struct sem_queue *q) error = q->status; while (unlikely(error == IN_WAKEUP)) { cpu_relax(); +#ifdef CONFIG_PREEMPT_RT_BASE + /*FIXME: obviously broken if called with semaphore spinlock held + * sched_yield() should only be called if get_queue_result() is + * called outside of the semaphore lock + */ + sched_yield(); +#endif error = q->status; }