~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/kernel/sched/isolation.c

Version: ~ [ linux-5.1-rc1 ] ~ [ linux-5.0.3 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.30 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.107 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.164 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.176 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.136 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  Housekeeping management. Manage the targets for routine code that can run on
  3  *  any CPU: unbound workqueues, timers, kthreads and any offloadable work.
  4  *
  5  * Copyright (C) 2017 Red Hat, Inc., Frederic Weisbecker
  6  * Copyright (C) 2017-2018 SUSE, Frederic Weisbecker
  7  *
  8  */
  9 #include "sched.h"
 10 
 11 DEFINE_STATIC_KEY_FALSE(housekeeping_overridden);
 12 EXPORT_SYMBOL_GPL(housekeeping_overridden);
 13 static cpumask_var_t housekeeping_mask;
 14 static unsigned int housekeeping_flags;
 15 
 16 int housekeeping_any_cpu(enum hk_flags flags)
 17 {
 18         if (static_branch_unlikely(&housekeeping_overridden))
 19                 if (housekeeping_flags & flags)
 20                         return cpumask_any_and(housekeeping_mask, cpu_online_mask);
 21         return smp_processor_id();
 22 }
 23 EXPORT_SYMBOL_GPL(housekeeping_any_cpu);
 24 
 25 const struct cpumask *housekeeping_cpumask(enum hk_flags flags)
 26 {
 27         if (static_branch_unlikely(&housekeeping_overridden))
 28                 if (housekeeping_flags & flags)
 29                         return housekeeping_mask;
 30         return cpu_possible_mask;
 31 }
 32 EXPORT_SYMBOL_GPL(housekeeping_cpumask);
 33 
 34 void housekeeping_affine(struct task_struct *t, enum hk_flags flags)
 35 {
 36         if (static_branch_unlikely(&housekeeping_overridden))
 37                 if (housekeeping_flags & flags)
 38                         set_cpus_allowed_ptr(t, housekeeping_mask);
 39 }
 40 EXPORT_SYMBOL_GPL(housekeeping_affine);
 41 
 42 bool housekeeping_test_cpu(int cpu, enum hk_flags flags)
 43 {
 44         if (static_branch_unlikely(&housekeeping_overridden))
 45                 if (housekeeping_flags & flags)
 46                         return cpumask_test_cpu(cpu, housekeeping_mask);
 47         return true;
 48 }
 49 EXPORT_SYMBOL_GPL(housekeeping_test_cpu);
 50 
 51 void __init housekeeping_init(void)
 52 {
 53         if (!housekeeping_flags)
 54                 return;
 55 
 56         static_branch_enable(&housekeeping_overridden);
 57 
 58         if (housekeeping_flags & HK_FLAG_TICK)
 59                 sched_tick_offload_init();
 60 
 61         /* We need at least one CPU to handle housekeeping work */
 62         WARN_ON_ONCE(cpumask_empty(housekeeping_mask));
 63 }
 64 
 65 static int __init housekeeping_setup(char *str, enum hk_flags flags)
 66 {
 67         cpumask_var_t non_housekeeping_mask;
 68         int err;
 69 
 70         alloc_bootmem_cpumask_var(&non_housekeeping_mask);
 71         err = cpulist_parse(str, non_housekeeping_mask);
 72         if (err < 0 || cpumask_last(non_housekeeping_mask) >= nr_cpu_ids) {
 73                 pr_warn("Housekeeping: nohz_full= or isolcpus= incorrect CPU range\n");
 74                 free_bootmem_cpumask_var(non_housekeeping_mask);
 75                 return 0;
 76         }
 77 
 78         if (!housekeeping_flags) {
 79                 alloc_bootmem_cpumask_var(&housekeeping_mask);
 80                 cpumask_andnot(housekeeping_mask,
 81                                cpu_possible_mask, non_housekeeping_mask);
 82                 if (cpumask_empty(housekeeping_mask))
 83                         __cpumask_set_cpu(smp_processor_id(), housekeeping_mask);
 84         } else {
 85                 cpumask_var_t tmp;
 86 
 87                 alloc_bootmem_cpumask_var(&tmp);
 88                 cpumask_andnot(tmp, cpu_possible_mask, non_housekeeping_mask);
 89                 if (!cpumask_equal(tmp, housekeeping_mask)) {
 90                         pr_warn("Housekeeping: nohz_full= must match isolcpus=\n");
 91                         free_bootmem_cpumask_var(tmp);
 92                         free_bootmem_cpumask_var(non_housekeeping_mask);
 93                         return 0;
 94                 }
 95                 free_bootmem_cpumask_var(tmp);
 96         }
 97 
 98         if ((flags & HK_FLAG_TICK) && !(housekeeping_flags & HK_FLAG_TICK)) {
 99                 if (IS_ENABLED(CONFIG_NO_HZ_FULL)) {
100                         tick_nohz_full_setup(non_housekeeping_mask);
101                 } else {
102                         pr_warn("Housekeeping: nohz unsupported."
103                                 " Build with CONFIG_NO_HZ_FULL\n");
104                         free_bootmem_cpumask_var(non_housekeeping_mask);
105                         return 0;
106                 }
107         }
108 
109         housekeeping_flags |= flags;
110 
111         free_bootmem_cpumask_var(non_housekeeping_mask);
112 
113         return 1;
114 }
115 
116 static int __init housekeeping_nohz_full_setup(char *str)
117 {
118         unsigned int flags;
119 
120         flags = HK_FLAG_TICK | HK_FLAG_WQ | HK_FLAG_TIMER | HK_FLAG_RCU | HK_FLAG_MISC;
121 
122         return housekeeping_setup(str, flags);
123 }
124 __setup("nohz_full=", housekeeping_nohz_full_setup);
125 
126 static int __init housekeeping_isolcpus_setup(char *str)
127 {
128         unsigned int flags = 0;
129 
130         while (isalpha(*str)) {
131                 if (!strncmp(str, "nohz,", 5)) {
132                         str += 5;
133                         flags |= HK_FLAG_TICK;
134                         continue;
135                 }
136 
137                 if (!strncmp(str, "domain,", 7)) {
138                         str += 7;
139                         flags |= HK_FLAG_DOMAIN;
140                         continue;
141                 }
142 
143                 pr_warn("isolcpus: Error, unknown flag\n");
144                 return 0;
145         }
146 
147         /* Default behaviour for isolcpus without flags */
148         if (!flags)
149                 flags |= HK_FLAG_DOMAIN;
150 
151         return housekeeping_setup(str, flags);
152 }
153 __setup("isolcpus=", housekeeping_isolcpus_setup);
154 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp