aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2008-02-06 20:25:04 -0500
committerEric Van Hensbergen <ericvh@opteron.homeip.net>2008-02-06 20:25:04 -0500
commitdea7bbb603735ceceb07bb370eca17198faf7c8d (patch)
tree9792ffca08225d8b1b19c250c33dd2b74441698f /net
parent14b8869ff4f00f105ea76678997b4d49d27baae3 (diff)
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 @@
33#include <net/9p/9p.h> 33#include <net/9p/9p.h>
34 34
35struct p9_idpool { 35struct p9_idpool {
36 struct semaphore lock; 36 spinlock_t lock;
37 struct idr pool; 37 struct idr pool;
38}; 38};
39 39
@@ -45,7 +45,7 @@ struct p9_idpool *p9_idpool_create(void)
45 if (!p) 45 if (!p)
46 return ERR_PTR(-ENOMEM); 46 return ERR_PTR(-ENOMEM);
47 47
48 init_MUTEX(&p->lock); 48 spin_lock_init(&p->lock);
49 idr_init(&p->pool); 49 idr_init(&p->pool);
50 50
51 return p; 51 return p;
@@ -71,19 +71,17 @@ int p9_idpool_get(struct p9_idpool *p)
71{ 71{
72 int i = 0; 72 int i = 0;
73 int error; 73 int error;
74 unsigned int flags;
74 75
75retry: 76retry:
76 if (idr_pre_get(&p->pool, GFP_KERNEL) == 0) 77 if (idr_pre_get(&p->pool, GFP_KERNEL) == 0)
77 return 0; 78 return 0;
78 79
79 if (down_interruptible(&p->lock) == -EINTR) { 80 spin_lock_irqsave(&p->lock, flags);
80 P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n");
81 return -1;
82 }
83 81
84 /* no need to store exactly p, we just need something non-null */ 82 /* no need to store exactly p, we just need something non-null */
85 error = idr_get_new(&p->pool, p, &i); 83 error = idr_get_new(&p->pool, p, &i);
86 up(&p->lock); 84 spin_unlock_irqrestore(&p->lock, flags);
87 85
88 if (error == -EAGAIN) 86 if (error == -EAGAIN)
89 goto retry; 87 goto retry;
@@ -104,12 +102,10 @@ EXPORT_SYMBOL(p9_idpool_get);
104 102
105void p9_idpool_put(int id, struct p9_idpool *p) 103void p9_idpool_put(int id, struct p9_idpool *p)
106{ 104{
107 if (down_interruptible(&p->lock) == -EINTR) { 105 unsigned int flags;
108 P9_EPRINTK(KERN_WARNING, "Interrupted while locking\n"); 106 spin_lock_irqsave(&p->lock, flags);
109 return;
110 }
111 idr_remove(&p->pool, id); 107 idr_remove(&p->pool, id);
112 up(&p->lock); 108 spin_unlock_irqrestore(&p->lock, flags);
113} 109}
114EXPORT_SYMBOL(p9_idpool_put); 110EXPORT_SYMBOL(p9_idpool_put);
115 111