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

Commit 226a0a71 authored by Isaac J. Manjarres's avatar Isaac J. Manjarres Committed by Hridya Valsaraju
Browse files

ANDROID: staging: ion: Fix dynamic heap ID assignment



The current implementation derives the heap ID using
ffs(), which is one-indexed, and then proceeds to use
this value with functions such as find_next_zero_bit()
and test_and_set_bit() which operate under a zero-indexing
scheme. This can lead to some clumsy/erroneous handling when
dynamically allocating a heap ID, as follows:

CMA heap bits range: [8, 15]

First CMA heap without a heap ID registration:

start_bit = ffs(ION_HEAP_DMA_START) /* 9 */
end_bit = ffs(ION_HEAP_DMA_END) /* 16 */
id_bit = find_next_zero_bit(dev->heap_ids, 16 + 1, 9) /* 9 */
test_and_set_bit(9 - 1, dev->heap_ids) /* Succeeds */

Second CMA heap without a heap ID registration:

start_bit = ffs(ION_HEAP_DMA_START) /* 9 */
end_bit = ffs(ION_HEAP_DMA_END) == 16 /* 16 */
id_bit = find_next_zero_bit(dev->heap_ids, 16 + 1, 9) /* 9 */
test_and_set_bit(9 - 1, dev->heap_ids) /* Fails */

Thus, switch to a zero-indexing scheme when deriving the
heap ID parameters to simplify the logic, as well as correct
the dynamic heap ID assignment logic.

Fixes: acbfdf32 ("ANDROID: staging: ion: add support for consistent heap ids")
Change-Id: I66d0f3838a3ef4dc4ff8537f23dd4e226472b9e2
Signed-off-by: default avatarIsaac J. Manjarres <isaacm@codeaurora.org>
parent 511b851f
Loading
Loading
Loading
Loading
+15 −18
Original line number Diff line number Diff line
@@ -231,33 +231,30 @@ DEFINE_SIMPLE_ATTRIBUTE(debug_shrink_fops, debug_shrink_get,

static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev)
{
	int id_bit;
	int start_bit, end_bit = -1;
	int id_bit = -EINVAL;
	int start_bit = -1, end_bit = -1;

	switch (heap->type) {
	case ION_HEAP_TYPE_SYSTEM:
		id_bit = ffs(ION_HEAP_SYSTEM);
		id_bit = __ffs(ION_HEAP_SYSTEM);
		break;
	case ION_HEAP_TYPE_SYSTEM_CONTIG:
		id_bit = ffs(ION_HEAP_SYSTEM_CONTIG);
		id_bit = __ffs(ION_HEAP_SYSTEM_CONTIG);
		break;
	case ION_HEAP_TYPE_CHUNK:
		id_bit = ffs(ION_HEAP_CHUNK);
		id_bit = __ffs(ION_HEAP_CHUNK);
		break;
	case ION_HEAP_TYPE_CARVEOUT:
		id_bit = 0;
		start_bit = ffs(ION_HEAP_CARVEOUT_START);
		end_bit = ffs(ION_HEAP_CARVEOUT_END);
		start_bit = __ffs(ION_HEAP_CARVEOUT_START);
		end_bit = __ffs(ION_HEAP_CARVEOUT_END);
		break;
	case ION_HEAP_TYPE_DMA:
		id_bit = 0;
		start_bit = ffs(ION_HEAP_DMA_START);
		end_bit = ffs(ION_HEAP_DMA_END);
		start_bit = __ffs(ION_HEAP_DMA_START);
		end_bit = __ffs(ION_HEAP_DMA_END);
		break;
	case ION_HEAP_TYPE_CUSTOM ... ION_HEAP_TYPE_MAX:
		id_bit = 0;
		start_bit = ffs(ION_HEAP_CUSTOM_START);
		end_bit = ffs(ION_HEAP_CUSTOM_END);
		start_bit = __ffs(ION_HEAP_CUSTOM_START);
		end_bit = __ffs(ION_HEAP_CUSTOM_END);
		break;
	default:
		return -EINVAL;
@@ -271,9 +268,9 @@ static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev)
	 * If the heap hasn't picked an id by itself, then we assign it
	 * one.
	 */
	if (!id_bit) {
	if (id_bit < 0) {
		if (heap->id) {
			id_bit = ffs(heap->id);
			id_bit = __ffs(heap->id);
			if (id_bit < start_bit || id_bit > end_bit)
				return -EINVAL;
		} else {
@@ -284,9 +281,9 @@ static int ion_assign_heap_id(struct ion_heap *heap, struct ion_device *dev)
		}
	}

	if (test_and_set_bit(id_bit - 1, dev->heap_ids))
	if (test_and_set_bit(id_bit, dev->heap_ids))
		return -EEXIST;
	heap->id = id_bit - 1;
	heap->id = id_bit;
	dev->heap_cnt++;

	return 0;