Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c94f156f authored by Stefan Roscher's avatar Stefan Roscher Committed by Roland Dreier
Browse files

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: default avatarStefan Roscher <stefan.roscher@de.ibm.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent bf31a1a0
Loading
Loading
Loading
Loading
+13 −4
Original line number Diff line number Diff line
@@ -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;