aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorRoland Dreier <rolandd@cisco.com>2006-08-31 19:43:06 -0400
committerRoland Dreier <rolandd@cisco.com>2006-08-31 20:25:56 -0400
commit5a4e6dccbc0cd1b726820b782daebf887dcb95e9 (patch)
tree28750ce9e633081f8e814d69a3f3d21fd71359f8 /drivers/infiniband
parent22db37ec5fd51b0c77b1dd5751b1cdc2672c08d6 (diff)
IB/mthca: Use IRQ safe locks to protect allocation bitmaps
It is supposed to be OK to call mthca_create_ah() and mthca_destroy_ah() from any context. However, for mem-full HCAs, these functions use the mthca_alloc() and mthca_free() bitmap helpers, and those helpers use non-IRQ-safe spin_lock() internally. Lockdep correctly warns that this could lead to a deadlock. Fix this by changing mthca_alloc() and mthca_free() to use spin_lock_irqsave(). Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_allocator.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c
index 25157f57a6d0..f930e55b58fc 100644
--- a/drivers/infiniband/hw/mthca/mthca_allocator.c
+++ b/drivers/infiniband/hw/mthca/mthca_allocator.c
@@ -41,9 +41,11 @@
41/* Trivial bitmap-based allocator */ 41/* Trivial bitmap-based allocator */
42u32 mthca_alloc(struct mthca_alloc *alloc) 42u32 mthca_alloc(struct mthca_alloc *alloc)
43{ 43{
44 unsigned long flags;
44 u32 obj; 45 u32 obj;
45 46
46 spin_lock(&alloc->lock); 47 spin_lock_irqsave(&alloc->lock, flags);
48
47 obj = find_next_zero_bit(alloc->table, alloc->max, alloc->last); 49 obj = find_next_zero_bit(alloc->table, alloc->max, alloc->last);
48 if (obj >= alloc->max) { 50 if (obj >= alloc->max) {
49 alloc->top = (alloc->top + alloc->max) & alloc->mask; 51 alloc->top = (alloc->top + alloc->max) & alloc->mask;
@@ -56,19 +58,24 @@ u32 mthca_alloc(struct mthca_alloc *alloc)
56 } else 58 } else
57 obj = -1; 59 obj = -1;
58 60
59 spin_unlock(&alloc->lock); 61 spin_unlock_irqrestore(&alloc->lock, flags);
60 62
61 return obj; 63 return obj;
62} 64}
63 65
64void mthca_free(struct mthca_alloc *alloc, u32 obj) 66void mthca_free(struct mthca_alloc *alloc, u32 obj)
65{ 67{
68 unsigned long flags;
69
66 obj &= alloc->max - 1; 70 obj &= alloc->max - 1;
67 spin_lock(&alloc->lock); 71
72 spin_lock_irqsave(&alloc->lock, flags);
73
68 clear_bit(obj, alloc->table); 74 clear_bit(obj, alloc->table);
69 alloc->last = min(alloc->last, obj); 75 alloc->last = min(alloc->last, obj);
70 alloc->top = (alloc->top + alloc->max) & alloc->mask; 76 alloc->top = (alloc->top + alloc->max) & alloc->mask;
71 spin_unlock(&alloc->lock); 77
78 spin_unlock_irqrestore(&alloc->lock, flags);
72} 79}
73 80
74int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask, 81int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask,