2013-11-22 01:00:09 +00:00
|
|
|
From: Ingo Molnar <mingo@elte.hu>
|
|
|
|
Date: Fri, 3 Jul 2009 08:30:12 -0500
|
|
|
|
Subject: ipc: Make the ipc code -rt aware
|
2014-01-15 02:32:05 +00:00
|
|
|
Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/3.12/patches-3.12.6-rt9.tar.xz
|
2013-11-22 01:00:09 +00:00
|
|
|
|
|
|
|
RT serializes the code with the (rt)spinlock but keeps preemption
|
|
|
|
enabled. Some parts of the code need to be atomic nevertheless.
|
|
|
|
|
|
|
|
Protect it with preempt_disable/enable_rt pairts.
|
|
|
|
|
|
|
|
Signed-off-by: Ingo Molnar <mingo@elte.hu>
|
|
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
|
|
|
|
|
|
---
|
|
|
|
ipc/mqueue.c | 5 +++++
|
|
|
|
ipc/msg.c | 16 ++++++++++++++++
|
|
|
|
2 files changed, 21 insertions(+)
|
|
|
|
|
|
|
|
--- a/ipc/mqueue.c
|
|
|
|
+++ b/ipc/mqueue.c
|
|
|
|
@@ -923,12 +923,17 @@ static inline void pipelined_send(struct
|
|
|
|
struct msg_msg *message,
|
|
|
|
struct ext_wait_queue *receiver)
|
|
|
|
{
|
|
|
|
+ /*
|
|
|
|
+ * Keep them in one critical section for PREEMPT_RT:
|
|
|
|
+ */
|
|
|
|
+ preempt_disable_rt();
|
|
|
|
receiver->msg = message;
|
|
|
|
list_del(&receiver->list);
|
|
|
|
receiver->state = STATE_PENDING;
|
|
|
|
wake_up_process(receiver->task);
|
|
|
|
smp_wmb();
|
|
|
|
receiver->state = STATE_READY;
|
|
|
|
+ preempt_enable_rt();
|
|
|
|
}
|
|
|
|
|
|
|
|
/* pipelined_receive() - if there is task waiting in sys_mq_timedsend()
|
|
|
|
--- a/ipc/msg.c
|
|
|
|
+++ b/ipc/msg.c
|
|
|
|
@@ -253,10 +253,18 @@ static void expunge_all(struct msg_queue
|
|
|
|
struct msg_receiver *msr, *t;
|
|
|
|
|
|
|
|
list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) {
|
|
|
|
+ /*
|
|
|
|
+ * Make sure that the wakeup doesnt preempt
|
|
|
|
+ * this CPU prematurely. (on PREEMPT_RT)
|
|
|
|
+ */
|
|
|
|
+ preempt_disable_rt();
|
|
|
|
+
|
|
|
|
msr->r_msg = NULL;
|
|
|
|
wake_up_process(msr->r_tsk);
|
|
|
|
smp_mb();
|
|
|
|
msr->r_msg = ERR_PTR(res);
|
|
|
|
+
|
|
|
|
+ preempt_enable_rt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@@ -636,6 +644,12 @@ static inline int pipelined_send(struct
|
|
|
|
!security_msg_queue_msgrcv(msq, msg, msr->r_tsk,
|
|
|
|
msr->r_msgtype, msr->r_mode)) {
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Make sure that the wakeup doesnt preempt
|
|
|
|
+ * this CPU prematurely. (on PREEMPT_RT)
|
|
|
|
+ */
|
|
|
|
+ preempt_disable_rt();
|
|
|
|
+
|
|
|
|
list_del(&msr->r_list);
|
|
|
|
if (msr->r_maxsize < msg->m_ts) {
|
|
|
|
msr->r_msg = NULL;
|
|
|
|
@@ -649,9 +663,11 @@ static inline int pipelined_send(struct
|
|
|
|
wake_up_process(msr->r_tsk);
|
|
|
|
smp_mb();
|
|
|
|
msr->r_msg = msg;
|
|
|
|
+ preempt_enable_rt();
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
+ preempt_enable_rt();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|