aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrederic Weisbecker <frederic@kernel.org>2017-10-26 22:42:35 -0400
committerIngo Molnar <mingo@kernel.org>2017-10-27 03:55:29 -0400
commitde201559df872f83d0c08fb4effe3efd28e6cbc8 (patch)
tree6d23d89a604b67b2cb1d216515f4ce4ab3cd9f41
parent5c4991e24c69737bd41fc2737b1e3980abbf73f9 (diff)
sched/isolation: Introduce housekeeping flags
Before we implement isolcpus under housekeeping, we need the isolation features to be more finegrained. For example some people want NOHZ_FULL without the full scheduler isolation, others want full scheduler isolation without NOHZ_FULL. So let's cut all these isolation features piecewise, at the risk of overcutting it right now. We can still merge some flags later if they always make sense together. Signed-off-by: Frederic Weisbecker <frederic@kernel.org> Acked-by: Thomas Gleixner <tglx@linutronix.de> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Christoph Lameter <cl@linux.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Luiz Capitulino <lcapitulino@redhat.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Rik van Riel <riel@redhat.com> Cc: Wanpeng Li <kernellwp@gmail.com> Link: http://lkml.kernel.org/r/1509072159-31808-9-git-send-email-frederic@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--drivers/net/ethernet/tile/tilegx.c4
-rw-r--r--include/linux/sched/isolation.h26
-rw-r--r--kernel/rcu/tree_plugin.h2
-rw-r--r--kernel/rcu/update.c2
-rw-r--r--kernel/sched/core.c8
-rw-r--r--kernel/sched/fair.c2
-rw-r--r--kernel/sched/isolation.c26
-rw-r--r--kernel/watchdog.c3
8 files changed, 43 insertions, 30 deletions
diff --git a/drivers/net/ethernet/tile/tilegx.c b/drivers/net/ethernet/tile/tilegx.c
index 27a3272dcd48..b3e5816a4678 100644
--- a/drivers/net/ethernet/tile/tilegx.c
+++ b/drivers/net/ethernet/tile/tilegx.c
@@ -2270,8 +2270,8 @@ static int __init tile_net_init_module(void)
2270 tile_net_dev_init(name, mac); 2270 tile_net_dev_init(name, mac);
2271 2271
2272 if (!network_cpus_init()) 2272 if (!network_cpus_init())
2273 cpumask_and(&network_cpus_map, housekeeping_cpumask(), 2273 cpumask_and(&network_cpus_map,
2274 cpu_online_mask); 2274 housekeeping_cpumask(HK_FLAG_MISC), cpu_online_mask);
2275 2275
2276 return 0; 2276 return 0;
2277} 2277}
diff --git a/include/linux/sched/isolation.h b/include/linux/sched/isolation.h
index 93ac2367a520..9bb753eece3b 100644
--- a/include/linux/sched/isolation.h
+++ b/include/linux/sched/isolation.h
@@ -5,35 +5,43 @@
5#include <linux/init.h> 5#include <linux/init.h>
6#include <linux/tick.h> 6#include <linux/tick.h>
7 7
8enum hk_flags {
9 HK_FLAG_TIMER = 1,
10 HK_FLAG_RCU = (1 << 1),
11 HK_FLAG_MISC = (1 << 2),
12 HK_FLAG_SCHED = (1 << 3),
13};
14
8#ifdef CONFIG_CPU_ISOLATION 15#ifdef CONFIG_CPU_ISOLATION
9DECLARE_STATIC_KEY_FALSE(housekeeping_overriden); 16DECLARE_STATIC_KEY_FALSE(housekeeping_overriden);
10extern int housekeeping_any_cpu(void); 17extern int housekeeping_any_cpu(enum hk_flags flags);
11extern const struct cpumask *housekeeping_cpumask(void); 18extern const struct cpumask *housekeeping_cpumask(enum hk_flags flags);
12extern void housekeeping_affine(struct task_struct *t); 19extern void housekeeping_affine(struct task_struct *t, enum hk_flags flags);
13extern bool housekeeping_test_cpu(int cpu); 20extern bool housekeeping_test_cpu(int cpu, enum hk_flags flags);
14extern void __init housekeeping_init(void); 21extern void __init housekeeping_init(void);
15 22
16#else 23#else
17 24
18static inline int housekeeping_any_cpu(void) 25static inline int housekeeping_any_cpu(enum hk_flags flags)
19{ 26{
20 return smp_processor_id(); 27 return smp_processor_id();
21} 28}
22 29
23static inline const struct cpumask *housekeeping_cpumask(void) 30static inline const struct cpumask *housekeeping_cpumask(enum hk_flags flags)
24{ 31{
25 return cpu_possible_mask; 32 return cpu_possible_mask;
26} 33}
27 34
28static inline void housekeeping_affine(struct task_struct *t) { } 35static inline void housekeeping_affine(struct task_struct *t,
36 enum hk_flags flags) { }
29static inline void housekeeping_init(void) { } 37static inline void housekeeping_init(void) { }
30#endif /* CONFIG_CPU_ISOLATION */ 38#endif /* CONFIG_CPU_ISOLATION */
31 39
32static inline bool housekeeping_cpu(int cpu) 40static inline bool housekeeping_cpu(int cpu, enum hk_flags flags)
33{ 41{
34#ifdef CONFIG_CPU_ISOLATION 42#ifdef CONFIG_CPU_ISOLATION
35 if (static_branch_unlikely(&housekeeping_overriden)) 43 if (static_branch_unlikely(&housekeeping_overriden))
36 return housekeeping_test_cpu(cpu); 44 return housekeeping_test_cpu(cpu, flags);
37#endif 45#endif
38 return true; 46 return true;
39} 47}
diff --git a/kernel/rcu/tree_plugin.h b/kernel/rcu/tree_plugin.h
index c7632f51c5a0..34125d23e58a 100644
--- a/kernel/rcu/tree_plugin.h
+++ b/kernel/rcu/tree_plugin.h
@@ -2584,7 +2584,7 @@ static void rcu_bind_gp_kthread(void)
2584 2584
2585 if (!tick_nohz_full_enabled()) 2585 if (!tick_nohz_full_enabled())
2586 return; 2586 return;
2587 housekeeping_affine(current); 2587 housekeeping_affine(current, HK_FLAG_RCU);
2588} 2588}
2589 2589
2590/* Record the current task on dyntick-idle entry. */ 2590/* Record the current task on dyntick-idle entry. */
diff --git a/kernel/rcu/update.c b/kernel/rcu/update.c
index 79abeb0ca329..e3e60efaafee 100644
--- a/kernel/rcu/update.c
+++ b/kernel/rcu/update.c
@@ -719,7 +719,7 @@ static int __noreturn rcu_tasks_kthread(void *arg)
719 LIST_HEAD(rcu_tasks_holdouts); 719 LIST_HEAD(rcu_tasks_holdouts);
720 720
721 /* Run on housekeeping CPUs by default. Sysadm can move if desired. */ 721 /* Run on housekeeping CPUs by default. Sysadm can move if desired. */
722 housekeeping_affine(current); 722 housekeeping_affine(current, HK_FLAG_RCU);
723 723
724 /* 724 /*
725 * Each pass through the following loop makes one check for 725 * Each pass through the following loop makes one check for
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d0fb448dd43a..2210c0203e51 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -527,7 +527,7 @@ int get_nohz_timer_target(void)
527 int i, cpu = smp_processor_id(); 527 int i, cpu = smp_processor_id();
528 struct sched_domain *sd; 528 struct sched_domain *sd;
529 529
530 if (!idle_cpu(cpu) && housekeeping_cpu(cpu)) 530 if (!idle_cpu(cpu) && housekeeping_cpu(cpu, HK_FLAG_TIMER))
531 return cpu; 531 return cpu;
532 532
533 rcu_read_lock(); 533 rcu_read_lock();
@@ -536,15 +536,15 @@ int get_nohz_timer_target(void)
536 if (cpu == i) 536 if (cpu == i)
537 continue; 537 continue;
538 538
539 if (!idle_cpu(i) && housekeeping_cpu(i)) { 539 if (!idle_cpu(i) && housekeeping_cpu(i, HK_FLAG_TIMER)) {
540 cpu = i; 540 cpu = i;
541 goto unlock; 541 goto unlock;
542 } 542 }
543 } 543 }
544 } 544 }
545 545
546 if (!housekeeping_cpu(cpu)) 546 if (!housekeeping_cpu(cpu, HK_FLAG_TIMER))
547 cpu = housekeeping_any_cpu(); 547 cpu = housekeeping_any_cpu(HK_FLAG_TIMER);
548unlock: 548unlock:
549 rcu_read_unlock(); 549 rcu_read_unlock();
550 return cpu; 550 return cpu;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index cdece8f967f0..f755de86a813 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -9027,7 +9027,7 @@ void nohz_balance_enter_idle(int cpu)
9027 return; 9027 return;
9028 9028
9029 /* Spare idle load balancing on CPUs that don't want to be disturbed: */ 9029 /* Spare idle load balancing on CPUs that don't want to be disturbed: */
9030 if (!housekeeping_cpu(cpu)) 9030 if (!housekeeping_cpu(cpu, HK_FLAG_SCHED))
9031 return; 9031 return;
9032 9032
9033 if (test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu))) 9033 if (test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))
diff --git a/kernel/sched/isolation.c b/kernel/sched/isolation.c
index bb8ba19a0235..37a138a780ff 100644
--- a/kernel/sched/isolation.c
+++ b/kernel/sched/isolation.c
@@ -15,37 +15,39 @@
15DEFINE_STATIC_KEY_FALSE(housekeeping_overriden); 15DEFINE_STATIC_KEY_FALSE(housekeeping_overriden);
16EXPORT_SYMBOL_GPL(housekeeping_overriden); 16EXPORT_SYMBOL_GPL(housekeeping_overriden);
17static cpumask_var_t housekeeping_mask; 17static cpumask_var_t housekeeping_mask;
18static unsigned int housekeeping_flags;
18 19
19int housekeeping_any_cpu(void) 20int housekeeping_any_cpu(enum hk_flags flags)
20{ 21{
21 if (static_branch_unlikely(&housekeeping_overriden)) 22 if (static_branch_unlikely(&housekeeping_overriden))
22 return cpumask_any_and(housekeeping_mask, cpu_online_mask); 23 if (housekeeping_flags & flags)
23 24 return cpumask_any_and(housekeeping_mask, cpu_online_mask);
24 return smp_processor_id(); 25 return smp_processor_id();
25} 26}
26EXPORT_SYMBOL_GPL(housekeeping_any_cpu); 27EXPORT_SYMBOL_GPL(housekeeping_any_cpu);
27 28
28const struct cpumask *housekeeping_cpumask(void) 29const struct cpumask *housekeeping_cpumask(enum hk_flags flags)
29{ 30{
30 if (static_branch_unlikely(&housekeeping_overriden)) 31 if (static_branch_unlikely(&housekeeping_overriden))
31 return housekeeping_mask; 32 if (housekeeping_flags & flags)
32 33 return housekeeping_mask;
33 return cpu_possible_mask; 34 return cpu_possible_mask;
34} 35}
35EXPORT_SYMBOL_GPL(housekeeping_cpumask); 36EXPORT_SYMBOL_GPL(housekeeping_cpumask);
36 37
37void housekeeping_affine(struct task_struct *t) 38void housekeeping_affine(struct task_struct *t, enum hk_flags flags)
38{ 39{
39 if (static_branch_unlikely(&housekeeping_overriden)) 40 if (static_branch_unlikely(&housekeeping_overriden))
40 set_cpus_allowed_ptr(t, housekeeping_mask); 41 if (housekeeping_flags & flags)
42 set_cpus_allowed_ptr(t, housekeeping_mask);
41} 43}
42EXPORT_SYMBOL_GPL(housekeeping_affine); 44EXPORT_SYMBOL_GPL(housekeeping_affine);
43 45
44bool housekeeping_test_cpu(int cpu) 46bool housekeeping_test_cpu(int cpu, enum hk_flags flags)
45{ 47{
46 if (static_branch_unlikely(&housekeeping_overriden)) 48 if (static_branch_unlikely(&housekeeping_overriden))
47 return cpumask_test_cpu(cpu, housekeeping_mask); 49 if (housekeeping_flags & flags)
48 50 return cpumask_test_cpu(cpu, housekeeping_mask);
49 return true; 51 return true;
50} 52}
51EXPORT_SYMBOL_GPL(housekeeping_test_cpu); 53EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
@@ -65,6 +67,8 @@ void __init housekeeping_init(void)
65 cpumask_andnot(housekeeping_mask, 67 cpumask_andnot(housekeeping_mask,
66 cpu_possible_mask, tick_nohz_full_mask); 68 cpu_possible_mask, tick_nohz_full_mask);
67 69
70 housekeeping_flags = HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC;
71
68 static_branch_enable(&housekeeping_overriden); 72 static_branch_enable(&housekeeping_overriden);
69 73
70 /* We need at least one CPU to handle housekeeping work */ 74 /* We need at least one CPU to handle housekeeping work */
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index 562652c9c815..e9e2ebb3db29 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -777,7 +777,8 @@ void __init lockup_detector_init(void)
777 if (tick_nohz_full_enabled()) 777 if (tick_nohz_full_enabled())
778 pr_info("Disabling watchdog on nohz_full cores by default\n"); 778 pr_info("Disabling watchdog on nohz_full cores by default\n");
779 779
780 cpumask_copy(&watchdog_cpumask, housekeeping_cpumask()); 780 cpumask_copy(&watchdog_cpumask,
781 housekeeping_cpumask(HK_FLAG_TIMER));
781 782
782 if (!watchdog_nmi_probe()) 783 if (!watchdog_nmi_probe())
783 nmi_watchdog_available = true; 784 nmi_watchdog_available = true;