summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2008-02-07 02:25:04 +0100
committerEric Van Hensbergen <ericvh@opteron.homeip.net>2008-02-07 02:25:04 +0100
commitdea7bbb603735ceceb07bb370eca17198faf7c8d (patch)
tree9792ffca08225d8b1b19c250c33dd2b74441698f /net
parent9p: fix mmap to be read-only (diff)
downloadlinux-dea7bbb603735ceceb07bb370eca17198faf7c8d.tar.xz
linux-dea7bbb603735ceceb07bb370eca17198faf7c8d.zip
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: Anthony Liguori <aliguori@us.ibm.com> Acked-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'net')
-rw-r--r--net/9p/util.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/net/9p/util.c b/net/9p/util.c
index 22077b79395d..ef7215565d88 100644
--- a/net/9p/util.c
+++ b/net/9p/util.c
@@ -33,7 +33,7 @@
#include <net/9p/9p.h>
struct p9_idpool {
- struct semaphore lock;
+ spinlock_t lock;
struct idr pool;
};
@@ -45,7 +45,7 @@ struct p9_idpool *p9_idpool_create(void)
if (!p)
return ERR_PTR(-ENOMEM);
- init_MUTEX(&p->lock);
+ spin_lock_init(&p->lock);
idr_init(&p->pool);
return p;
@@ -71,19 +71,17 @@ int p9_idpool_get(struct p9_idpool *p)
{
int i = 0;
int error;
+ unsigned int flags;
retry:
if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
return 0;
- if (down_interruptible(&p->lock) == -EINTR) {
- P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n");
- return -1;
- }
+ spin_lock_irqsave(&p->lock, flags);
/* no need to store exactly p, we just need something non-null */
error = idr_get_new(&p->pool, p, &i);
- up(&p->lock);
+ spin_unlock_irqrestore(&p->lock, flags);
if (error == -EAGAIN)
goto retry;
@@ -104,12 +102,10 @@ EXPORT_SYMBOL(p9_idpool_get);
void p9_idpool_put(int id, struct p9_idpool *p)
{
- if (down_interruptible(&p->lock) == -EINTR) {
- P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n");
- return;
- }
+ unsigned int flags;
+ spin_lock_irqsave(&p->lock, flags);
idr_remove(&p->pool, id);
- up(&p->lock);
+ spin_unlock_irqrestore(&p->lock, flags);
}
EXPORT_SYMBOL(p9_idpool_put);