aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorStefan Roscher <ossrosch@linux.vnet.ibm.com>2009-05-13 19:52:42 -0400
committerRoland Dreier <rolandd@cisco.com>2009-05-13 19:52:42 -0400
commitc94f156f63c835ffc02b686f9d4238b106f31a5d (patch)
tree2b9e4a8543259fd077f79624838d93b2587e3f73 /drivers/infiniband
parentbf31a1a02eb28d9bda0bb74345df7889faeb7335 (diff)
IB/ehca: Fall back to vmalloc() for big allocations
In case of large queue pairs there is the possibillity of allocation failures due to memory fragmentation when using kmalloc(). To ensure the memory is allocated even if kmalloc() can not find chunks which are big enough, we fall back to allocating the memory with vmalloc(). Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.c b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
index a2605593ae79..1227c593627a 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.c
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.c
@@ -222,8 +222,11 @@ int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue,
222 /* allocate queue page pointers */ 222 /* allocate queue page pointers */
223 queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL); 223 queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL);
224 if (!queue->queue_pages) { 224 if (!queue->queue_pages) {
225 ehca_gen_err("Couldn't allocate queue page list"); 225 queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
226 return 0; 226 if (!queue->queue_pages) {
227 ehca_gen_err("Couldn't allocate queue page list");
228 return 0;
229 }
227 } 230 }
228 memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *)); 231 memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *));
229 232
@@ -240,7 +243,10 @@ int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue,
240ipz_queue_ctor_exit0: 243ipz_queue_ctor_exit0:
241 ehca_gen_err("Couldn't alloc pages queue=%p " 244 ehca_gen_err("Couldn't alloc pages queue=%p "
242 "nr_of_pages=%x", queue, nr_of_pages); 245 "nr_of_pages=%x", queue, nr_of_pages);
243 kfree(queue->queue_pages); 246 if (is_vmalloc_addr(queue->queue_pages))
247 vfree(queue->queue_pages);
248 else
249 kfree(queue->queue_pages);
244 250
245 return 0; 251 return 0;
246} 252}
@@ -262,7 +268,10 @@ int ipz_queue_dtor(struct ehca_pd *pd, struct ipz_queue *queue)
262 free_page((unsigned long)queue->queue_pages[i]); 268 free_page((unsigned long)queue->queue_pages[i]);
263 } 269 }
264 270
265 kfree(queue->queue_pages); 271 if (is_vmalloc_addr(queue->queue_pages))
272 vfree(queue->queue_pages);
273 else
274 kfree(queue->queue_pages);
266 275
267 return 1; 276 return 1;
268} 277}