[BUG] kmalloc_node(GFP_KERNEL) while smp_alt spinlocked

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <linux-kernel@...>
Cc: Ingo Molnar <mingo@...>, Steven Rostedt <rostedt@...>, <mathieu.desnoyers@...>
Date: Saturday, April 19, 2008 - 11:41 am

On Mon, 14 Apr 2008 08:57:13 +0200
Ingo Molnar <mingo@elte.hu> wrote:


I have been eyeballing the code in current sched-devel/latest and there's
something I think I found.

This is the beginning of my enter_uniprocessor() which is called from
enable_mmiotrace() seen in the backtrace.

static void enter_uniprocessor(void)
{
	int cpu;
	int err;

	get_online_cpus();
	downed_cpus = cpu_online_map;
	cpu_clear(first_cpu(cpu_online_map), downed_cpus);
	if (num_online_cpus() > 1)
		pr_notice(NAME "Disabling non-boot CPUs...\n");
	put_online_cpus();

	for_each_cpu_mask(cpu, downed_cpus) {
		err = cpu_down(cpu);

The function get_online_cpus() calls might_sleep(), so at that
point everything is fine.

Following the backtrace, we come to alternatives_smp_switch(),
which does
	spin_lock(&smp_alt);
and then continues eventually into this function:

void *__kprobes text_poke(void *addr, const void *opcode, size_t len)
{
        unsigned long flags;
        char *vaddr;
        int nr_pages = 2;

        BUG_ON(len > sizeof(long));
        BUG_ON((((long)addr + len - 1) & ~(sizeof(long) - 1))
                - ((long)addr & ~(sizeof(long) - 1)));
        if (kernel_text_address((unsigned long)addr)) {
                struct page *pages[2] = { virt_to_page(addr),
                        virt_to_page(addr + PAGE_SIZE) };
                if (!pages[1])
                        nr_pages = 1;
                vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);

After which we find ourselves in

struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
                                unsigned long start, unsigned long end)
{
	return __get_vm_area_node(size, flags, start, end, -1, GFP_KERNEL);

and in __get_vm_area_node() there is
area = kmalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node);

where gfp_mask is now GFP_KERNEL. As far as I can tell, using SLAB,
kmalloc_node() here is actually kmalloc(). Anyway, looks like we end up
in __kmalloc with such flags that it may sleep.

I have followed the code so that the path up to kmalloc_node() is
possible, unless there are some "should never happen" conditions
along the way, which I just cannot know of.

Is this the bug?


Thanks.

-- 
Pekka Paalanen
http://www.iki.fi/pq/
--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[BUG] kmalloc_node(GFP_KERNEL) while smp_alt spinlocked, Pekka Paalanen, (Sat Apr 19, 11:41 am)
[PATCH] Fix SMP alternatives : use mutex instead of spinlock..., Mathieu Desnoyers, (Sat Apr 19, 12:19 pm)
Re: [repost PATCH] Fix SMP alternatives : use mutex instead ..., Mathieu Desnoyers, (Tue Apr 22, 4:22 pm)
[PATCH] Check for breakpoint in text_poke to eliminate bug_on, Mathieu Desnoyers, (Sat Apr 19, 5:58 pm)
Re: [PATCH] Check for breakpoint in text_poke to eliminate b..., Mathieu Desnoyers, (Sat Apr 19, 8:05 pm)
Re: [PATCH] Check for breakpoint in text_poke to eliminate b..., Mathieu Desnoyers, (Sun Apr 20, 3:44 pm)
Re: [PATCH] Check for breakpoint in text_poke to eliminate b..., Mathieu Desnoyers, (Sun Apr 20, 4:25 pm)
[PATCH] x86_64: fix kernel rodata NX setting, Pekka Paalanen, (Mon Apr 21, 2:48 pm)
Re: [PATCH] x86_64: fix kernel rodata NX setting, Ingo Molnar, (Mon Apr 21, 3:03 pm)
Re: [PATCH] x86_64: fix kernel rodata NX setting, Steven Rostedt, (Mon Apr 21, 2:57 pm)
Re: [Nouveau] [BUG/PATCH] x86 mmiotrace: dynamically disable..., Stephane Marchesin, (Thu Jul 24, 11:34 am)