[PATCH] uml: avoid malloc to sleep in atomic sections

Ugly trick to help make malloc not sleeping - we can't do anything else.  But
this is not yet optimal, since spinlock don't trigger in_atomic() when
preemption is disabled.

Also, even if ugly, this was already used in one place, and was even more
bogus.  Fix it.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Cc: Jeff Dike <jdike@addtoit.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
Paolo 'Blaisorblade' Giarrusso 2006-01-18 17:42:58 -08:00 committed by Linus Torvalds
parent b6a2b13778
commit b63162939c
4 changed files with 19 additions and 11 deletions

View file

@ -120,8 +120,10 @@ extern void machine_halt(void);
extern int is_syscall(unsigned long addr);
extern void arch_switch(void);
extern void free_irq(unsigned int, void *);
extern int um_in_interrupt(void);
extern int cpu(void);
/* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */
extern int __cant_sleep(void);
extern void segv_handler(int sig, union uml_pt_regs *regs);
extern void sigio_handler(int sig, union uml_pt_regs *regs);

View file

@ -18,6 +18,7 @@ extern int open_gdb_chan(void);
extern unsigned long strlcpy(char *, const char *, unsigned long);
extern unsigned long strlcat(char *, const char *, unsigned long);
extern void *um_vmalloc(int size);
extern void *um_vmalloc_atomic(int size);
extern void vfree(void *ptr);
#endif

View file

@ -287,17 +287,27 @@ EXPORT_SYMBOL(disable_hlt);
void *um_kmalloc(int size)
{
return(kmalloc(size, GFP_KERNEL));
return kmalloc(size, GFP_KERNEL);
}
void *um_kmalloc_atomic(int size)
{
return(kmalloc(size, GFP_ATOMIC));
return kmalloc(size, GFP_ATOMIC);
}
void *um_vmalloc(int size)
{
return(vmalloc(size));
return vmalloc(size);
}
void *um_vmalloc_atomic(int size)
{
return __vmalloc(size, GFP_ATOMIC | __GFP_HIGHMEM, PAGE_KERNEL);
}
int __cant_sleep(void) {
return in_atomic() || irqs_disabled() || in_interrupt();
/* Is in_interrupt() really needed? */
}
unsigned long get_fault_addr(void)
@ -369,11 +379,6 @@ int smp_sigio_handler(void)
return(0);
}
int um_in_interrupt(void)
{
return(in_interrupt());
}
int cpu(void)
{
return(current_thread->cpu);

View file

@ -60,7 +60,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
if((stack_out != NULL) && (*stack_out != 0))
stack = *stack_out;
else stack = alloc_stack(0, um_in_interrupt());
else stack = alloc_stack(0, __cant_sleep());
if(stack == 0)
return(-ENOMEM);
@ -124,7 +124,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
unsigned long stack, sp;
int pid, status, err;
stack = alloc_stack(stack_order, um_in_interrupt());
stack = alloc_stack(stack_order, __cant_sleep());
if(stack == 0) return(-ENOMEM);
sp = stack + (page_size() << stack_order) - sizeof(void *);