aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c34
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.h1
2 files changed, 35 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 46981d48c232..ea45de8c5b8e 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -192,6 +192,40 @@ void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int o
192 up(&table->mutex); 192 up(&table->mutex);
193} 193}
194 194
195void *mthca_table_find(struct mthca_icm_table *table, int obj)
196{
197 int idx, offset, i;
198 struct mthca_icm_chunk *chunk;
199 struct mthca_icm *icm;
200 struct page *page = NULL;
201
202 if (!table->lowmem)
203 return NULL;
204
205 down(&table->mutex);
206
207 idx = (obj & (table->num_obj - 1)) * table->obj_size;
208 icm = table->icm[idx / MTHCA_TABLE_CHUNK_SIZE];
209 offset = idx % MTHCA_TABLE_CHUNK_SIZE;
210
211 if (!icm)
212 goto out;
213
214 list_for_each_entry(chunk, &icm->chunk_list, list) {
215 for (i = 0; i < chunk->npages; ++i) {
216 if (chunk->mem[i].length >= offset) {
217 page = chunk->mem[i].page;
218 break;
219 }
220 offset -= chunk->mem[i].length;
221 }
222 }
223
224out:
225 up(&table->mutex);
226 return page ? lowmem_page_address(page) + offset : NULL;
227}
228
195int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table, 229int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
196 int start, int end) 230 int start, int end)
197{ 231{
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h
index ef72e430250a..fe7be2a6bc4a 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.h
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.h
@@ -85,6 +85,7 @@ struct mthca_icm_table *mthca_alloc_icm_table(struct mthca_dev *dev,
85void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table); 85void mthca_free_icm_table(struct mthca_dev *dev, struct mthca_icm_table *table);
86int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int obj); 86int mthca_table_get(struct mthca_dev *dev, struct mthca_icm_table *table, int obj);
87void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj); 87void mthca_table_put(struct mthca_dev *dev, struct mthca_icm_table *table, int obj);
88void *mthca_table_find(struct mthca_icm_table *table, int obj);
88int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table, 89int mthca_table_get_range(struct mthca_dev *dev, struct mthca_icm_table *table,
89 int start, int end); 90 int start, int end);
90void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table *table, 91void mthca_table_put_range(struct mthca_dev *dev, struct mthca_icm_table *table,