Commit b6316293 authored by Paolo 'Blaisorblade' Giarrusso's avatar Paolo 'Blaisorblade' Giarrusso Committed by Linus Torvalds

[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: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
Cc: Jeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent b6a2b137
...@@ -120,8 +120,10 @@ extern void machine_halt(void); ...@@ -120,8 +120,10 @@ extern void machine_halt(void);
extern int is_syscall(unsigned long addr); extern int is_syscall(unsigned long addr);
extern void arch_switch(void); extern void arch_switch(void);
extern void free_irq(unsigned int, void *); extern void free_irq(unsigned int, void *);
extern int um_in_interrupt(void);
extern int cpu(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 segv_handler(int sig, union uml_pt_regs *regs);
extern void sigio_handler(int sig, union uml_pt_regs *regs); extern void sigio_handler(int sig, union uml_pt_regs *regs);
......
...@@ -18,6 +18,7 @@ extern int open_gdb_chan(void); ...@@ -18,6 +18,7 @@ extern int open_gdb_chan(void);
extern unsigned long strlcpy(char *, const char *, unsigned long); extern unsigned long strlcpy(char *, const char *, unsigned long);
extern unsigned long strlcat(char *, const char *, unsigned long); extern unsigned long strlcat(char *, const char *, unsigned long);
extern void *um_vmalloc(int size); extern void *um_vmalloc(int size);
extern void *um_vmalloc_atomic(int size);
extern void vfree(void *ptr); extern void vfree(void *ptr);
#endif #endif
......
...@@ -287,17 +287,27 @@ EXPORT_SYMBOL(disable_hlt); ...@@ -287,17 +287,27 @@ EXPORT_SYMBOL(disable_hlt);
void *um_kmalloc(int size) void *um_kmalloc(int size)
{ {
return(kmalloc(size, GFP_KERNEL)); return kmalloc(size, GFP_KERNEL);
} }
void *um_kmalloc_atomic(int size) void *um_kmalloc_atomic(int size)
{ {
return(kmalloc(size, GFP_ATOMIC)); return kmalloc(size, GFP_ATOMIC);
} }
void *um_vmalloc(int size) 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) unsigned long get_fault_addr(void)
...@@ -369,11 +379,6 @@ int smp_sigio_handler(void) ...@@ -369,11 +379,6 @@ int smp_sigio_handler(void)
return(0); return(0);
} }
int um_in_interrupt(void)
{
return(in_interrupt());
}
int cpu(void) int cpu(void)
{ {
return(current_thread->cpu); return(current_thread->cpu);
......
...@@ -60,7 +60,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, ...@@ -60,7 +60,7 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv,
if((stack_out != NULL) && (*stack_out != 0)) if((stack_out != NULL) && (*stack_out != 0))
stack = *stack_out; stack = *stack_out;
else stack = alloc_stack(0, um_in_interrupt()); else stack = alloc_stack(0, __cant_sleep());
if(stack == 0) if(stack == 0)
return(-ENOMEM); return(-ENOMEM);
...@@ -124,7 +124,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, ...@@ -124,7 +124,7 @@ int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags,
unsigned long stack, sp; unsigned long stack, sp;
int pid, status, err; int pid, status, err;
stack = alloc_stack(stack_order, um_in_interrupt()); stack = alloc_stack(stack_order, __cant_sleep());
if(stack == 0) return(-ENOMEM); if(stack == 0) return(-ENOMEM);
sp = stack + (page_size() << stack_order) - sizeof(void *); sp = stack + (page_size() << stack_order) - sizeof(void *);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment