diff options
Diffstat (limited to 'drivers/infiniband/hw/mthca/mthca_allocator.c')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_allocator.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_allocator.c b/drivers/infiniband/hw/mthca/mthca_allocator.c index 9ba3211cef7c..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 */ |
42 | u32 mthca_alloc(struct mthca_alloc *alloc) | 42 | u32 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 | ||
64 | void mthca_free(struct mthca_alloc *alloc, u32 obj) | 66 | void 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 | ||
74 | int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask, | 81 | int mthca_alloc_init(struct mthca_alloc *alloc, u32 num, u32 mask, |
@@ -108,14 +115,15 @@ void mthca_alloc_cleanup(struct mthca_alloc *alloc) | |||
108 | * serialize access to the array. | 115 | * serialize access to the array. |
109 | */ | 116 | */ |
110 | 117 | ||
118 | #define MTHCA_ARRAY_MASK (PAGE_SIZE / sizeof (void *) - 1) | ||
119 | |||
111 | void *mthca_array_get(struct mthca_array *array, int index) | 120 | void *mthca_array_get(struct mthca_array *array, int index) |
112 | { | 121 | { |
113 | int p = (index * sizeof (void *)) >> PAGE_SHIFT; | 122 | int p = (index * sizeof (void *)) >> PAGE_SHIFT; |
114 | 123 | ||
115 | if (array->page_list[p].page) { | 124 | if (array->page_list[p].page) |
116 | int i = index & (PAGE_SIZE / sizeof (void *) - 1); | 125 | return array->page_list[p].page[index & MTHCA_ARRAY_MASK]; |
117 | return array->page_list[p].page[i]; | 126 | else |
118 | } else | ||
119 | return NULL; | 127 | return NULL; |
120 | } | 128 | } |
121 | 129 | ||
@@ -130,8 +138,7 @@ int mthca_array_set(struct mthca_array *array, int index, void *value) | |||
130 | if (!array->page_list[p].page) | 138 | if (!array->page_list[p].page) |
131 | return -ENOMEM; | 139 | return -ENOMEM; |
132 | 140 | ||
133 | array->page_list[p].page[index & (PAGE_SIZE / sizeof (void *) - 1)] = | 141 | array->page_list[p].page[index & MTHCA_ARRAY_MASK] = value; |
134 | value; | ||
135 | ++array->page_list[p].used; | 142 | ++array->page_list[p].used; |
136 | 143 | ||
137 | return 0; | 144 | return 0; |
@@ -144,7 +151,8 @@ void mthca_array_clear(struct mthca_array *array, int index) | |||
144 | if (--array->page_list[p].used == 0) { | 151 | if (--array->page_list[p].used == 0) { |
145 | free_page((unsigned long) array->page_list[p].page); | 152 | free_page((unsigned long) array->page_list[p].page); |
146 | array->page_list[p].page = NULL; | 153 | array->page_list[p].page = NULL; |
147 | } | 154 | } else |
155 | array->page_list[p].page[index & MTHCA_ARRAY_MASK] = NULL; | ||
148 | 156 | ||
149 | if (array->page_list[p].used < 0) | 157 | if (array->page_list[p].used < 0) |
150 | pr_debug("Array %p index %d page %d with ref count %d < 0\n", | 158 | pr_debug("Array %p index %d page %d with ref count %d < 0\n", |