ppc64: Fix a sleeping with spinlock bug in ioremap
PATCH 1/1 ppc64: Fix a sleeping with spinlock bug in ioremap
Hi !
ppc64 uses it's own range allocator for ioremap (in order to allocate things in a different space than normal vmalloc). This is historic stuff, we may get rid of it, but in the meantime, here's a patch turning the spinlock in there into a semaphore so it doesn't blow up when doing kmalloc's
===== arch/ppc64/mm/imalloc.c 1.3 vs edited =====
arch/ppc64/mm/imalloc.c +9 -9
@@ -9,13 +9,13 @@#include <linux/slab.h> #include <linux/vmalloc.h> -#include <linux/spinlock.h> #include <asm/uaccess.h> #include <asm/pgalloc.h> #include <asm/pgtable.h> +#include <asm/semaphore.h> -rwlock_t imlist_lock =RW_LOCK_UNLOCKED ; +static DECLARE_MUTEX (imlist_sem);struct vm_struct * imlist =NULL ;static int get_free_im_addr (unsigned long size,unsigned long *im_addr)
@@ -223,7 +223,7 @@struct vm_struct *area;unsigned long addr; -write_lock (&imlist_lock); +down (&imlist_sem);if (get_free_im_addr (size, &addr)) {printk (KERN_ERR "%s() cannot obtain addr for size 0x%lx\n" , __FUNCTION__, size);
@@ -238,7 +238,7 @@ __FUNCTION__, addr, size); } next_im_done: -write_unlock (&imlist_lock); +up (&imlist_sem);return area; }
@@ -247,9 +247,9 @@ {struct vm_struct *area; -write_lock (&imlist_lock); +down (&imlist_sem); area =__im_get_area (v_addr, size, criteria); -write_unlock (&imlist_lock); +up (&imlist_sem);return area; }
@@ -264,17 +264,17 @@printk (KERN_ERR "Trying to %s bad address (%p)\n" , __FUNCTION__, addr);return ret_size; } -write_lock (&imlist_lock); +down (&imlist_sem);for (p = &imlist ; (tmp = *p) ; p = &tmp->next) {if (tmp->addr == addr) { ret_size = tmp->size; *p = tmp->next;kfree (tmp); -write_unlock (&imlist_lock); +up (&imlist_sem);return ret_size; } } -write_unlock (&imlist_lock); +up (&imlist_sem);printk (KERN_ERR "Trying to %s nonexistent area (%p)\n" , __FUNCTION__, addr);return ret_size;