Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[powerpc.git] / drivers / infiniband / hw / mthca / mthca_memfree.c
index 1827400..9fb985a 100644 (file)
@@ -82,7 +82,7 @@ void mthca_free_icm(struct mthca_dev *dev, struct mthca_icm *icm)
 }
 
 struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
-                                 unsigned int gfp_mask)
+                                 gfp_t gfp_mask)
 {
        struct mthca_icm *icm;
        struct mthca_icm_chunk *chunk = NULL;
@@ -233,7 +233,7 @@ void *mthca_table_find(struct mthca_icm_table *table, int obj)
                for (i = 0; i < chunk->npages; ++i) {
                        if (chunk->mem[i].length >= offset) {
                                page = chunk->mem[i].page;
-                               break;
+                               goto out;
                        }
                        offset -= chunk->mem[i].length;
                }
@@ -290,7 +290,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
        int i;
        u8 status;
 
-       num_icm = obj_size * nobj / MTHCA_TABLE_CHUNK_SIZE;
+       num_icm = (obj_size * nobj + MTHCA_TABLE_CHUNK_SIZE - 1) / MTHCA_TABLE_CHUNK_SIZE;
 
        table = kmalloc(sizeof *table + num_icm * sizeof *table->icm, GFP_KERNEL);
        if (!table)
@@ -485,9 +485,12 @@ void mthca_cleanup_user_db_tab(struct mthca_dev *dev, struct mthca_uar *uar,
                        put_page(db_tab->page[i].mem.page);
                }
        }
+
+       kfree(db_tab);
 }
 
-int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
+int mthca_alloc_db(struct mthca_dev *dev, enum mthca_db_type type,
+                  u32 qn, __be32 **db)
 {
        int group;
        int start, end, dir;
@@ -529,12 +532,25 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
                        goto found;
                }
 
+       for (i = start; i != end; i += dir)
+               if (!dev->db_tab->page[i].db_rec) {
+                       page = dev->db_tab->page + i;
+                       goto alloc;
+               }
+
        if (dev->db_tab->max_group1 >= dev->db_tab->min_group2 - 1) {
                ret = -ENOMEM;
                goto out;
        }
 
+       if (group == 0)
+               ++dev->db_tab->max_group1;
+       else
+               --dev->db_tab->min_group2;
+
        page = dev->db_tab->page + end;
+
+alloc:
        page->db_rec = dma_alloc_coherent(&dev->pdev->dev, 4096,
                                          &page->mapping, GFP_KERNEL);
        if (!page->db_rec) {
@@ -554,10 +570,6 @@ int mthca_alloc_db(struct mthca_dev *dev, int type, u32 qn, __be32 **db)
        }
 
        bitmap_zero(page->used, MTHCA_DB_REC_PER_PAGE);
-       if (group == 0)
-               ++dev->db_tab->max_group1;
-       else
-               --dev->db_tab->min_group2;
 
 found:
        j = find_first_zero_bit(page->used, MTHCA_DB_REC_PER_PAGE);