Commit dea7bbb6 authored by Anthony Liguori's avatar Anthony Liguori Committed by Eric Van Hensbergen

9p: Convert semaphore to spinlock for p9_idpool

When booting from v9fs, down_interruptible in p9_idpool_get() triggered a BUG
as it was being called with IRQs disabled.  A spinlock seems like the right
thing to be using since the idr functions go out of their way not to sleep.

This patch eliminates the BUG by converting the semaphore to a spinlock.
Signed-off-by: default avatarAnthony Liguori <aliguori@us.ibm.com>
Acked-by: default avatarEric Van Hensbergen <ericvh@gmail.com>
parent 14b8869f
...@@ -33,7 +33,7 @@ ...@@ -33,7 +33,7 @@
#include <net/9p/9p.h> #include <net/9p/9p.h>
struct p9_idpool { struct p9_idpool {
struct semaphore lock; spinlock_t lock;
struct idr pool; struct idr pool;
}; };
...@@ -45,7 +45,7 @@ struct p9_idpool *p9_idpool_create(void) ...@@ -45,7 +45,7 @@ struct p9_idpool *p9_idpool_create(void)
if (!p) if (!p)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
init_MUTEX(&p->lock); spin_lock_init(&p->lock);
idr_init(&p->pool); idr_init(&p->pool);
return p; return p;
...@@ -71,19 +71,17 @@ int p9_idpool_get(struct p9_idpool *p) ...@@ -71,19 +71,17 @@ int p9_idpool_get(struct p9_idpool *p)
{ {
int i = 0; int i = 0;
int error; int error;
unsigned int flags;
retry: retry:
if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
return 0; return 0;
if (down_interruptible(&p->lock) == -EINTR) { spin_lock_irqsave(&p->lock, flags);
P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n");
return -1;
}
/* no need to store exactly p, we just need something non-null */ /* no need to store exactly p, we just need something non-null */
error = idr_get_new(&p->pool, p, &i); error = idr_get_new(&p->pool, p, &i);
up(&p->lock); spin_unlock_irqrestore(&p->lock, flags);
if (error == -EAGAIN) if (error == -EAGAIN)
goto retry; goto retry;
...@@ -104,12 +102,10 @@ EXPORT_SYMBOL(p9_idpool_get); ...@@ -104,12 +102,10 @@ EXPORT_SYMBOL(p9_idpool_get);
void p9_idpool_put(int id, struct p9_idpool *p) void p9_idpool_put(int id, struct p9_idpool *p)
{ {
if (down_interruptible(&p->lock) == -EINTR) { unsigned int flags;
P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n"); spin_lock_irqsave(&p->lock, flags);
return;
}
idr_remove(&p->pool, id); idr_remove(&p->pool, id);
up(&p->lock); spin_unlock_irqrestore(&p->lock, flags);
} }
EXPORT_SYMBOL(p9_idpool_put); EXPORT_SYMBOL(p9_idpool_put);
......
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