[Devel] [PATCH RH8] proc connector: protect from task cpu migration in send_msg_ve

Alexander Mikhalitsyn alexander.mikhalitsyn at virtuozzo.com
Tue Aug 31 15:34:24 MSK 2021


Fixes: 0e60020d2a ("proc connector: take number of listeners and per-cpu conters from VE")

Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
---
 drivers/connector/cn_proc.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c
index 9b63792f0dff..83c068c900cf 100644
--- a/drivers/connector/cn_proc.c
+++ b/drivers/connector/cn_proc.c
@@ -63,6 +63,21 @@ static inline void send_msg_ve(struct ve_struct *ve, struct cn_msg *msg)
 {
 	struct local_event *le_ptr;
 
+	/*
+	 * Our kernel is non-PREEMPT_RT or even non-PREEMPT but
+	 * to be on the safe side we need to disable task cpu
+	 * migration before calculating this_cpu_ptr.
+	 *
+	 * Note 1. local_lock implies migrate_disable on PREEMPT_RT
+	 * kernels and preempt_disable on PREEMPT kernels.
+	 * But we need to have migrations disabled *before*
+	 * this_cpu_ptr() call.
+	 * It's safe to nest migrate_disable/preempt_disable.
+	 * Note 2. yep, local_lock is still needed here because
+	 * on PREEMPT_RT kernel it is also implies per-cpu spin_lock
+	 * which protects from reentrancy problems.
+	 */
+	migrate_disable();
 	le_ptr = this_cpu_ptr(ve->cn->local_event);
 	local_lock(&le_ptr->lock);
 
@@ -78,6 +93,7 @@ static inline void send_msg_ve(struct ve_struct *ve, struct cn_msg *msg)
 	cn_netlink_send_ve(ve, msg, 0, CN_IDX_PROC, GFP_NOWAIT);
 
 	local_unlock(&le_ptr->lock);
+	migrate_enable();
 }
 
 static struct cn_msg *cn_msg_fill(__u8 *buffer, struct ve_struct *ve,
-- 
2.28.0



More information about the Devel mailing list