question on sched-rt group allocation cap: sched_rt_runtime_us
Subsystems (4)
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 10 lines · Lucas De Marchi
Indeed. I've tested this same test program in a single core machine and it produces the expected behavior:
rt_runtime_us/rt_period_us% loops executed inSCHED_OTHER95% 4.48%
60% 54.84%
50% 86.03%
40% OTHER completed first
Hmm. This does seem to indicate that there is some kind of relationship with SMP. So I wonder whether there is a way to turn this 'RT bandwidth accumulation' heuristic off. I did an
echo 0 > /proc/sys/kernel/sched_migration_cost
but results were identical to previous.
I figure that if I set it to zero, the regular sched-fair (non-RT) tasks will be treated as not being cache hot and hence susceptible to migration. From the code it looks like sched-rt tasks are always treated as cache cold? Mind you though that I have not yet looked into the code very rigorously. I knew the O(1) scheduler relatively well, but I am just begun digging into the new CFS scheduler code.
On a side note, why is there no documentation explain the sched_migration_cost tuning knob? It would be nice to have one - at least where the sysctl variable is defined.
--Ani
Quoted 12 lines · Ani
Quoted 10 lines · Lucas De Marchi
Indeed. I've tested this same test program in a single core machine and it produces the expected behavior:
rt_runtime_us / rt_period_us % loops executed in SCHED_OTHER 95% 4.48% 60% 54.84% 50% 86.03% 40% OTHER completed first
Quoted 3 lines
Hmm. This does seem to indicate that there is some kind of relationship with SMP. So I wonder whether there is a way to turn this 'RT bandwidth accumulation' heuristic off.
No there isn't, but maybe there should be, since this isn't the first time it's come up. One pro argument is that pinned tasks are thoroughly screwed when an RT hog lands on their runqueue. On the con side, the whole RT bandwidth restriction thing is intended (AFAIK) to allow an admin to regain control should RT app go insane, which the default 5% aggregate accomplishes just fine.
Dunno. Fly or die little patchlet (toss).
sched: allow the user to disable RT bandwidth aggregation.
LKML-Reference: <new-submission>
include/linux/sched.h +1 -0
@@ -1881,6 +1881,7 @@ static inline unsigned int get_sysctl_timer_migration(void)#endif extern unsigned int sysctl_sched_rt_period;extern int sysctl_sched_rt_runtime; +extern int sysctl_sched_rt_bandwidth_aggregate; int sched_rt_handler(struct ctl_table *table, int write, struct file *filp, void __user *buffer, size_t *lenp,
kernel/sched.c +6 -0
@@ -864,6 +864,12 @@ static __read_mostly int scheduler_running;*/ int sysctl_sched_rt_runtime =950000 ; +/* +* aggregate bandwidth, ie allow borrowing from neighbors when +* bandwidth for an individual runqueue is exhausted. +*/ +int sysctl_sched_rt_bandwidth_aggregate =1 ; +static inline u64 global_rt_period (void ) {return (u64 )sysctl_sched_rt_period *NSEC_PER_USEC ;
kernel/sched_rt.c +3 -0
@@ -495,6 +495,9 @@ static int balance_runtime(struct rt_rq *rt_rq) {int more =0 ; +if (!sysctl_sched_rt_bandwidth_aggregate) +return 0 ; +if (rt_rq->rt_time > rt_rq->rt_runtime) {spin_unlock (&rt_rq->rt_runtime_lock); more =do_balance_runtime (rt_rq);
kernel/sysctl.c +8 -0
@@ -368,6 +368,14 @@ static struct ctl_table kern_table[] = { }, { .ctl_name = CTL_UNNUMBERED, + .procname = "sched_rt_bandwidth_aggregate", + .data = &sysctl_sched_rt_bandwidth_aggregate, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &sched_rt_handler, + }, + { + .ctl_name = CTL_UNNUMBERED, .procname = "sched_compat_yield", .data = &sysctl_sched_compat_yield, .maxlen = sizeof(unsigned int),
Quoted 17 lines · Mike Galbraith
Quoted 12 lines · Ani
Quoted 10 lines · Lucas De Marchi
Indeed. I've tested this same test program in a single core machine and it produces the expected behavior:
rt_runtime_us / rt_period_us % loops executed in SCHED_OTHER 95% 4.48% 60% 54.84% 50% 86.03% 40% OTHER completed firstQuoted 3 lines
Hmm. This does seem to indicate that there is some kind of relationship with SMP. So I wonder whether there is a way to turn this 'RT bandwidth accumulation' heuristic off.
Quoted 8 lines
No there isn't, but maybe there should be, since this isn't the first time it's come up. One pro argument is that pinned tasks are thoroughly screwed when an RT hog lands on their runqueue. On the con side, the whole RT bandwidth restriction thing is intended (AFAIK) to allow an admin to regain control should RT app go insane, which the default 5% aggregate accomplishes just fine.
Dunno. Fly or die little patchlet (toss).
btw, a _kinda sorta_ pro is that it can prevent IO lockups like the below. Seems kjournald can end up depending on kblockd/3, which ain't going anywhere with that 100% RT hog in the way, so the whole box is fairly hosed. (much better would be to wake some other kblockd)
top - 12:01:49 up 56 min, 20 users, load average: 8.01, 4.96, 2.39
Tasks: 304 total, 4 running, 300 sleeping, 0 stopped, 0 zombie
Cpu(s): 25.8%us, 0.3%sy, 0.0%ni, 0.0%id, 73.7%wa, 0.3%hi, 0.0%si, 0.0%st
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ P COMMAND 13897 root -2 0 7920 592 484 R 100 0.0 1:13.43 3 xx 12716 root 20 0 8868 1328 860 R 1 0.0 0:01.44 0 top 14 root 15 -5 0 0 0 R 0 0.0 0:00.02 3 events/3 94 root 15 -5 0 0 0 R 0 0.0 0:00.00 3 kblockd/3 1212 root 15 -5 0 0 0 D 0 0.0 0:00.04 2 kjournald 14393 root 20 0 9848 2296 756 D 0 0.1 0:00.01 0 make 14404 root 20 0 38012 25m 5552 D 0 0.8 0:00.21 1 cc1 14405 root 20 0 20220 8852 2388 D 0 0.3 0:00.02 1 as 14437 root 20 0 24132 10m 2680 D 0 0.3 0:00.06 2 cc1 14448 root 20 0 18324 1724 1240 D 0 0.1 0:00.00 2 cc1 14452 root 20 0 12540 792 656 D 0 0.0 0:00.00 2 mv
A message that is not in the archive (sent off-list or not yet received): DDFD17CC94A9BD49A82147DDF7D545C54DC482@exchange.ZeugmaSystems.local
Quoted 8 lines · Anirban Sinha
Quoted 5 lines
Seems kjournald can end up depending on kblockd/3, which ain't going anywhere with that 100% RT hog in the way,
I think in the past AKPM's response to this has been "just don't do it", i.e, don't hog the CPU with an RT thread.
Oh yeah, sure. Best to run RT oinkers on isolated cpus. It just surprised me that the 100% compute RT cpu became involved in IO.
-Mike
Quoted 11 lines · Mike Galbraith
Quoted 8 lines · Anirban Sinha
Quoted 5 lines
Seems kjournald can end up depending on kblockd/3, which ain't going anywhere with that 100% RT hog in the way,
I think in the past AKPM's response to this has been "just don't do it", i.e, don't hog the CPU with an RT thread.
Oh yeah, sure. Best to run RT oinkers on isolated cpus.
Correct. Unfortunately at some places, the application coders do stupid things and then the onus falls on the kernel guys to make things 'just work'.
I would not have any problems if such a cap mechanism did not exist at all. However, since we do have such a tuning knob. I would say that let's make it do what it is supposed to do. In the documentation it says "0.05s to be used by SCHED_OTHER". Unfortunately, it never hints that if your thread is tied to the RT core, you are screwed. The bandwidth accumulation logic would virtually kill all the remaining SCHED_OTHER threads, much before that 95% cap is reached. Somewhere it doesn't quite seem right. At the very very least, can we have this clearly written in sched-rt-group.txt?
Cheers,
Ani
A message that is not in the archive (sent off-list or not yet received): [email protected]
RFC 1/1 lru_add_drain_all() vs isolation
Quoted 11 lines · Mike Galbraith
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10
Quoted 8 lines
[ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1b
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also flush_workqueue().
--- include/linux/workqueue.h | 1 + kernel/workqueue.c | 52 +++++++++++++++++++++++++++++++++++--------- mm/swap.c | 14 ++++++++--- 3 files changed, 52 insertions(+), 15 deletions(-)
include/linux/workqueue.h +1 -0
@@ -213,6 +213,7 @@ extern int schedule_work_on(int cpu, struct work_struct *work);extern int schedule_delayed_work (struct delayed_work *work,unsigned long delay);extern int schedule_delayed_work_on (int cpu,struct delayed_work *work,unsigned long delay); +extern int schedule_on_mask (const struct cpumask *mask,work_func_t func);extern int schedule_on_each_cpu (work_func_t func);extern int current_is_keventd (void );extern int keventd_up (void );
kernel/workqueue.c +41 -11
76 lines not on this page · raw message
mm/swap.c +10 -4
@@ -36,6 +36,7 @@/* How many pages do we try to swap or page in/out together? */ int page_cluster; +static cpumask_t lru_drain_mask; static DEFINE_PER_CPU(struct pagevec[NR_LRU_LISTS], lru_add_pvecs); static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs);
@@ -216,12 +217,15 @@ EXPORT_SYMBOL(mark_page_accessed);void __lru_cache_add (struct page *page,enum lru_list lru) { -struct pagevec *pvec = &get_cpu_var (lru_add_pvecs)[lru]; +int cpu =get_cpu (); +struct pagevec *pvec = &per_cpu (lru_add_pvecs, cpu)[lru]; + +cpumask_set_cpu (cpu, lru_drain_mask);page_cache_get (page);if (!pagevec_add (pvec, page))____pagevec_lru_add (pvec, lru); -put_cpu_var (lru_add_pvecs); +put_cpu (); }/**
@@ -294,7 +298,9 @@ static void drain_cpu_pagevecs(int cpu)void lru_add_drain (void ) { -drain_cpu_pagevecs (get_cpu ()); +int cpu =get_cpu (); +cpumask_clear_cpu (cpu, lru_drain_mask); +drain_cpu_pagevecs (cpu);put_cpu (); }
@@ -308,7 +314,7 @@ static void lru_add_drain_per_cpu(struct work_struct *dummy)*/ int lru_add_drain_all (void ) { -return schedule_on_each_cpu (lru_add_drain_per_cpu); +return schedule_on_mask (lru_drain_mask, lru_add_drain_per_cpu); }/*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 23 lines · Peter Zijlstra
Quoted 11 lines · Mike Galbraith
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10Quoted 8 lines
[ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1b
Quoted 4 lines
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also
flush_workqueue().
Failed to google the previous discussion. Could you please point me? What is the problem?
kernel/workqueue.c int schedule_delayed_work_on(int cpu, · line 665
Quoted 6 lines
kernel/workqueue.c +6
-0+struct sched_work_struct { +struct work_struct work; +work_func_t func; +atomic_t *count; +struct completion *completion; +};
(not that it matters, but perhaps sched_work_struct should have a single
pointer to the struct which contains func,count,comletion).
kernel/workqueue.c EXPORT_SYMBOL(schedule_delayed_work_on); · line 686
Quoted 2 lines
kernel/workqueue.c +1
-1-int schedule_on_each_cpu (work_func_t func) +int schedule_on_mask (const struct cpumask *mask,work_func_t func)
Looks like a usefule helper. But,
kernel/workqueue.c EXPORT_SYMBOL(schedule_delayed_work_on); · line 704
Quoted 10 lines
kernel/workqueue.c +7
-2+for_each_cpu (cpu, mask) { +struct sched_work_struct *work =per_cpu_ptr (works, cpu); + work->count = &count; + work->completion = &completion; + work->func = func; -INIT_WORK (work, func); -schedule_work_on (cpu, work); +INIT_WORK (&work->work, do_sched_work); +schedule_work_on (cpu, &work->work);
This means the caller must ensure CPU online and can't go away. Otherwise we can hang forever.
schedule_on_each_cpu() is fine, it calls us under get_online_cpus(). But,
mm/swap.c static void lru_add_drain_per_cpu(struct work_struct *dummy) · line 318
Quoted 5 lines
int
lru_add_drain_all(void)
{mm/swap.c +1
-1-return schedule_on_each_cpu (lru_add_drain_per_cpu); +return schedule_on_mask (lru_drain_mask, lru_add_drain_per_cpu); }
This doesn't look safe.
Looks like, schedule_on_mask() should take get_online_cpus(), do cpus_and(mask, mask, online_cpus), then schedule works.
If we don't care the work can migrate to another CPU, schedule_on_mask() can do put_online_cpus() before wait_for_completion().
Oleg.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 24 lines · Oleg Nesterov
Quoted 23 lines · Peter Zijlstra
Quoted 19 lines · Mike Galbraith
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1b
Quoted 7 lines
Quoted 4 lines
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also
flush_workqueue().Failed to google the previous discussion. Could you please point me? What is the problem?
Ah, the general problem is that when we carve up the machine into partitions using cpusets, we still get machine wide tickles on all cpus from workqueue stuff like schedule_on_each_cpu() and flush_workqueue(), even if some cpus don't actually used their workqueue.
So the below limits lru_add_drain() activity to cpus that actually have pages in their per-cpu lists.
flush_workqueue() could limit itself to cpus that had work queued since the last flush_workqueue() invocation, etc.
This avoids un-needed disruption of these cpus.
Christoph wants this because he's running cpu-bound userspace and simply doesn't care to donate a few cycles to the kernel maintenance when not needed (every tiny bit helps in completing the HPC job sooner).
Mike ran into this because he's starving a partitioned cpu using an RT task -- which currently starves the other cpus because the workqueues don't get to run and everybody waits...
The lru_add_drain_all() thing is just one of the many cases, and the below won't fully solve Mike's problem since the cpu could still have pending work on the per-cpu list from starting the RT task.. but its showing the direction on how improve things.
Quoted 9 lines
kernel/workqueue.c int schedule_delayed_work_on(int cpu, · line 665
Quoted 6 lines
kernel/workqueue.c +6
-0+struct sched_work_struct { +struct work_struct work; +work_func_t func; +atomic_t *count; +struct completion *completion; +};(not that it matters, but perhaps
sched_work_structshould have a single
pointer to the struct which contains func,count,comletion).
Sure, it more-or-less grew while writing, I always forget completions don't count.
Quoted 30 lines
kernel/workqueue.c EXPORT_SYMBOL(schedule_delayed_work_on); · line 686
Quoted 2 lines
kernel/workqueue.c +1
-1-int schedule_on_each_cpu (work_func_t func) +int schedule_on_mask (const struct cpumask *mask,work_func_t func)Looks like a usefule helper. But,
kernel/workqueue.c EXPORT_SYMBOL(schedule_delayed_work_on); · line 704
Quoted 10 lines
kernel/workqueue.c +7
-2+for_each_cpu (cpu, mask) { +struct sched_work_struct *work =per_cpu_ptr (works, cpu); + work->count = &count; + work->completion = &completion; + work->func = func; -INIT_WORK (work, func); -schedule_work_on (cpu, work); +INIT_WORK (&work->work, do_sched_work); +schedule_work_on (cpu, &work->work);This means the caller must ensure CPU online and can't go away. Otherwise we can hang forever.
schedule_on_each_cpu()is fine, it calls us underget_online_cpus(). But,mm/swap.c static void lru_add_drain_per_cpu(struct work_struct *dummy) · line 318
Quoted 5 lines
int
lru_add_drain_all(void)
{mm/swap.c +1
-1-return schedule_on_each_cpu (lru_add_drain_per_cpu); +return schedule_on_mask (lru_drain_mask, lru_add_drain_per_cpu); }This doesn't look safe.
Quoted 5 lines
Looks like,
schedule_on_mask()should takeget_online_cpus(), docpus_and(mask, mask, online_cpus), then schedule works.If we don't care the work can migrate to another CPU,
schedule_on_mask()can doput_online_cpus()beforewait_for_completion().
Ah, right. Like said, I only quickly hacked this up as an example on how to improve isolation between cpus and limit unneeded work in the hope someone would pick this up and maybe tackle other sites as well.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 6 lines · Peter Zijlstra
Quoted 3 lines · Oleg Nesterov
Failed to google the previous discussion. Could you please point me? What is the problem?
Quoted 7 lines
Ah, the general problem is that when we carve up the machine into partitions using cpusets, we still get machine wide tickles on all cpus from workqueue stuff like
schedule_on_each_cpu()andflush_workqueue(), even if some cpus don't actually used their workqueue.So the below limits
lru_add_drain()activity to cpus that actually have pages in their per-cpu lists.
Thanks Peter!
Quoted 2 lines
flush_workqueue()could limit itself to cpus that had work queued since the lastflush_workqueue()invocation, etc.
But "work queued since the last flush_workqueue() invocation" just means "has work queued". Please note that flush_cpu_workqueue() does nothing if there are no works, except it does lock/unlock of cwq->lock.
IIRC, flush_cpu_workqueue() has to lock/unlock to avoid the races with CPU hotplug, but _perhaps_ flush_workqueue() can do the check lockless.
Afaics, we can add the workqueue_struct->cpu_map_has_works to help flush_workqueue(), but this means we should complicate insert_work() and run_workqueue() which should set/clear the bit. But given that flush_workqueue() should be avoided anyway, I am not sure.
Oleg.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 7 lines · Oleg Nesterov
Quoted 2 lines
flush_workqueue()could limit itself to cpus that had work queued since the lastflush_workqueue()invocation, etc.But "work queued since the last
flush_workqueue()invocation" just means "has work queued". Please note thatflush_cpu_workqueue()does nothing if there are no works, except it does lock/unlock ofcwq->lock.
Quoted 7 lines
IIRC,
flush_cpu_workqueue()has to lock/unlock to avoid the races with CPU hotplug, but _perhaps_flush_workqueue()can do the check lockless.Afaics, we can add the
workqueue_struct->cpu_map_has_worksto helpflush_workqueue(), but this means we should complicateinsert_work()andrun_workqueue()which should set/clear the bit. But given thatflush_workqueue()should be avoided anyway, I am not sure.
Ah, indeed. Then nothing new would be needed here, since it will indeed not interrupt processing on the remote cpus that never queued any work.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
In reply to Peter ZijlstraHi Peter,
Quoted 22 lines · Mike Galbraith
Quoted 12 lines
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10Quoted 8 lines
[ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1b
Quoted 4 lines
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also
flush_workqueue().
Can you please explain reproduce way and problem detail?
AFAIK, mlock() call lru_add_drain_all() _before_ grab semaphoe. Then, it doesn't cause any deadlock.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 29 lines · KOSAKI Motohiro
Hi Peter,
Quoted 22 lines · Mike Galbraith
Quoted 12 lines
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10Quoted 8 lines
[ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1bQuoted 4 lines
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also
flush_workqueue().
Quoted 4 lines
Can you please explain reproduce way and problem detail?
AFAIK,
mlock()calllru_add_drain_all()_before_ grab semaphoe. Then, it doesn't cause any deadlock.
Suppose you have 2 cpus, cpu1 is busy doing a SCHED_FIFO-99 while(1), cpu0 does mlock()->lru_add_drain_all(), which does schedule_on_each_cpu(), which then waits for all cpus to complete the work. Except that cpu1, which is busy with the RT task, will never run keventd until the RT load goes away.
This is not so much an actual deadlock as a serious starvation case.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 35 lines · KOSAKI Motohiro
Quoted 29 lines
Hi Peter,
Quoted 22 lines · Mike Galbraith
Quoted 12 lines
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10Quoted 8 lines
[ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1bQuoted 4 lines
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also
flush_workqueue().Quoted 4 lines
Can you please explain reproduce way and problem detail?
AFAIK,
mlock()calllru_add_drain_all()_before_ grab semaphoe. Then, it doesn't cause any deadlock.
Quoted 7 lines
Suppose you have 2 cpus, cpu1 is busy doing a SCHED_FIFO-99 while(1), cpu0 does mlock()->lru_add_drain_all(), which does
schedule_on_each_cpu(), which then waits for all cpus to complete the work. Except that cpu1, which is busy with the RT task, will never run keventd until the RT load goes away.This is not so much an actual deadlock as a serious starvation case.
This seems flush_work vs RT-thread problem, not only lru_add_drain_all(). Why other workqueue flusher doesn't affect this issue?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 41 lines · KOSAKI Motohiro
Quoted 41 lines · KOSAKI Motohiro
Quoted 29 lines
Hi Peter,
Quoted 22 lines · Mike Galbraith
Quoted 12 lines
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10Quoted 8 lines
[ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1bQuoted 4 lines
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also
flush_workqueue().Quoted 4 lines
Can you please explain reproduce way and problem detail?
AFAIK,
mlock()calllru_add_drain_all()_before_ grab semaphoe. Then, it doesn't cause any deadlock.Suppose you have 2 cpus, cpu1 is busy doing a SCHED_FIFO-99 while(1), cpu0 does mlock()->lru_add_drain_all(), which does
schedule_on_each_cpu(), which then waits for all cpus to complete the work. Except that cpu1, which is busy with the RT task, will never run keventd until the RT load goes away.
Quoted 4 lines
Quoted 1 line
This is not so much an actual deadlock as a serious starvation case.
This seems
flush_workvs RT-thread problem, not onlylru_add_drain_all(). Why other workqueue flusher doesn't affect this issue?
flush_work() will only flush workqueues on which work has been enqueued as Oleg pointed out.
The problem is with lru_add_drain_all() enqueueing work on all workqueues.
There is nothing that makes lru_add_drain_all() the only such site, its the one Mike posted to me, and my patch was a way to deal with that.
I also explained that its not only RT related in that the HPC folks also want to avoid unneeded work -- for them its not starvation but a performance issue.
In generic we should avoid doing work when there is no work to be done.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 44 lines · KOSAKI Motohiro
Quoted 43 lines
Quoted 42 lines · KOSAKI Motohiro
Quoted 29 lines
Hi Peter,
Quoted 22 lines · Mike Galbraith
Quoted 12 lines
[ 774.651779] SysRq : Show Blocked State [ 774.655770] task PC stack pid father [ 774.655770] evolution.bin D ffff8800bc1575f0 0 7349 6459 0x00000000 [ 774.676008] ffff8800bc3c9d68 0000000000000086 ffff8800015d9340 ffff8800bb91b780 [ 774.676008] 000000000000dd28 ffff8800bc3c9fd8 0000000000013340 0000000000013340 [ 774.676008] 00000000000000fd ffff8800015d9340 ffff8800bc1575f0 ffff8800bc157888 [ 774.676008] Call Trace: [ 774.676008] [<ffffffff812c4a11>] schedule_timeout+0x2d/0x20c [ 774.676008] [<ffffffff812c4891>] wait_for_common+0xde/0x155 [ 774.676008] [<ffffffff8103f1cd>] ? default_wake_function+0x0/0x14 [ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10Quoted 8 lines
[ 774.676008] [<ffffffff810c0e63>] ? lru_add_drain_per_cpu+0x0/0x10 [ 774.676008] [<ffffffff812c49ab>] wait_for_completion+0x1d/0x1f [ 774.676008] [<ffffffff8105fdf5>] flush_work+0x7f/0x93 [ 774.676008] [<ffffffff8105f870>] ? wq_barrier_func+0x0/0x14 [ 774.676008] [<ffffffff81060109>] schedule_on_each_cpu+0xb4/0xed [ 774.676008] [<ffffffff810c0c78>] lru_add_drain_all+0x15/0x17 [ 774.676008] [<ffffffff810d1dbd>] sys_mlock+0x2e/0xde [ 774.676008] [<ffffffff8100bc1b>] system_call_fastpath+0x16/0x1bQuoted 4 lines
FWIW, something like the below (prone to explode since its utterly untested) should (mostly) fix that one case. Something similar needs to be done for pretty much all machine wide workqueue thingies, possibly also
flush_workqueue().Quoted 4 lines
Can you please explain reproduce way and problem detail?
AFAIK,
mlock()calllru_add_drain_all()_before_ grab semaphoe. Then, it doesn't cause any deadlock.Suppose you have 2 cpus, cpu1 is busy doing a SCHED_FIFO-99 while(1), cpu0 does mlock()->lru_add_drain_all(), which does
schedule_on_each_cpu(), which then waits for all cpus to complete the work. Except that cpu1, which is busy with the RT task, will never run keventd until the RT load goes away.This is not so much an actual deadlock as a serious starvation case.
Quoted 8 lines
Quoted 2 lines
This seems
flush_workvs RT-thread problem, not onlylru_add_drain_all(). Why other workqueue flusher doesn't affect this issue?
flush_work()will only flush workqueues on which work has been enqueued as Oleg pointed out.The problem is with
lru_add_drain_all()enqueueing work on all workqueues.
Thank you for kindly explanation. I gradually become to understand this isssue. Yes, lru_add_drain_all() use schedule_on_each_cpu() and it have following code
for_each_online_cpu(cpu)
flush_work(per_cpu_ptr(works, cpu));However, I don't think your approach solve this issue. lru_add_drain_all() flush lru_add_pvecs and lru_rotate_pvecs.
lru_add_pvecs is accounted when
- lru move
e.g. read(2), write(2), page fault, vmscan, page migration, et al
lru_rotate_pves is accounted when
- page writeback
IOW, if RT-thread call write(2) syscall or page fault, we face the same problem. I don't think we can assume RT-thread don't make page fault....
hmm, this seems difficult problem. I guess any mm code should use schedule_on_each_cpu(). I continue to think this issue awhile.
Quoted 2 lines
There is nothing that makes
lru_add_drain_all()the only such site, its the one Mike posted to me, and my patch was a way to deal with that.
Well, schedule_on_each_cpu() is very limited used function. Practically we can ignore other caller.
Quoted 3 lines
I also explained that its not only RT related in that the HPC folks also want to avoid unneeded work -- for them its not starvation but a performance issue.
I think you talked about OS jitter issue. if so, I don't think this issue make serious problem. OS jitter mainly be caused by periodic action
(e.g. tick update, timer, vmstat update). it's because
little-delay x plenty-times = large-delay
lru_add_drain_all() is called from very limited point. e.g. mlock, shm-lock, page-migration, memory-hotplug. all caller is not periodic.
Quoted 1 line
In generic we should avoid doing work when there is no work to be done.
Probably. but I'm not sure ;)
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 13 lines · KOSAKI Motohiro
Thank you for kindly explanation. I gradually become to understand this isssue. Yes,
lru_add_drain_all()useschedule_on_each_cpu()and it have following codefor_each_online_cpu(cpu) flush_work(per_cpu_ptr(works, cpu));However, I don't think your approach solve this issue.
lru_add_drain_all()flushlru_add_pvecsandlru_rotate_pvecs.
lru_add_pvecsis accounted when
- lru move
e.g. read(2), write(2), page fault, vmscan, page migration, et al
Quoted 8 lines
lru_rotate_pvesis accounted when
- page writebackIOW, if RT-thread call write(2) syscall or page fault, we face the same problem. I don't think we can assume RT-thread don't make page fault....
hmm, this seems difficult problem. I guess any mm code should use
schedule_on_each_cpu(). I continue to think this issue awhile.
This is about avoiding work when there is non, clearly when an application does use the kernel it creates work.
But a clearly userspace, cpu-bound process, while(1), should not get interrupted by things like lru_add_drain() when it doesn't have any pages to drain.
Quoted 5 lines
Quoted 2 lines
There is nothing that makes
lru_add_drain_all()the only such site, its the one Mike posted to me, and my patch was a way to deal with that.Well,
schedule_on_each_cpu()is very limited used function. Practically we can ignore other caller.
No, we need to inspect all callers, having only a few makes that easier.
Quoted 11 lines
Quoted 3 lines
I also explained that its not only RT related in that the HPC folks also want to avoid unneeded work -- for them its not starvation but a performance issue.
I think you talked about OS jitter issue. if so, I don't think this issue make serious problem. OS jitter mainly be caused by periodic action
(e.g. tick update, timer, vmstat update). it's because
little-delay x plenty-times = large-delay
lru_add_drain_all()is called from very limited point. e.g. mlock, shm-lock, page-migration, memory-hotplug. all caller is not periodic.
Doesn't matter, if you want to reduce it, you need to address all of them, a process 4 nodes away calling mlock() while this partition has been user-bound for the last hour or so and doesn't have any lru pages simply needn't be woken.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 2 lines · Peter Zijlstra
This is about avoiding work when there is non, clearly when an application does use the kernel it creates work.
Hmmm. The lru draining in page migration is to reduce the number of pages that are not on the lru to increase the chance of page migration to be successful. A page on a per cpu list cannot be drained.
Reducing the number of cpus where we perform the drain results in increased likelyhood that we cannot migrate a page because its on the per cpu lists of a cpu not covered.
On the other hand if the cpu is offline then we know that it has no per cpu pages. That is why I found the idea of the OFFLINE scheduler attractive.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 5 lines · Christoph Lameter
Quoted 2 lines · Peter Zijlstra
This is about avoiding work when there is non, clearly when an application does use the kernel it creates work.
Quoted 7 lines
Hmmm. The lru draining in page migration is to reduce the number of pages that are not on the lru to increase the chance of page migration to be successful. A page on a per cpu list cannot be drained.
Reducing the number of cpus where we perform the drain results in increased likelyhood that we cannot migrate a page because its on the per cpu lists of a cpu not covered.
Did you even read the patch?
There is _no_ functional difference between before and after, except less wakeups on cpus that don't have any __lru_cache_add activity.
If there's pages on the per cpu lru_add_pvecs list it will be present in the mask and will be send a drain request. If its not, then it won't be send.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 6 lines · Peter Zijlstra
There is _no_ functional difference between before and after, except less wakeups on cpus that don't have any
__lru_cache_addactivity.If there's pages on the per cpu
lru_add_pvecslist it will be present in the mask and will be send a drain request. If its not, then it won't be send.
Ok I see.
A global cpu mask like this will cause cacheline bouncing. After all this is a hot cpu path. Maybe do not set the bit if its already set (which may be very frequent)? Then add some benchmarks to show that it does not cause a regression on a 16p box (Nehalem) or so?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 9 lines · Christoph Lameter
Quoted 6 lines · Peter Zijlstra
There is _no_ functional difference between before and after, except less wakeups on cpus that don't have any
__lru_cache_addactivity.If there's pages on the per cpu
lru_add_pvecslist it will be present in the mask and will be send a drain request. If its not, then it won't be send.
Quoted 6 lines
Ok I see.
A global cpu mask like this will cause cacheline bouncing. After all this is a hot cpu path. Maybe do not set the bit if its already set (which may be very frequent)? Then add some benchmarks to show that it does not cause a regression on a 16p box (Nehalem) or so?
Yeah, testing the bit before poking at is sounds like a good plan.
Unless someone feels inclined to finish this and audit the kernel for more such places, I'll stick it on the ever growing todo pile.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
In reply to Christoph LameterThe usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code without system interaction.
2. There are repeated VM activities that require page isolation / migration.
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code without system interaction.
2. There are repeated VM activities that require page isolation / migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need lru_add_drain_all() as synchronous, because page migration have 10 times retry.
Then asynchronous lru_add_drain_all() cause
- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.
I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
What do you think?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 3 lines · KOSAKI Motohiro
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.
True this is only an optimization that increases the chance of isolation being successful. You dont need draining at all.
Quoted 8 lines
Then asynchronous
lru_add_drain_all()cause- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
What do you think?
The retries can be very fast if the migrate pages list is small. The migrate attempts may be finished before the IPI can be processed by the other cpus.
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 14 lines · KOSAKI Motohiro
Quoted 4 lines
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.True this is only an optimization that increases the chance of isolation being successful. You dont need draining at all.
Quoted 5 lines
Then asynchronous
lru_add_drain_all()cause- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.
Quoted 7 lines
Quoted 3 lines
I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
What do you think?
The retries can be very fast if the migrate pages list is small. The migrate attempts may be finished before the IPI can be processed by the other cpus.
Ah, I see. Yes, my last proposal is not good. small migration might be fail.
How about this?
- pass 1-2, lru_add_drain_all_async()
- pass 3-10, lru_add_drain_all()
this scheme might save RT-thread case and never cause regression. (I think)
The last remain problem is, if RT-thread binding cpu's pagevec has migrate targetted page, migration still face the same issue.
but we can't solve it...
RT-thread must use /proc/sys/vm/drop_caches properly.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 5 lines · KOSAKI Motohiro
How about this?
- pass 1-2,lru_add_drain_all_async()
- pass 3-10,lru_add_drain_all()this scheme might save RT-thread case and never cause regression. (I think)
Sounds good.
Quoted 4 lines
The last remain problem is, if RT-thread binding cpu's pagevec has migrate targetted page, migration still face the same issue.
but we can't solve it...
RT-thread must use/proc/sys/vm/drop_cachesproperly.
A system call "sys_os_quiet_down" may be useful. It would drain all caches, fold counters etc etc so that there will be no OS activities needed for those things later.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
In reply to KOSAKI MotohiroQuoted 20 lines · KOSAKI Motohiro
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code without system interaction.
2. There are repeated VM activities that require page isolation / migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.
Quoted 6 lines
Then asynchronous
lru_add_drain_all()cause- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
I think, more exactly, we don't have to drain lru pages for mlocking. Mlocked pages will go into unevictable lru due to try_to_unmap when shrink of lru happens.
How about removing draining in case of mlock?
Quoted 10 lines
What do you think?
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Signature · 2 lines
Kind regards, Minchan Kim
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 27 lines · Minchan Kim
Quoted 25 lines · KOSAKI Motohiro
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code without system interaction.
2. There are repeated VM activities that require page isolation / migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.Then asynchronous
lru_add_drain_all()cause- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.
Quoted 9 lines
Quoted 1 line
I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
I think, more exactly, we don't have to drain lru pages for mlocking. Mlocked pages will go into unevictable lru due to
try_to_unmapwhen shrink of lru happens.
How about removing draining in case of mlock?Quoted 2 lines
What do you think?
Remember how the code works: __mlock_vma_pages_range() loops calliing get_user_pages() to fault in batches of 16 pages and returns the page pointers for mlocking. Mlocking now requires isolation from the lru. If you don't drain after each call to get_user_pages(), up to a pagevec's worth of pages [~14] will likely still be in the pagevec and won't be isolatable/mlockable(). We can end up with most of the pages still on the normal lru lists. If we want to move to an almost exclusively lazy culling of mlocked pages to the unevictable then we can remove the drain. If we want to be more proactive in culling the unevictable pages as we populate the vma, we'll want to keep the drain.
Lee
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Hi, Lee.
Long time no see. :)
Quoted 39 lines · Lee Schermerhorn
Quoted 27 lines · Minchan Kim
Quoted 25 lines · KOSAKI Motohiro
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code without system interaction.
2. There are repeated VM activities that require page isolation / migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.Then asynchronous
lru_add_drain_all()cause- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.Quoted 9 lines
Quoted 1 line
I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
I think, more exactly, we don't have to drain lru pages for mlocking. Mlocked pages will go into unevictable lru due to
try_to_unmapwhen shrink of lru happens.
How about removing draining in case of mlock?Quoted 2 lines
What do you think?
Quoted 6 lines
Remember how the code works: __mlock_vma_pages_range() loops calliing
get_user_pages()to fault in batches of 16 pages and returns the page pointers for mlocking. Mlocking now requires isolation from the lru. If you don't drain after each call toget_user_pages(), up to a pagevec's worth of pages [~14] will likely still be in the pagevec and won't be isolatable/mlockable(). We can end up with most of the pages
Sorry for confusing.
I said not lru_add_drain but lru_add_drain_all.
Now problem is schedule_on_each_cpu.
Anyway, that case pagevec's worth of pages will be much increased by the number of CPU as you pointed out.
Quoted 5 lines
still on the normal lru lists. If we want to move to an almost exclusively lazy culling of mlocked pages to the unevictable then we can remove the drain. If we want to be more proactive in culling the unevictable pages as we populate the vma, we'll want to keep the drain.
It's not good that lazy culling of many pages causes high reclaim overhead. But now lazy culling of reclaim is doing just only shrink_page_list. we can do it shrink_active_list's page_referenced so that we can sparse cost of lazy culling.
Quoted 3 lines
Lee
Signature · 2 lines
Kind regards, Minchan Kim
Re: [rfc] lru_add_drain_all() vs isolation
In reply to Minchan KimQuoted 24 lines
Quoted 22 lines · KOSAKI Motohiro
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code without system interaction.
2. There are repeated VM activities that require page isolation / migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.Then asynchronous
lru_add_drain_all()cause
Quoted 8 lines
Quoted 4 lines
- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
I think, more exactly, we don't have to drain lru pages for mlocking. Mlocked pages will go into unevictable lru due to
try_to_unmapwhen shrink of lru happens.
Right.
Quoted 1 line
How about removing draining in case of mlock?
Umm, I don't like this. because perfectly no drain often make strange test result.
I mean /proc/meminfo::Mlock might be displayed unexpected value. it is not leak. it's only lazy cull. but many tester and administrator wiill think it's bug... ;)
Practically, lru_add_drain_all() is nearly zero cost. because mlock's page fault is very costly operation. it hide drain cost. now, we only want to treat corner case issue. I don't hope dramatic change.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 33 lines · On Thu, 10 Sep 2009 08:58:20 +0900 (JST) KOSAKI Motohiro…
Quoted 24 lines
Quoted 22 lines · KOSAKI Motohiro
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code without system interaction.
2. There are repeated VM activities that require page isolation / migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.Then asynchronous
lru_add_drain_all()causeQuoted 8 lines
Quoted 4 lines
- if system isn't under heavy pressure, retry succussfull.
- if system is under heavy pressure or RT-thread work busy busy loop, retry failure.I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
I think, more exactly, we don't have to drain lru pages for mlocking. Mlocked pages will go into unevictable lru due to
try_to_unmapwhen shrink of lru happens.
Quoted 7 lines
Right.
Quoted 1 line
How about removing draining in case of mlock?
Umm, I don't like this. because perfectly no drain often make strange test result.
I mean /proc/meminfo::Mlock might be displayed unexpected value. it is not leak. it's only lazy cull. but many tester and administrator wiill think it's bug... ;)
I agree. I have no objection to your approach. :)
Quoted 3 lines
Practically,
lru_add_drain_all()is nearly zero cost. because mlock's page fault is very costly operation. it hide drain cost. now, we only want to treat corner case issue. I don't hope dramatic change.
Another problem is as follow.
Although some CPUs don't have any thing to do, we do it. HPC guys don't want to consume CPU cycle as Christoph pointed out. I liked Peter's idea with regard to this.
My approach can solve it, too.
But I agree it would be dramatic change.
Signature · 2 lines
Kind regards, Minchan Kim
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 50 lines
Quoted 33 lines · On Thu, 10 Sep 2009 08:58:20 +0900 (JST) KOSAKI Motohiro…
Quoted 24 lines
Quoted 22 lines · KOSAKI Motohiro
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code A A without system interaction.
2. There are repeated VM activities that require page isolation / A A migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.Then asynchronous
lru_add_drain_all()causeQuoted 8 lines
Quoted 4 lines
A - if system isn't under heavy pressure, retry succussfull.
A - if system is under heavy pressure or RT-thread work busy busy loop, retry failure.I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
I think, more exactly, we don't have to drain lru pages for mlocking. Mlocked pages will go into unevictable lru due to
try_to_unmapwhen shrink of lru happens.Quoted 7 lines
Right.
Quoted 1 line
How about removing draining in case of mlock?
Umm, I don't like this. because perfectly no drain often make strange test result.
I mean /proc/meminfo::Mlock might be displayed unexpected value. it is not leak. it's only lazy cull. but many tester and administrator wiill think it's bug... ;)I agree. I have no objection to your approach. :)
Quoted 3 lines
Practically,
lru_add_drain_all()is nearly zero cost. because mlock's page fault is very costly operation. it hide drain cost. now, we only want to treat corner case issue. I don't hope dramatic change.
Quoted 7 lines
Another problem is as follow.
Although some CPUs don't have any thing to do, we do it. HPC guys don't want to consume CPU cycle as Christoph pointed out. I liked Peter's idea with regard to this.
My approach can solve it, too.
But I agree it would be dramatic change.
Is Perter's + mine approach bad?
It mean,
- RT-thread binding cpu is not grabbing the page
-> mlock successful by Peter's improvement - RT-thread binding cpu is grabbing the page -> mlock successful by mine approach the page is culled later.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
Quoted 52 lines · On Thu, 10 Sep 2009 10:15:07 +0900 (JST) KOSAKI Motohiro…
Quoted 52 lines
Quoted 33 lines · On Thu, 10 Sep 2009 08:58:20 +0900 (JST) KOSAKI Motohiro…
Quoted 24 lines
Quoted 22 lines · KOSAKI Motohiro
Quoted 8 lines
The usefulness of a scheme like this requires:
1. There are cpus that continually execute user space code A A without system interaction.
2. There are repeated VM activities that require page isolation / A A migration.
Quoted 7 lines
The first page isolation activity will then clear the lru caches of the processes doing number crunching in user space (and therefore the first isolation will still interrupt). The second and following isolation will then no longer interrupt the processes.
2. is rare. So the question is if the additional code in the LRU handling can be justified. If lru handling is not time sensitive then yes.
Christoph, I'd like to discuss a bit related (and almost unrelated) thing. I think page migration don't need
lru_add_drain_all()as synchronous, because page migration have 10 times retry.Then asynchronous
lru_add_drain_all()causeQuoted 8 lines
Quoted 4 lines
A - if system isn't under heavy pressure, retry succussfull.
A - if system is under heavy pressure or RT-thread work busy busy loop, retry failure.I don't think this is problematic bahavior. Also, mlock can use asynchrounous lru drain.
I think, more exactly, we don't have to drain lru pages for mlocking. Mlocked pages will go into unevictable lru due to
try_to_unmapwhen shrink of lru happens.Quoted 7 lines
Right.
Quoted 1 line
How about removing draining in case of mlock?
Umm, I don't like this. because perfectly no drain often make strange test result.
I mean /proc/meminfo::Mlock might be displayed unexpected value. it is not leak. it's only lazy cull. but many tester and administrator wiill think it's bug... ;)I agree. I have no objection to your approach. :)
Quoted 3 lines
Practically,
lru_add_drain_all()is nearly zero cost. because mlock's page fault is very costly operation. it hide drain cost. now, we only want to treat corner case issue. I don't hope dramatic change.Another problem is as follow.
Quoted 7 lines
Quoted 5 lines
Although some CPUs don't have any thing to do, we do it. HPC guys don't want to consume CPU cycle as Christoph pointed out. I liked Peter's idea with regard to this.
My approach can solve it, too.
But I agree it would be dramatic change.Is Perter's + mine approach bad?
It's good to me! :)
Quoted 11 lines
It mean,
- RT-thread binding cpu is not grabbing the page
-> mlock successful by Peter's improvement - RT-thread binding cpu is grabbing the page -> mlock successful by mine approach the page is culled later.
Signature · 8 lines
Kind regards, Minchan Kim -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
Re: [rfc] lru_add_drain_all() vs isolation
In reply to Peter ZijlstraHi
Quoted 22 lines
Quoted 13 lines
Thank you for kindly explanation. I gradually become to understand this isssue. Yes,
lru_add_drain_all()useschedule_on_each_cpu()and it have following codefor_each_online_cpu(cpu) flush_work(per_cpu_ptr(works, cpu));However, I don't think your approach solve this issue.
lru_add_drain_all()flushlru_add_pvecsandlru_rotate_pvecs.
lru_add_pvecsis accounted when
- lru move
e.g. read(2), write(2), page fault, vmscan, page migration, et alQuoted 8 lines
lru_rotate_pvesis accounted when
- page writebackIOW, if RT-thread call write(2) syscall or page fault, we face the same problem. I don't think we can assume RT-thread don't make page fault....
hmm, this seems difficult problem. I guess any mm code should use
schedule_on_each_cpu(). I continue to think this issue awhile.
Quoted 6 lines
This is about avoiding work when there is non, clearly when an application does use the kernel it creates work.
But a clearly userspace, cpu-bound process, while(1), should not get interrupted by things like
lru_add_drain()when it doesn't have any pages to drain.
Yup. makes sense.
So, I think you mean you'd like to tackle this special case as fist step, right? if yes, I agree.
Quoted 7 lines
Quoted 5 lines
Quoted 2 lines
There is nothing that makes
lru_add_drain_all()the only such site, its the one Mike posted to me, and my patch was a way to deal with that.Well,
schedule_on_each_cpu()is very limited used function. Practically we can ignore other caller.No, we need to inspect all callers, having only a few makes that easier.
Sorry my poor english. I meaned I don't oppose your patch approach. I don't oppose additional work at all.
Quoted 10 lines
Quoted 10 lines
Quoted 4 lines
I also explained that its not only RT related in that the HPC folks also want to avoid unneeded work -- for them its not starvation but a performance issue.
I think you talked about OS jitter issue. if so, I don't think this issue make serious problem. OS jitter mainly be caused by periodic action
(e.g. tick update, timer, vmstat update). it's because
little-delay x plenty-times = large-delay
Quoted 7 lines
Quoted 2 lines
lru_add_drain_all()is called from very limited point. e.g. mlock, shm-lock, page-migration, memory-hotplug. all caller is not periodic.Doesn't matter, if you want to reduce it, you need to address all of them, a process 4 nodes away calling
mlock()while this partition has been user-bound for the last hour or so and doesn't have any lru pages simply needn't be woken.
Doesn't matter? You mean can we stop to discuss hits HPC performance issue as Christoph pointed out?
hmmm, sorry, I haven't catch your point.
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
A message that is not in the archive (sent off-list or not yet received): DDFD17CC94A9BD49A82147DDF7D545C54DC483@exchange.ZeugmaSystems.local
A message that is not in the archive (sent off-list or not yet received): DDFD17CC94A9BD49A82147DDF7D545C54DC485@exchange.ZeugmaSystems.local
Quoted 4 lines
Dunno. Fly or die little patchlet (toss).
sched: allow the user to disable RT bandwidth aggregation.
Hmm. Interesting. With this change, my results are as follows:
rt_runtime/rt_period % of reg iterations
0.2 100% 0.25 100% 0.3 100% 0.4 100% 0.5 82% 0.6 66% 0.7 54% 0.8 46% 0.9 38.5% 0.95 32%
This results are on a quad core blade. Does it still makes sense though? Can anyone else run the same tests on a quadcore over the latest kernel? I will patch our 2.6.26 kernel with upstream fixes and rerun these tests on tuesday.
Ani
Quoted 22 lines · Anirban Sinha
Quoted 5 lines
Dunno. Fly or die little patchlet (toss).
sched: allow the user to disable RT bandwidth aggregation.
Hmm. Interesting. With this change, my results are as follows:
rt_runtime/rt_period % of reg iterations
0.2 100% 0.25 100% 0.3 100% 0.4 100% 0.5 82% 0.6 66% 0.7 54% 0.8 46% 0.9 38.5% 0.95 32%
Quoted 5 lines
This results are on a quad core blade. Does it still makes sense though?
Can anyone else run the same tests on a quadcore over the latest kernel? I will patch our 2.6.26 kernel with upstream fixes and rerun these tests on tuesday.
I tested tip (v2.6.31-rc9-1357-ge6a3cd0) with a little perturbation measurement proglet on an isolated Q6600 core.
10s measurement interval results:
sched_rt_runtime_us RT utilization 950000 94.99% 750000 75.00% 500000 50.04% 250000 25.02%
50000 5.03%
Seems to work fine here.
-Mike
A message that is not in the archive (sent off-list or not yet received): DDFD17CC94A9BD49A82147DDF7D545C54DC489@exchange.ZeugmaSystems.local
Quoted 33 lines · Anirban Sinha
-----Original Message-----
From: Mike Galbraith [mailto:[email protected]]
Sent: Sun 9/6/2009 11:54 PM
To: Anirban Sinha
Cc: Lucas De Marchi; [email protected]; Peter Zijlstra; Ingo Molnar
Subject: RE: question on sched-rt group allocation cap:sched_rt_runtime_usQuoted 22 lines · Anirban Sinha
Quoted 5 lines
Dunno. Fly or die little patchlet (toss).
sched: allow the user to disable RT bandwidth aggregation.
Hmm. Interesting. With this change, my results are as follows:
rt_runtime/rt_period % of reg iterations
0.2 100% 0.25 100% 0.3 100% 0.4 100% 0.5 82% 0.6 66% 0.7 54% 0.8 46% 0.9 38.5% 0.95 32%
Quoted 8 lines
Quoted 5 lines
This results are on a quad core blade. Does it still makes sense though?
Can anyone else run the same tests on a quadcore over the latest kernel? I will patch our 2.6.26 kernel with upstream fixes and rerun these tests on tuesday.I tested tip (v2.6.31-rc9-1357-ge6a3cd0) with a little perturbation measurement proglet on an isolated Q6600 core.
Thanks Mike. Is this on a single core machine (or one core carved out of N)? We may have some newer patches missing from the 2.6.26 kernel that fixes some accounting bugs. I will do a review and rerun the test after applying the upstream patches.
Ani
Quoted 8 lines · Anirban Sinha
Quoted 2 lines
I tested tip (v2.6.31-rc9-1357-ge6a3cd0) with a little perturbation measurement proglet on an isolated Q6600 core.
Thanks Mike. Is this on a single core machine (or one core carved out of N)? We may have some newer patches missing from the 2.6.26 kernel that fixes some accounting bugs. I will do a review and rerun the test after applying the upstream patches.
Q6600 is a quad, test was 1 carved out of 4 (thought i said that).
-Mike
Quoted 13 lines · Mike Galbraith
Quoted 12 lines · Ani
Quoted 10 lines · Lucas De Marchi
Indeed. I've tested this same test program in a single core machine and it produces the expected behavior:
rt_runtime_us / rt_period_us % loops executed in SCHED_OTHER 95% 4.48% 60% 54.84% 50% 86.03% 40% OTHER completed first
Quoted 5 lines
Quoted 3 lines
Hmm. This does seem to indicate that there is some kind of relationship with SMP. So I wonder whether there is a way to turn this 'RT bandwidth accumulation' heuristic off.
No there isn't..
Actually there is, use cpusets to carve the system into partitions.
Quoted 14 lines · Peter Zijlstra
Quoted 13 lines · Mike Galbraith
Quoted 12 lines · Ani
Quoted 10 lines · Lucas De Marchi
Indeed. I've tested this same test program in a single core machine and it produces the expected behavior:
rt_runtime_us / rt_period_us % loops executed in SCHED_OTHER 95% 4.48% 60% 54.84% 50% 86.03% 40% OTHER completed first
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Hmm. This does seem to indicate that there is some kind of relationship with SMP. So I wonder whether there is a way to turn this 'RT bandwidth accumulation' heuristic off.
No there isn't..
Actually there is, use cpusets to carve the system into partitions.
Yeah, I stand corrected. I tend to think in terms of the dirt simplest configuration only.
-Mike
A message that is not in the archive (sent off-list or not yet received): DDFD17CC94A9BD49A82147DDF7D545C54DC487@exchange.ZeugmaSystems.local
Quoted 26 lines · Anirban Sinha
-----Original Message-----
From: Peter Zijlstra [mailto:[email protected]]
Sent: Mon 9/7/2009 12:59 AM
To: Mike Galbraith
Cc: Anirban Sinha; Lucas De Marchi; [email protected]; Ingo Molnar
Subject: Re: question on sched-rt group allocation cap:sched_rt_runtime_usQuoted 2 lines · Mike Galbraith
Quoted 1 line · Ani
On Sep 5, 3:50 pm, Lucas De Marchi <[email protected]>
Quoted 2 lines · wrote:
Quoted 2 lines
Quoted 2 lines
Indeed. I've tested this same test program in a single core
machine and it
Quoted 9 lines
Quoted 9 lines
Quoted 8 lines
produces the expected behavior:
rt_runtime_us / rt_period_us % loops executed in SCHED_OTHER 95% 4.48% 60% 54.84% 50% 86.03% 40% OTHER completed first
Quoted 8 lines
Quoted 2 lines
Quoted 2 lines
Hmm. This does seem to indicate that there is some kind of relationship with SMP. So I wonder whether there is a way to
turn this
Quoted 3 lines
Quoted 1 line
'RT bandwidth accumulation' heuristic off.
No there isn't..
Actually there is, use cpusets to carve the system into partitions.
hmm. ok. I looked at the code a little bit. It seems to me that the 'borrowing' of RT runtimes occurs only from rt runqueues belonging to the same root domain. And partition_sched_domains() is the only external interface that can be used to create root domain out of a CPU set. But then I think it needs to have CGROUPS/USER groups enabled? Right?
--Ani
Quoted 3 lines
Quoted 8 lines · Anirban Sinha
Quoted 1 line
Actually there is, use cpusets to carve the system into partitions.
hmm. ok. I looked at the code a little bit. It seems to me that the 'borrowing' of RT runtimes occurs only from rt runqueues belonging to the same root domain. And
partition_sched_domains()is the only external interface that can be used to create root domain out of a CPU set. But then I think it needs to have CGROUPS/USER groups enabled? Right?
No you need cpusets, you create a partition by disabling load-balancing on the top set, thereby only allowing load-balancing withing the children.
The runtime sharing is a form of load-balancing.
CONFIG_CPUSETS=y
Documentation/cgroups/cpusets.txt
Quoted 11 lines · Peter Zijlstra
Quoted 8 lines · Anirban Sinha
Quoted 1 line
Actually there is, use cpusets to carve the system into partitions.
hmm. ok. I looked at the code a little bit. It seems to me that the 'borrowing' of RT runtimes occurs only from rt runqueues belonging to the same root domain. And
partition_sched_domains()is the only external interface that can be used to create root domain out of a CPU set. But then I think it needs to have CGROUPS/USER groups enabled? Right?
Quoted 4 lines
No you need cpusets, you create a partition by disabling load-balancing on the top set, thereby only allowing load-balancing withing the children.
Ah I see. Thanks for the clarification.
Quoted 1 line
The runtime sharing is a form of load-balancing.
sure.
Quoted 2 lines
CONFIG_CPUSETS=y
Hmm. Ok. I guess what I meant but did not articulate properly (because I was thinking in terms of code) was CPUSETS needed CGROUPS support:
config CPUSETS
bool "Cpuset support"
depends on CGROUPS
Anyway, that's fine. I'll dig around the code a little bit more.
Quoted 2 lines
Documentation/cgroups/cpusets.txt
Thanks for the pointer. My bad, I did not care to see the docs. I tend to ignore docs and read code instead. :D
Quoted 1 line
A message that is not in the archive (sent off-list or not yet received): DDFD17CC94A9BD49A82147DDF7D545C54DC48B@exchange.ZeugmaSystems.local
Quoted 30 lines · Anirban Sinha
-----Original Message-----
From: Mike Galbraith [mailto:[email protected]]
Sent: Sat 9/5/2009 11:32 PM
To: Anirban Sinha
Cc: Lucas De Marchi; [email protected]; Peter Zijlstra; Ingo Molnar
Subject: Re: question on sched-rt group allocation cap:sched_rt_runtime_usQuoted 1 line · Ani
On Sep 5, 3:50 pm, Lucas De Marchi <[email protected]>
Quoted 2 lines · wrote:
Quoted 2 lines
Indeed. I've tested this same test program in a single core
machine and it
Quoted 11 lines
Quoted 8 lines
produces the expected behavior:
rt_runtime_us / rt_period_us % loops executed in SCHED_OTHER 95% 4.48% 60% 54.84% 50% 86.03% 40% OTHER completed firstHmm. This does seem to indicate that there is some kind of relationship with SMP. So I wonder whether there is a way to turn
this
Quoted 1 line
'RT bandwidth accumulation' heuristic off.
Quoted 8 lines
No there isn't, but maybe there should be, since this isn't the first time it's come up. One pro argument is that pinned tasks are thoroughly screwed when an RT hog lands on their runqueue. On the con side, the whole RT bandwidth restriction thing is intended (AFAIK) to allow an admin to regain control should RT app go insane, which the default 5% aggregate accomplishes just fine.
Dunno. Fly or die little patchlet (toss).
So it would be nice to have a knob like this when CGROUPS is disabled (it say 'say N when unsure' :)). CPUSETS depends on CGROUPS.
Quoted 6 lines
sched: allow the user to disable RT bandwidth aggregation.
Signed-off-by Mike Galbraith <[email protected]>Cc Ingo Molnar <[email protected]>Cc Peter Zijlstra <[email protected]>
Quoted 70 lines
LKML-Reference: <new-submission>
include/linux/sched.h +1
-0@@ -1881,6 +1881,7 @@ static inline unsigned int get_sysctl_timer_migration(void)#endif extern unsigned int sysctl_sched_rt_period;extern int sysctl_sched_rt_runtime; +extern int sysctl_sched_rt_bandwidth_aggregate; int sched_rt_handler(struct ctl_table *table, int write,struct file *filp, void
__user*buffer,size_t*lenp,kernel/sched.c +6
-0@@ -864,6 +864,12 @@ static __read_mostly int scheduler_running;*/ int sysctl_sched_rt_runtime =950000 ; +/* +* aggregate bandwidth, ie allow borrowing from neighbors when +* bandwidth for an individual runqueue is exhausted. +*/ +int sysctl_sched_rt_bandwidth_aggregate =1 ; +static inline u64 global_rt_period (void ) {return (u64 )sysctl_sched_rt_period *NSEC_PER_USEC ;kernel/sched_rt.c +3
-0@@ -495,6 +495,9 @@ static int balance_runtime(struct rt_rq *rt_rq) {int more =0 ; +if (!sysctl_sched_rt_bandwidth_aggregate) +return 0 ; +if (rt_rq->rt_time > rt_rq->rt_runtime) {spin_unlock (&rt_rq->rt_runtime_lock); more =do_balance_runtime (rt_rq);kernel/sysctl.c +8
-0@@ -368,6 +368,14 @@ static struct ctl_table kern_table[] = { }, { .ctl_name = CTL_UNNUMBERED, + .procname = "sched_rt_bandwidth_aggregate", + .data = &sysctl_sched_rt_bandwidth_aggregate, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &sched_rt_handler, + }, + { + .ctl_name = CTL_UNNUMBERED, .procname = "sched_compat_yield", .data = &sysctl_sched_compat_yield,.maxlen = sizeof(unsigned int),
Quoted 7 lines · Anirban Sinha
Quoted 1 line · Anirban Sinha
Dunno. Fly or die little patchlet (toss).
So it would be nice to have a knob like this when CGROUPS is disabled (it say 'say N when unsure' :)). CPUSETS depends on CGROUPS.
Maybe. Short term hack. My current thoughts on the subject, after some testing, is that the patchlet should just die, and pondering the larger solution should happen.
-Mike
Quoted 2 lines
Maybe. Short term hack. My current thoughts on the subject, after
some
Quoted 2 lines
testing, is that the patchlet should just die, and pondering the larger solution should happen.
Just curious, what is the larger solution? When everyone adapts using control-groups?
Quoted 6 lines · Anirban Sinha
Quoted 1 line
Maybe. Short term hack. My current thoughts on the subject, after
some
Quoted 2 lines
testing, is that the patchlet should just die, and pondering the larger solution should happen.
Just curious, what is the larger solution?
That's what needs pondering :)
-Mike