[MTHCA] bugfix: mthca_array_clear() does not clear the slot if the used count is
[mirror/winof/.git] / hw / mthca / kernel / mthca_allocator.c
index 84b1aa9..8dae219 100644 (file)
@@ -113,14 +113,15 @@ void mthca_alloc_cleanup(struct mthca_alloc *alloc)
  * serialize access to the array.
  */
 
+#define MTHCA_ARRAY_MASK (PAGE_SIZE / sizeof (void *) - 1)
+
 void *mthca_array_get(struct mthca_array *array, int index)
 {
        int p = (index * sizeof (void *)) >> PAGE_SHIFT;
 
-       if (array->page_list[p].page) {
-               int i = index & (PAGE_SIZE / sizeof (void *) - 1);
-               return array->page_list[p].page[i];
-       } else
+       if (array->page_list[p].page)
+               return array->page_list[p].page[index & MTHCA_ARRAY_MASK];
+       else
                return NULL;
 }
 
@@ -135,8 +136,7 @@ int mthca_array_set(struct mthca_array *array, int index, void *value)
        if (!array->page_list[p].page)
                return -ENOMEM;
 
-       array->page_list[p].page[index & (PAGE_SIZE / sizeof (void *) - 1)] =
-               value;
+       array->page_list[p].page[index & MTHCA_ARRAY_MASK] = value;
        ++array->page_list[p].used;
 
        return 0;
@@ -146,14 +146,18 @@ void mthca_array_clear(struct mthca_array *array, int index)
 {
        int p = (index * sizeof (void *)) >> PAGE_SHIFT;
 
+       if (array->page_list[p].used <= 0) {
+               HCA_PRINT(TRACE_LEVEL_INFORMATION, HCA_DBG_LOW,("Array %p index %d page %d with ref count %d < 0\n",
+                        array, index, p, array->page_list[p].used));
+               return;
+       }
+
        if (--array->page_list[p].used == 0) {
                free_page((void*) array->page_list[p].page);
                array->page_list[p].page = NULL;
        }
-
-       if (array->page_list[p].used < 0)
-               HCA_PRINT(TRACE_LEVEL_INFORMATION, HCA_DBG_LOW,("Array %p index %d page %d with ref count %d < 0\n",
-                        array, index, p, array->page_list[p].used));
+       else
+               array->page_list[p].page[index & MTHCA_ARRAY_MASK] = NULL;
 }
 
 int mthca_array_init(struct mthca_array *array, int nent)