[MTHCA] bugfix: mthca_array_clear() does not clear the slot if the used count is
authorleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 1 Aug 2006 10:11:10 +0000 (10:11 +0000)
committerleonidk <leonidk@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Tue, 1 Aug 2006 10:11:10 +0000 (10:11 +0000)
positive. This leads to crashes in mthca_qp_event() since that uses
mthca_array_get() to check that the qp is valid.

git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@435 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

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)