cpusets: Isolate CPUs via sysfs using cpusets
Subsystems (5)
v2 cover cpusets: Isolate CPUs via sysfs using cpusets
We need to migrate away all the background kernel activities (Unbound) for systems requiring isolation of cores (HPC, Real time, networking, etc). After creating cpusets, you can write 1 or 0 to cpuset.quiesce file.
In our case, we are working on a networking machine which wants to run time critical data plane threads on some CPUs, i.e. a single thread per CPU. And these CPUs shouldn't be interrupted at all by background kernel activities, like timers/hrtimers/workqueues/etc..
Writing '1': on this file would migrate unbound/unpinned timers and hrtimers away from the CPUs of the cpuset in question. Also it would disallow addition of any new unpinned timers & hrtimers to isolated CPUs.
Writing '0': will disable isolation of CPUs in current cpuset and unpinned timers/hrtimers would be allowed in future on these CPUs.
This patchset allow us to do this. In the first few patches it builds basic infrastructure in timers and hrtimers and then finally use that in cpusets. Also it updates get_nohz_timer_target() to stop adding new timers/hrtimers to these isolated CPUs.
V1: https://lkml.org/lkml/2014/3/20/319
Not many comments received.
Based on some other timers/hrtimers cleanup I did:
http://comments.gmane.org/gmane.linux.kernel/1677797
Available here: git://git.linaro.org/people/viresh.kumar/linux.git isolate-cpusets
V1->V2:
- Add support to migrate hrtimers as well (V1 only had timers)
- cpuset.quiesce now supports writing 0 and reading as well
- update get_nohz_timer_target() to stop adding new timers/hrtimers to these isolated CPUs.
- Minor fixups that I noticed
Known issues:
1. Patch: "timer: track pinned timers with TIMER_PINNED flag", following reporting by kbuild system (Don't know how to fix this):
config: make ARCH=blackfin allyesconfig
Note: the vireshk/timer-cleanup-for-tglx HEAD ea63467ac9150cd86f4d960887116f99a2803b56 builds fine. It only hurts bisectibility.
All error/warnings:
kernel/timer.c: In function 'init_timers':
>> kernel/timer.c:1683:2: error: call to '__compiletime_assert_1683' >> declared with attribute error: BUILD_BUG_ON failed:
>> __alignof__(struct tvec_base) & TIMER_FLAG_MASK
2. Patch: "timer: don't migrate pinned timers", following reporting by kbuild system (Not really a problem created due to this patch, but just highlighted an existing bug. As pinned timers must be removed by owners before CPU goes down):
smpboot: CPU 1 is now offline
------------[ cut here ]------------
WARNING: CPU: 0 PID: 1935 at kernel/timer.c:1621 migrate_timer_list+0xd6/0xf0()
migrate_timer_list: can't migrate pinned timer: ffffffff81f06a60, deactivating it Modules linked in:
Viresh Kumar (8):
timer: track pinned timers with TIMER_PINNED flag
timer: don't migrate pinned timers
timer: create timer_quiesce_cpu() to isolate CPU from timers
hrtimer: update timer->state with 'pinned' information
hrtimer: don't migrate pinned timers
hrtimer: create hrtimer_quiesce_cpu() to isolate CPU from hrtimers
cpuset: Create sysfs file: cpusets.quiesce to isolate CPUs
sched: don't queue timers on quiesced CPUs
Documentation/cgroups/cpusets.txt | 19 +++++++- include/linux/cpuset.h | 8 ++++ include/linux/hrtimer.h | 6 +++ include/linux/timer.h | 13 ++++-- kernel/cpuset.c | 76 ++++++++++++++++++++++++++++++++ kernel/hrtimer.c | 69 ++++++++++++++++++++++++----- kernel/sched/core.c | 9 ++-- kernel/timer.c | 91 +++++++++++++++++++++++++++++++-------- 8 files changed, 253 insertions(+), 38 deletions(-)
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 1/8 timer: track pinned timers with TIMER_PINNED flag
In order to quiesce a CPU on which Isolation might be required, we need to move away all the timers queued on that CPU. There are two types of timers queued on any CPU: ones that are pinned to that CPU and others can run on any CPU but are queued on CPU in question. And we need to migrate only the second type of timers away from the CPU entering quiesce state.
For this we need some basic infrastructure in timer core to identify which timers are pinned and which are not.
Hence, this patch adds another flag bit TIMER_PINNED which will be set only for the timers which are pinned to a CPU.
It also removes 'pinned' parameter of __mod_timer() as it is no more required.
NOTE: One functional change worth mentioning
Existing Behavior: add_timer_on() followed by multiple mod_timer() wouldn't pin the timer on CPU mentioned in add_timer_on()..
New Behavior: add_timer_on() followed by multiple mod_timer() would pin the timer on CPU running mod_timer().
I didn't gave much attention to this as we should call mod_timer_on() for the timers queued with add_timer_on(). Though if required we can simply clear the TIMER_PINNED flag in mod_timer().
--- include/linux/timer.h | 10 ++++++---- kernel/timer.c | 27 ++++++++++++++++++++------- 2 files changed, 26 insertions(+), 11 deletions(-)
include/linux/timer.h +6 -4
@@ -49,7 +49,7 @@ extern struct tvec_base boot_tvec_bases;#endif /* -* Note that all tvec_bases are at least 4 byte aligned and lower two bits +* Note that all tvec_bases are at least 8 byte aligned and lower three bits * of base in timer_list is guaranteed to be zero. Use them for flags. * * A deferrable timer will work normally when the system is busy, but
@@ -61,14 +61,18 @@ extern struct tvec_base boot_tvec_bases;* the completion of the running instance from IRQ handlers, for example, * by calling del_timer_sync(). * +* A pinned timer is allowed to run only on the cpu mentioned and shouldn't be +* migrated to any other CPU. +* * Note: The irq disabled callback execution is a special case for * workqueue locking issues. It's not meant for executing random crap * with interrupts disabled. Abuse is monitored! */ #define TIMER_DEFERRABLE 0x1LU#define TIMER_IRQSAFE 0x2LU +#define TIMER_PINNED 0x4LU -#define TIMER_FLAG_MASK 0x3LU +#define TIMER_FLAG_MASK 0x7LU#define __TIMER_INITIALIZER (_function, _expires, _data, _flags) { \ .entry = { .prev = TIMER_ENTRY_STATIC }, \
@@ -179,8 +183,6 @@ extern int mod_timer_pinned(struct timer_list *timer, unsigned long expires);extern void set_timer_slack (struct timer_list *time,int slack_hz); -#define TIMER_NOT_PINNED 0 -#define TIMER_PINNED 1/* * The jiffies value which is added to now, when there is no timer * in the timer wheel:
kernel/timer.c +20 -7
@@ -104,6 +104,11 @@ static inline unsigned int tbase_get_irqsafe(struct tvec_base *base)return ((unsigned int )(unsigned long )base &TIMER_IRQSAFE ); } +static inline unsigned int tbase_get_pinned (struct tvec_base *base) +{ +return ((unsigned int )(unsigned long )base &TIMER_PINNED ); +} +static inline struct tvec_base *tbase_get_base (struct tvec_base *base) {return ((struct tvec_base *)((unsigned long )base & ~TIMER_FLAG_MASK ));
@@ -117,6 +122,13 @@ timer_set_base(struct timer_list *timer, struct tvec_base *new_base) timer->base = (struct tvec_base *)((unsigned long )(new_base) | flags); } +static inline void +timer_set_flags (struct timer_list *timer,unsigned int flags) +{ + timer->base = (struct tvec_base *)((unsigned long )(timer->base) | + flags); +} +static unsigned long round_jiffies_common (unsigned long j,int cpu,bool force_up) {
@@ -742,8 +754,7 @@ static struct tvec_base *lock_timer_base(struct timer_list *timer, }static inline int -__mod_timer (struct timer_list *timer,unsigned long expires, -bool pending_only,int pinned) +__mod_timer (struct timer_list *timer,unsigned long expires,bool pending_only) {struct tvec_base *base, *new_base;unsigned long flags;
@@ -760,7 +771,7 @@ __mod_timer(struct timer_list *timer, unsigned long expires,debug_activate (timer, expires); - cpu =get_nohz_timer_target (pinned); + cpu =get_nohz_timer_target (tbase_get_pinned (timer->base)); new_base =per_cpu (tvec_bases, cpu);if (base != new_base) {
@@ -802,7 +813,7 @@ out_unlock:*/ int mod_timer_pending (struct timer_list *timer,unsigned long expires) { -return __mod_timer (timer, expires, true,TIMER_NOT_PINNED ); +return __mod_timer (timer, expires, true); }EXPORT_SYMBOL (mod_timer_pending);
@@ -877,7 +888,7 @@ int mod_timer(struct timer_list *timer, unsigned long expires)if (timer_pending (timer) && timer->expires == expires)return 1 ; -return __mod_timer (timer, expires, false,TIMER_NOT_PINNED ); +return __mod_timer (timer, expires, false); }EXPORT_SYMBOL (mod_timer);
@@ -905,7 +916,8 @@ int mod_timer_pinned(struct timer_list *timer, unsigned long expires)if (timer->expires == expires &&timer_pending (timer))return 1 ; -return __mod_timer (timer, expires, false,TIMER_PINNED ); +timer_set_flags (timer,TIMER_PINNED ); +return __mod_timer (timer, expires, false); }EXPORT_SYMBOL (mod_timer_pinned);
@@ -944,6 +956,7 @@ void add_timer_on(struct timer_list *timer, int cpu)timer_stats_timer_set_start_info (timer);BUG_ON (timer_pending (timer) || !timer->function); +timer_set_flags (timer,TIMER_PINNED );spin_lock_irqsave (&base->lock, flags);timer_set_base (timer, base);debug_activate (timer, timer->expires);
@@ -1493,7 +1506,7 @@ signed long __sched schedule_timeout(signed long timeout) expire = timeout + jiffies;setup_timer_on_stack (&timer, process_timeout, (unsigned long )current); -__mod_timer (&timer, expire, false,TIMER_NOT_PINNED ); +__mod_timer (&timer, expire, false);schedule ();del_singleshot_timer_sync (&timer);
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 2/8 timer: don't migrate pinned timers
In reply to Viresh Kumarmigrate_timer() is called when a CPU goes down and its timers are required to be migrated to some other CPU. Its the responsibility of the users of the timer to remove it before control reaches to migrate_timers().
As these were the pinned timers, the best we can do is: don't migrate these and report to the user as well.
That's all this patch does.
--- kernel/timer.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
kernel/timer.c +10 -0
@@ -1606,11 +1606,21 @@ static int init_timers_cpu(int cpu)static void migrate_timer_list (struct tvec_base *new_base,struct list_head *head) {struct timer_list *timer; +int is_pinned;while (!list_empty (head)) { timer = list_first_entry(head, struct timer_list, entry);/* We ignore the accounting on the dying cpu */ detach_timer (timer, false); + + is_pinned =tbase_get_pinned (timer->base); + +/* Check if CPU still has pinned timers */ +if (unlikely (WARN (is_pinned, +"%s: can't migrate pinned timer: %p, deactivating it\n" , + __func__, timer))) +continue ; +timer_set_base (timer, new_base);internal_add_timer (new_base, timer); }
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 3/8 timer: create timer_quiesce_cpu() to isolate CPU from timers
In reply to Viresh KumarTo isolate CPUs (isolate from timers) from sysfs using cpusets, we need some support from the timer core. i.e. A routine timer_quiesce_cpu() which would migrate away all the unpinned timers, but shouldn't touch the pinned ones.
This patch creates this routine.
--- include/linux/timer.h | 3 +++ kernel/timer.c | 54 ++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 46 insertions(+), 11 deletions(-)
include/linux/timer.h +3 -0
@@ -196,6 +196,9 @@ extern void set_timer_slack(struct timer_list *time, int slack_hz);*/ extern unsigned long get_next_timer_interrupt (unsigned long now); +/* To be used from cpusets, only */ +extern void timer_quiesce_cpu (void *cpup); +/* * Timer-statistics info: */
kernel/timer.c +43 -11
96 lines not on this page · raw message
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 4/8 hrtimer: update timer->state with 'pinned' information
In reply to Viresh Kumar'Pinned' information would be required in migrate_hrtimers() now, as we can migrate non-pinned timers away without a hotplug (i.e. with cpuset.quiesce). And so we may need to identify pinned timers now, as we can't migrate them.
This patch reuses the timer->state variable for setting this flag as there were enough number of free bits available in this variable. And there is no point increasing size of this struct by adding another field.
--- include/linux/hrtimer.h | 3 +++ kernel/hrtimer.c | 12 ++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-)
include/linux/hrtimer.h +3 -0
@@ -55,6 +55,7 @@ enum hrtimer_restart {* 0x01 enqueued into rbtree * 0x02 callback function running * 0x04 timer is migrated to another cpu +* 0x08 timer is pinned to a cpu * * Special cases: * 0x03 callback function running and enqueued
@@ -81,6 +82,8 @@ enum hrtimer_restart {#define HRTIMER_STATE_ENQUEUED 0x01#define HRTIMER_STATE_CALLBACK 0x02#define HRTIMER_STATE_MIGRATE 0x04 +#define HRTIMER_PINNED_SHIFT 3 +#define HRTIMER_STATE_PINNED (1 << HRTIMER_PINNED_SHIFT)/** * struct hrtimer - the basic hrtimer structure
kernel/hrtimer.c +10 -2
@@ -905,7 +905,11 @@ static void __remove_hrtimer(struct hrtimer *timer, unsigned long newstate, hrtimer_force_reprogram(base->cpu_base, 1); }#endif - timer->state = newstate; +/* +* We need to preserve PINNED state here, otherwise we may end up +* migrating pinned hrtimers as well. +*/ + timer->state = newstate | (timer->state &HRTIMER_STATE_PINNED ); }/* remove hrtimer, called with base lock held */
@@ -970,6 +974,10 @@ int __hrtimer_start_range_ns(struct hrtimer *timer, ktime_t tim,timer_stats_hrtimer_set_start_info (timer); +/* Update pinned state */ + timer->state &= ~HRTIMER_STATE_PINNED ; + timer->state |= !!(mode &HRTIMER_MODE_PINNED ) <<HRTIMER_PINNED_SHIFT ; +enqueue_hrtimer (timer);/*
@@ -1227,7 +1235,7 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)* hrtimer_start_range_ns() or in hrtimer_interrupt() */ if (restart !=HRTIMER_NORESTART ) { -BUG_ON (timer->state !=HRTIMER_STATE_CALLBACK ); +BUG_ON (!(timer->state &HRTIMER_STATE_CALLBACK ));enqueue_hrtimer (timer); }
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 5/8 hrtimer: don't migrate pinned timers
In reply to Viresh Kumarmigrate_hrtimer() is called when a CPU goes down and its timers are required to be migrated to some other CPU. Its the responsibility of the users of the hrtimer to remove it before control reaches to migrate_hrtimer().
As these were the pinned hrtimers, the best we can do is: don't migrate these and report to the user as well.
That's all this patch does.
--- kernel/hrtimer.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
kernel/hrtimer.c +10 -0
@@ -1640,6 +1640,7 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base, {struct hrtimer *timer;struct timerqueue_node *node; +int is_pinned;while ((node =timerqueue_getnext (&old_base->active))) { timer = container_of(node, struct hrtimer, node);
@@ -1652,6 +1653,15 @@ static void migrate_hrtimer_list(struct hrtimer_clock_base *old_base,* under us on another CPU */ __remove_hrtimer (timer,HRTIMER_STATE_MIGRATE ,0 ); + + is_pinned = timer->state &HRTIMER_STATE_PINNED ; + +/* Check if CPU still has pinned timers */ +if (unlikely (WARN (is_pinned, +"%s: can't migrate pinned timer: %p, deactivating it\n" , + __func__, timer))) +continue ; + timer->base = new_base;/* * Enqueue the timers on the new cpu. This does not
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 6/8 hrtimer: create hrtimer_quiesce_cpu() to isolate CPU from hrtimers
In reply to Viresh KumarTo isolate CPUs (isolate from hrtimers) from sysfs using cpusets, we need some support from the hrtimer core. i.e. A routine hrtimer_quiesce_cpu() which would migrate away all the unpinned hrtimers, but shouldn't touch the pinned ones.
This patch creates this routine.
--- include/linux/hrtimer.h | 3 +++ kernel/hrtimer.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 42 insertions(+), 8 deletions(-)
include/linux/hrtimer.h +3 -0
@@ -350,6 +350,9 @@ DECLARE_PER_CPU(struct tick_device, tick_cpu_device);/* Exported timer functions: */ +/* To be used from cpusets, only */ +extern void hrtimer_quiesce_cpu (void *cpup); +/* Initialize timers: */ extern void hrtimer_init (struct hrtimer *timer,clockid_t which_clock,enum hrtimer_mode mode);
kernel/hrtimer.c +39 -8
96 lines not on this page · raw message
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 7/8 cpuset: Create sysfs file: cpusets.quiesce to isolate CPUs
In reply to Viresh KumarFor networking applications, platforms need to provide one CPU per each user space data plane thread. These CPUs shouldn't be interrupted by kernel at all unless userspace has requested for some functionality. Currently, there are background kernel activities that are running on almost every CPU, like:
timers/hrtimers/watchdogs/etc, and these are required to be migrated to other CPUs.
To achieve that, this patch adds another option to cpusets, i.e. 'quiesce'. Writing '1' on this file would migrate these unbound/unpinned timers/hrtimers away from the CPUs of the cpuset in question. Also it would disallow addition of any new unpinned timers/hrtimers to isolated CPUs (This would be handled in next patch). Writing '0' will disable isolation of CPUs in current cpuset and unpinned timers/hrtimers would be allowed in future on these CPUs.
Currently, only timers and hrtimers are migrated. This would be followed by other kernel infrastructure later if required.
--- Documentation/cgroups/cpusets.txt | 19 ++++++++-- include/linux/cpuset.h | 8 +++++ kernel/cpuset.c | 76 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 101 insertions(+), 2 deletions(-)
Documentation/cgroups/cpusets.txt +17 -2
@@ -22,7 +22,8 @@ CONTENTS: 1.6 What is memory spread ? 1.7 What is sched_load_balance ? 1.8 What is sched_relax_domain_level ? - 1.9 How do I use cpusets ? + 1.9 What is quiesce? + 1.10 How do I use cpusets ? 2. Usage Examples and Syntax 2.1 Basic Usage 2.2 Adding/removing cpus
@@ -581,7 +582,21 @@ If your situation is: then increasing 'sched_relax_domain_level' would benefit you. -1.9 How do I use cpusets ? +1.9 What is quiesce ? +-------------------------------------- +We need to migrate away all the background kernel activities (Unbound) for +systems requiring isolation of cores (HPC, Real time, networking, etc). After +creating cpusets, you can write 1 or 0 to cpuset.quiesce file. + +Writing '1': on this file would migrate unbound/unpinned timers and hrtimers +away from the CPUs of the cpuset in question. Also it would disallow addition of +any new unpinned timers & hrtimers to isolated CPUs. + +Writing '0': will disable isolation of CPUs in current cpuset and unpinned +timers/hrtimers would be allowed in future on these CPUs. + + +1.10 How do I use cpusets ? -------------------------- In order to minimize the impact of cpusets on critical kernel
include/linux/cpuset.h +8 -0
@@ -15,6 +15,13 @@#ifdef CONFIG_CPUSETS +extern cpumask_var_t cpuset_quiesced_cpus_mask; + +static inline bool cpu_quiesced (int cpu) +{ +return cpumask_test_cpu (cpu, cpuset_quiesced_cpus_mask); +} +extern int number_of_cpusets;/* How many cpusets are defined in system? */ extern int cpuset_init (void );
@@ -123,6 +130,7 @@ static inline void set_mems_allowed(nodemask_t nodemask)#else /* !CONFIG_CPUSETS */ +static inline bool cpu_quiesced (int cpu) {return 0 ; }static inline int cpuset_init (void ) {return 0 ; }static inline void cpuset_init_smp (void ) {}
kernel/cpuset.c +76 -0
140 lines not on this page · raw message
Signature · 1 line
1.7.12.rc2.18.g61b472e
PATCH v2 8/8 sched: don't queue timers on quiesced CPUs
In reply to Viresh KumarCPUSets have cpusets.quiesce sysfs file now, with which some CPUs can opt for isolating themselves from background kernel activities, like: timers & hrtimers.
get_nohz_timer_target() is used for finding suitable CPU for firing a timer. To guarantee that new timers wouldn't be queued on quiesced CPUs, we need to modify this routine.
--- kernel/sched/core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
kernel/sched/core.c +5 -4
@@ -557,17 +557,18 @@ void resched_cpu(int cpu)*/ int get_nohz_timer_target (int pinned) { -int cpu =smp_processor_id (); -int i; +int cpu =smp_processor_id (), i;struct sched_domain *sd; -if (pinned || !get_sysctl_timer_migration () || !idle_cpu (cpu)) +if (pinned || !get_sysctl_timer_migration () || + !(idle_cpu (cpu) ||cpu_quiesced (cpu)))return cpu;rcu_read_lock ();for_each_domain (cpu, sd) {for_each_cpu (i,sched_domain_span (sd)) { -if (!idle_cpu (i)) { +/* Don't push timers to quiesced CPUs */ +if (!(cpu_quiesced (i) ||idle_cpu (i))) { cpu = i; goto unlock; }
Signature · 1 line
1.7.12.rc2.18.g61b472e
Quoted 3 lines · Viresh Kumar
We need to migrate away all the background kernel activities (Unbound) for systems requiring isolation of cores (HPC, Real time, networking, etc). After creating cpusets, you can write 1 or 0 to cpuset.quiesce file.
I wonder if adding a quiesce switch is really necessary.
Seems to me that if you don't have load balancing turned off, you can't be very concerned about perturbation, so this should be tied into the load balancing on/off switch as an extension to isolating cores from the #1 perturbation source, the scheduler.
I also didn't notice a check for is_cpu_exclusive() at a glance, which would be a bug, but one that would go away if this additional isolation were coupled to the existing isolation switch.
-Mike
Hi Mike,
Quoted 6 lines · Mike Galbraith
I wonder if adding a quiesce switch is really necessary.
Seems to me that if you don't have load balancing turned off, you can't be very concerned about perturbation, so this should be tied into the load balancing on/off switch as an extension to isolating cores from the #1 perturbation source, the scheduler.
Its more about not doing any background activities on these CPU which can be avoided. So, even if a add_timer() is issued from these isolated CPUs, it should goto the set chosen for doing background activity, unless add_timer_on() has been issued, in which case user wants that code to execute on the isolated core.
Probably, yes, people would be disabling load_balancing between these cpusets to avoid migration of tasks to isolated core as well.. Atleast we are using it :)
Quoted 3 lines
I also didn't notice a check for
is_cpu_exclusive()at a glance, which would be a bug, but one that would go away if this additional isolation were coupled to the existing isolation switch.
Yeah, there is no check for that. But I didn't got your point completely. Why do I need to check for exclusivity on the isolated CPUs? So, that same CPU isn't isolated as well as non-isolated on two separate sets?
Thanks for your feedback.
--
viresh
Quoted 16 lines · Viresh Kumar
Hi Mike,
Quoted 6 lines · Mike Galbraith
I wonder if adding a quiesce switch is really necessary.
Seems to me that if you don't have load balancing turned off, you can't be very concerned about perturbation, so this should be tied into the load balancing on/off switch as an extension to isolating cores from the #1 perturbation source, the scheduler.
Its more about not doing any background activities on these CPU which can be avoided. So, even if a
add_timer()is issued from these isolated CPUs, it should goto the set chosen for doing background activity, unlessadd_timer_on()has been issued, in which case user wants that code to execute on the isolated core.
Quoted 3 lines
Probably, yes, people would be disabling
load_balancingbetween these cpusets to avoid migration of tasks to isolated core as well.. Atleast we are using it :)
Yes, that's the whole point I'm trying to make. If you do not have cores isolated, there's no point to quiesce, as timers and whatnot are the least of your worries. Conversely, why would you bother isolating cores if you didn't want a nice quiet environment. Seems to me full isolation ala killing sched domains implies that your goal is bare metal.. or as close as you can get to that anyway.
Quoted 7 lines
Quoted 3 lines
I also didn't notice a check for
is_cpu_exclusive()at a glance, which would be a bug, but one that would go away if this additional isolation were coupled to the existing isolation switch.Yeah, there is no check for that. But I didn't got your point completely. Why do I need to check for exclusivity on the isolated CPUs? So, that same CPU isn't isolated as well as non-isolated on two separate sets?
Yes, both on and off is kinda hard to do per cpu :)
-Mike
Quoted 1 line · Mike Galbraith
Yes, both on and off is kinda hard to do per cpu :)
Correct.. would get it fixed in V3..