Commit 272c5ac4 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: Fix a sleeping with spinlock bug in ioremap

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.
parent b9f47731
......@@ -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;
......
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