2018-08-27 14:32:32 +00:00
|
|
|
From: Thomas Gleixner <tglx@linutronix.de>
|
|
|
|
Date: Wed, 15 Jun 2011 12:36:06 +0200
|
2019-11-25 00:04:39 +00:00
|
|
|
Subject: [PATCH 116/290] hotplug: Lightweight get online cpus
|
|
|
|
Origin: https://git.kernel.org/cgit/linux/kernel/git/rt/linux-stable-rt.git/commit?id=b3427c6b64cd30370b25801db8a88491596c1d4c
|
2018-08-27 14:32:32 +00:00
|
|
|
|
|
|
|
get_online_cpus() is a heavy weight function which involves a global
|
|
|
|
mutex. migrate_disable() wants a simpler construct which prevents only
|
|
|
|
a CPU from going doing while a task is in a migrate disabled section.
|
|
|
|
|
|
|
|
Implement a per cpu lockless mechanism, which serializes only in the
|
|
|
|
real unplug case on a global mutex. That serialization affects only
|
|
|
|
tasks on the cpu which should be brought down.
|
|
|
|
|
|
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
|
|
---
|
2019-04-08 23:49:20 +00:00
|
|
|
include/linux/cpu.h | 5 +++++
|
|
|
|
kernel/cpu.c | 15 +++++++++++++++
|
|
|
|
kernel/sched/core.c | 4 ++++
|
2018-08-27 14:32:32 +00:00
|
|
|
3 files changed, 24 insertions(+)
|
|
|
|
|
2019-04-08 23:49:20 +00:00
|
|
|
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
|
2019-08-18 21:33:52 +00:00
|
|
|
index 006f69f9277b..d45ea5c98cdd 100644
|
2018-08-27 14:32:32 +00:00
|
|
|
--- a/include/linux/cpu.h
|
|
|
|
+++ b/include/linux/cpu.h
|
2019-08-18 21:33:52 +00:00
|
|
|
@@ -113,6 +113,8 @@ extern void cpu_hotplug_disable(void);
|
2018-08-27 14:32:32 +00:00
|
|
|
extern void cpu_hotplug_enable(void);
|
|
|
|
void clear_tasks_mm_cpumask(int cpu);
|
|
|
|
int cpu_down(unsigned int cpu);
|
|
|
|
+extern void pin_current_cpu(void);
|
|
|
|
+extern void unpin_current_cpu(void);
|
|
|
|
|
|
|
|
#else /* CONFIG_HOTPLUG_CPU */
|
|
|
|
|
2019-08-18 21:33:52 +00:00
|
|
|
@@ -124,6 +126,9 @@ static inline int cpus_read_trylock(void) { return true; }
|
2018-08-27 14:32:32 +00:00
|
|
|
static inline void lockdep_assert_cpus_held(void) { }
|
|
|
|
static inline void cpu_hotplug_disable(void) { }
|
|
|
|
static inline void cpu_hotplug_enable(void) { }
|
|
|
|
+static inline void pin_current_cpu(void) { }
|
|
|
|
+static inline void unpin_current_cpu(void) { }
|
|
|
|
+
|
|
|
|
#endif /* !CONFIG_HOTPLUG_CPU */
|
|
|
|
|
|
|
|
/* Wrappers which go away once all code is converted */
|
2019-04-08 23:49:20 +00:00
|
|
|
diff --git a/kernel/cpu.c b/kernel/cpu.c
|
2019-11-25 00:04:39 +00:00
|
|
|
index d9f855cb9f6f..02e05a7e463c 100644
|
2018-08-27 14:32:32 +00:00
|
|
|
--- a/kernel/cpu.c
|
|
|
|
+++ b/kernel/cpu.c
|
2018-12-14 09:55:05 +00:00
|
|
|
@@ -281,6 +281,21 @@ static int cpu_hotplug_disabled;
|
2018-08-27 14:32:32 +00:00
|
|
|
|
|
|
|
#ifdef CONFIG_HOTPLUG_CPU
|
|
|
|
|
|
|
|
+/**
|
|
|
|
+ * pin_current_cpu - Prevent the current cpu from being unplugged
|
|
|
|
+ */
|
|
|
|
+void pin_current_cpu(void)
|
|
|
|
+{
|
|
|
|
+
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * unpin_current_cpu - Allow unplug of current cpu
|
|
|
|
+ */
|
|
|
|
+void unpin_current_cpu(void)
|
|
|
|
+{
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
DEFINE_STATIC_PERCPU_RWSEM(cpu_hotplug_lock);
|
|
|
|
|
|
|
|
void cpus_read_lock(void)
|
2019-04-08 23:49:20 +00:00
|
|
|
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
|
2019-11-25 00:04:39 +00:00
|
|
|
index 9ba05b3f69e1..5723a8966865 100644
|
2018-08-27 14:32:32 +00:00
|
|
|
--- a/kernel/sched/core.c
|
|
|
|
+++ b/kernel/sched/core.c
|
2019-11-25 00:04:39 +00:00
|
|
|
@@ -7248,6 +7248,7 @@ void migrate_disable(void)
|
2018-08-27 14:32:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
preempt_disable();
|
|
|
|
+ pin_current_cpu();
|
|
|
|
|
|
|
|
migrate_disable_update_cpus_allowed(p);
|
|
|
|
p->migrate_disable = 1;
|
2019-11-25 00:04:39 +00:00
|
|
|
@@ -7313,12 +7314,15 @@ void migrate_enable(void)
|
2018-08-27 14:32:32 +00:00
|
|
|
arg.task = p;
|
|
|
|
arg.dest_cpu = dest_cpu;
|
|
|
|
|
|
|
|
+ unpin_current_cpu();
|
|
|
|
preempt_enable();
|
|
|
|
stop_one_cpu(task_cpu(p), migration_cpu_stop, &arg);
|
|
|
|
tlb_migrate_finish(p->mm);
|
|
|
|
+
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
+ unpin_current_cpu();
|
|
|
|
preempt_enable();
|
|
|
|
}
|
|
|
|
EXPORT_SYMBOL(migrate_enable);
|