提交 c94f156f 编写于 作者: S Stefan Roscher 提交者: Roland Dreier

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: NStefan Roscher <stefan.roscher@de.ibm.com>
Signed-off-by: NRoland Dreier <rolandd@cisco.com>
上级 bf31a1a0
......@@ -221,10 +221,13 @@ int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue,
/* allocate queue page pointers */
queue->queue_pages = kmalloc(nr_of_pages * sizeof(void *), GFP_KERNEL);
if (!queue->queue_pages) {
queue->queue_pages = vmalloc(nr_of_pages * sizeof(void *));
if (!queue->queue_pages) {
ehca_gen_err("Couldn't allocate queue page list");
return 0;
}
}
memset(queue->queue_pages, 0, nr_of_pages * sizeof(void *));
/* allocate actual queue pages */
......@@ -240,6 +243,9 @@ int ipz_queue_ctor(struct ehca_pd *pd, struct ipz_queue *queue,
ipz_queue_ctor_exit0:
ehca_gen_err("Couldn't alloc pages queue=%p "
"nr_of_pages=%x", queue, nr_of_pages);
if (is_vmalloc_addr(queue->queue_pages))
vfree(queue->queue_pages);
else
kfree(queue->queue_pages);
return 0;
......@@ -262,6 +268,9 @@ int ipz_queue_dtor(struct ehca_pd *pd, struct ipz_queue *queue)
free_page((unsigned long)queue->queue_pages[i]);
}
if (is_vmalloc_addr(queue->queue_pages))
vfree(queue->queue_pages);
else
kfree(queue->queue_pages);
return 1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册