]> git.hungrycats.org Git - linux/commitdiff
[PATCH] ppc64: Fix a sleeping with spinlock bug in ioremap
authorAndrew Morton <akpm@osdl.org>
Thu, 26 Feb 2004 14:44:54 +0000 (06:44 -0800)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 26 Feb 2004 14:44:54 +0000 (06:44 -0800)
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>

ppc64 uses its 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
kmallocs.

arch/ppc64/mm/imalloc.c

index d6bf228150967fead62950238ede48b5de44d858..2399f3fcba050dbaf5ffce9dca7582504c001485 100644 (file)
@@ -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 * im_get_free_area(unsigned long size)
        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 @@ struct vm_struct * im_get_free_area(unsigned long size)
                        __FUNCTION__, addr, size);
        }
 next_im_done:
-       write_unlock(&imlist_lock);
+       up(&imlist_sem);
        return area;
 }
 
@@ -247,9 +247,9 @@ struct vm_struct * im_get_area(unsigned long v_addr, unsigned long size,
 {
        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 @@ unsigned long im_free(void * addr)
                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;