|
@@ -10,6 +10,8 @@
|
|
|
#include <linux/sched.h>
|
|
|
#include <linux/unistd.h>
|
|
|
#include <linux/cpu.h>
|
|
|
+#include <linux/oom.h>
|
|
|
+#include <linux/rcupdate.h>
|
|
|
#include <linux/export.h>
|
|
|
#include <linux/kthread.h>
|
|
|
#include <linux/stop_machine.h>
|
|
@@ -173,6 +175,30 @@ void __ref unregister_cpu_notifier(struct notifier_block *nb)
|
|
|
}
|
|
|
EXPORT_SYMBOL(unregister_cpu_notifier);
|
|
|
|
|
|
+void clear_tasks_mm_cpumask(int cpu)
|
|
|
+{
|
|
|
+ struct task_struct *p;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * This function is called after the cpu is taken down and marked
|
|
|
+ * offline, so its not like new tasks will ever get this cpu set in
|
|
|
+ * their mm mask. -- Peter Zijlstra
|
|
|
+ * Thus, we may use rcu_read_lock() here, instead of grabbing
|
|
|
+ * full-fledged tasklist_lock.
|
|
|
+ */
|
|
|
+ rcu_read_lock();
|
|
|
+ for_each_process(p) {
|
|
|
+ struct task_struct *t;
|
|
|
+
|
|
|
+ t = find_lock_task_mm(p);
|
|
|
+ if (!t)
|
|
|
+ continue;
|
|
|
+ cpumask_clear_cpu(cpu, mm_cpumask(t->mm));
|
|
|
+ task_unlock(t);
|
|
|
+ }
|
|
|
+ rcu_read_unlock();
|
|
|
+}
|
|
|
+
|
|
|
static inline void check_for_tasks(int cpu)
|
|
|
{
|
|
|
struct task_struct *p;
|