(mem hotplug, pcpu_alloc) BUG: sleeping function called from invalid context at kernel/mutex.c:94
Subsystems (2)
Hi,
We have seen following might_sleep warning while hot adding memory...
[ 142.339267] BUG: sleeping function called from invalid context at kernel/mutex.c:94 [ 142.339276] in_atomic(): 0, irqs_disabled(): 1, pid: 4, name: migration/0 [ 142.339283] Pid: 4, comm: migration/0 Not tainted 2.6.35.6-45.fc14.x86_64 #1 [ 142.339288] Call Trace: [ 142.339305] [<ffffffff8103d12b>] __might_sleep+0xeb/0xf0 [ 142.339316] [<ffffffff81468245>] mutex_lock+0x24/0x50 [ 142.339326] [<ffffffff8110eaa6>] pcpu_alloc+0x6d/0x7ee [ 142.339336] [<ffffffff81048888>] ? load_balance+0xbe/0x60e [ 142.339343] [<ffffffff8103a1b3>] ? rt_se_boosted+0x21/0x2f [ 142.339349] [<ffffffff8103e1cf>] ? dequeue_rt_stack+0x18b/0x1ed [ 142.339356] [<ffffffff8110f237>] __alloc_percpu+0x10/0x12 [ 142.339362] [<ffffffff81465e22>] setup_zone_pageset+0x38/0xbe [ 142.339373] [<ffffffff810d6d81>] ? build_zonelists_node.clone.58+0x79/0x8c [ 142.339384] [<ffffffff81452539>] __build_all_zonelists+0x419/0x46c [ 142.339395] [<ffffffff8108ef01>] ? cpu_stopper_thread+0xb2/0x198 [ 142.339401] [<ffffffff8108f075>] stop_machine_cpu_stop+0x8e/0xc5 [ 142.339407] [<ffffffff8108efe7>] ? stop_machine_cpu_stop+0x0/0xc5 [ 142.339414] [<ffffffff8108ef57>] cpu_stopper_thread+0x108/0x198 [ 142.339420] [<ffffffff81467a37>] ? schedule+0x5b2/0x5cc [ 142.339426] [<ffffffff8108ee4f>] ? cpu_stopper_thread+0x0/0x198 [ 142.339434] [<ffffffff81065f29>] kthread+0x7f/0x87 [ 142.339443] [<ffffffff8100aae4>] kernel_thread_helper+0x4/0x10 [ 142.339449] [<ffffffff81065eaa>] ? kthread+0x0/0x87 [ 142.339455] [<ffffffff8100aae0>] ? kernel_thread_helper+0x0/0x10 [ 142.340099] Built 5 zonelists in Node order, mobility grouping on. Total pages: 289456 [ 142.340108] Policy zone: Normal
This warning was seen on the FC14 kernel, though looking at the current git, the problem seems to exist on mainline too.
The problem is that pcpu_alloc expects that it is called from non-atomic context as a result it grabs the pcpu_alloc_mutex.
In the memory-hotplug case though, we do end up calling pcpu_alloc from atomic context, while all cpus are stopped.
void build_all_zonelists(void *data)
{
set_zonelist_order();
if (system_state == SYSTEM_BOOTING) {
__build_all_zonelists(NULL);
mminit_verify_zonelist();
cpuset_init_current_mems_allowed();
} else {
/* we have to stop all cpus to guarantee there is no user
of zonelist */
stop_machine(__build_all_zonelists, data, NULL); <=========
/* cpuset refresh routine should be here */
}__build_all_zonelists eventually calls pcpu_alloc.
I didn't dive through the history, so am not sure when was this regression introduced, but could have regressed with the new pcpu memory allocator.
--
Alok
Hello,
Quoted 52 lines · Alok Kataria
We have seen following
might_sleepwarning while hot adding memory...[ 142.339267] BUG: sleeping function called from invalid context at kernel/mutex.c:94 [ 142.339276] in_atomic(): 0, irqs_disabled(): 1, pid: 4, name: migration/0 [ 142.339283] Pid: 4, comm: migration/0 Not tainted 2.6.35.6-45.fc14.x86_64 #1 [ 142.339288] Call Trace: [ 142.339305] [<ffffffff8103d12b>] __might_sleep+0xeb/0xf0 [ 142.339316] [<ffffffff81468245>] mutex_lock+0x24/0x50 [ 142.339326] [<ffffffff8110eaa6>] pcpu_alloc+0x6d/0x7ee [ 142.339336] [<ffffffff81048888>] ? load_balance+0xbe/0x60e [ 142.339343] [<ffffffff8103a1b3>] ? rt_se_boosted+0x21/0x2f [ 142.339349] [<ffffffff8103e1cf>] ? dequeue_rt_stack+0x18b/0x1ed [ 142.339356] [<ffffffff8110f237>] __alloc_percpu+0x10/0x12 [ 142.339362] [<ffffffff81465e22>] setup_zone_pageset+0x38/0xbe [ 142.339373] [<ffffffff810d6d81>] ? build_zonelists_node.clone.58+0x79/0x8c [ 142.339384] [<ffffffff81452539>] __build_all_zonelists+0x419/0x46c [ 142.339395] [<ffffffff8108ef01>] ? cpu_stopper_thread+0xb2/0x198 [ 142.339401] [<ffffffff8108f075>] stop_machine_cpu_stop+0x8e/0xc5 [ 142.339407] [<ffffffff8108efe7>] ? stop_machine_cpu_stop+0x0/0xc5 [ 142.339414] [<ffffffff8108ef57>] cpu_stopper_thread+0x108/0x198 [ 142.339420] [<ffffffff81467a37>] ? schedule+0x5b2/0x5cc [ 142.339426] [<ffffffff8108ee4f>] ? cpu_stopper_thread+0x0/0x198 [ 142.339434] [<ffffffff81065f29>] kthread+0x7f/0x87 [ 142.339443] [<ffffffff8100aae4>] kernel_thread_helper+0x4/0x10 [ 142.339449] [<ffffffff81065eaa>] ? kthread+0x0/0x87 [ 142.339455] [<ffffffff8100aae0>] ? kernel_thread_helper+0x0/0x10 [ 142.340099] Built 5 zonelists in Node order, mobility grouping on. Total pages: 289456 [ 142.340108] Policy zone: NormalThis warning was seen on the FC14 kernel, though looking at the current git, the problem seems to exist on mainline too.
The problem is thatpcpu_allocexpects that it is called from non-atomic context as a result it grabs thepcpu_alloc_mutex.
In the memory-hotplug case though, we do end up callingpcpu_allocfrom atomic context, while all cpus are stopped.void
build_all_zonelists(void *data){ set_zonelist_order(); if (system_state == SYSTEM_BOOTING) { __build_all_zonelists(NULL); mminit_verify_zonelist(); cpuset_init_current_mems_allowed(); } else { /* we have to stop all cpus to guarantee there is no user of zonelist */ stop_machine(__build_all_zonelists, data, NULL); <========= /* cpuset refresh routine should be here */ }
Quoted 5 lines
__build_all_zonelistseventually callspcpu_alloc.I didn't dive through the history, so am not sure when was this regression introduced, but could have regressed with the new pcpu memory allocator.
Meh... the percpu allocator required user context from the beginning. The new allocator didn't change that.
Wouldn't it be possible to prepare hotplug outside of cpu_stop and use stop_machine() only to make it available to the system. In general, it's a very bad idea to allocate memory from inside stop_machine. The whole machine is stopped, after all. In general, it shouldn't be too difficult to add new resource without stop_machine too unlike removing one. Pekka, Christoph, any ideas?
Thanks.
Signature · 8 lines
tejun -- 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/ . Fight unfair telecom policy in Canada: sign http://dissolvethecrtc.ca/ Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/1 fix build_all_zonelist where percpu_alloc is wrongly called under stop_machine_run (Was Re: (mem hotplug, pcpu_alloc) BUG: sleeping function called from invalid context at kernel/mutex.c:94
Quoted 10 lines · On Sat, 13 Nov 2010 11:09:23 +0100 Tejun Heo <[email protected]> wrote:
Meh... the percpu allocator required user context from the beginning. The new allocator didn't change that.
Wouldn't it be possible to prepare hotplug outside of
cpu_stopand usestop_machine()only to make it available to the system. In general, it's a very bad idea to allocate memory from insidestop_machine. The whole machine is stopped, after all. In general, it shouldn't be too difficult to add new resource withoutstop_machinetoo unlike removing one. Pekka, Christoph, any ideas?
Fix here. I'm glad if someone test this.
==
At memory hotplug, build_allzonelists() may be called under stop_machine_run(). In this function, setup_zone_pageset() is called. But it's bug because it will do page allocation under stop_machine_run().
Here is a report from Alok Kataria.
[ 142.339267] BUG: sleeping function called from invalid context at kernel/mutex.c:94 [ 142.339276] in_atomic(): 0, irqs_disabled(): 1, pid: 4, name: migration/0 [ 142.339283] Pid: 4, comm: migration/0 Not tainted 2.6.35.6-45.fc14.x86_64 #1 [ 142.339288] Call Trace: [ 142.339305] [<ffffffff8103d12b>] __might_sleep+0xeb/0xf0 [ 142.339316] [<ffffffff81468245>] mutex_lock+0x24/0x50 [ 142.339326] [<ffffffff8110eaa6>] pcpu_alloc+0x6d/0x7ee [ 142.339336] [<ffffffff81048888>] ? load_balance+0xbe/0x60e [ 142.339343] [<ffffffff8103a1b3>] ? rt_se_boosted+0x21/0x2f [ 142.339349] [<ffffffff8103e1cf>] ? dequeue_rt_stack+0x18b/0x1ed [ 142.339356] [<ffffffff8110f237>] __alloc_percpu+0x10/0x12 [ 142.339362] [<ffffffff81465e22>] setup_zone_pageset+0x38/0xbe [ 142.339373] [<ffffffff810d6d81>] ? build_zonelists_node.clone.58+0x79/0x8c [ 142.339384] [<ffffffff81452539>] __build_all_zonelists+0x419/0x46c [ 142.339395] [<ffffffff8108ef01>] ? cpu_stopper_thread+0xb2/0x198 [ 142.339401] [<ffffffff8108f075>] stop_machine_cpu_stop+0x8e/0xc5 [ 142.339407] [<ffffffff8108efe7>] ? stop_machine_cpu_stop+0x0/0xc5 [ 142.339414] [<ffffffff8108ef57>] cpu_stopper_thread+0x108/0x198 [ 142.339420] [<ffffffff81467a37>] ? schedule+0x5b2/0x5cc [ 142.339426] [<ffffffff8108ee4f>] ? cpu_stopper_thread+0x0/0x198 [ 142.339434] [<ffffffff81065f29>] kthread+0x7f/0x87 [ 142.339443] [<ffffffff8100aae4>] kernel_thread_helper+0x4/0x10 [ 142.339449] [<ffffffff81065eaa>] ? kthread+0x0/0x87 [ 142.339455] [<ffffffff8100aae0>] ? kernel_thread_helper+0x0/0x10 [ 142.340099] Built 5 zonelists in Node order, mobility grouping on. Total pages: 289456 [ 142.340108] Policy zone: Normal
This patch tries to fix the issue by moving setup_zone_pageset() out from stop_machine_run(). It's obviously not necessary to be called under stop_machine_run().
--- mm/page_alloc.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-)
mm/page_alloc.c +7 -9
@@ -3027,14 +3027,6 @@ static __init_refok int __build_all_zonebuild_zonelist_cache (pgdat); } -#ifdef CONFIG_MEMORY_HOTPLUG -/* Setup real pagesets for the new zone */ -if (data) { -struct zone *zone = data; -setup_zone_pageset (zone); - } -#endif -/* * Initialize the boot_pagesets that are going to be used * for bootstrapping processors. The real pagesets for
@@ -3083,7 +3075,13 @@ void build_all_zonelists(void *data) }else {/* we have to stop all cpus to guarantee there is no user of zonelist */ -stop_machine (__build_all_zonelists, data,NULL ); +#ifdef CONFIG_MEMORY_HOTPLUG +if (data) { +struct zone *zone = (struct zone *)data; +setup_zone_pageset (zone); + } +#endif +stop_machine (__build_all_zonelists,NULL ,NULL );/* cpuset refresh routine should be here */ } vm_total_pages =nr_free_pagecache_pages ();