[PATCH] mm: cma: Retry from the beginning of cma area if all blocks are busy
johannes at johannesthoma.com
johannes at johannesthoma.com
Fri Jan 6 11:16:11 EST 2017
From: Johannes Thoma <johannes at johannesthoma.com>
When the size of the requested block is close to the total size of
the contigous memory, cma_alloc fails early when no more free
memory blocks are found by bitmap_find_next_zero_area_off and the
memory areas tested are temporarily busy.
This patch introduces a little extra loop that causes cma_alloc to
rescan from the beginning when all checked memory areas are busy.
We ran into this problem when a GPU driver tried to allocate cma memory
on a busy system, but failed because the memory area was busy.
Signed-off-by: Johannes Thoma <johannes at johannesthoma.com>
---
mm/cma.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/mm/cma.c b/mm/cma.c
index c960459..35d68c8 100644
--- a/mm/cma.c
+++ b/mm/cma.c
@@ -368,6 +368,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align)
unsigned long pfn = -1;
unsigned long start = 0;
unsigned long bitmap_maxno, bitmap_no, bitmap_count;
+ int retries = 10;
struct page *page = NULL;
int ret;
@@ -390,10 +391,21 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align)
for (;;) {
mutex_lock(&cma->lock);
+scan_again:
bitmap_no = bitmap_find_next_zero_area_off(cma->bitmap,
bitmap_maxno, start, bitmap_count, mask,
offset);
if (bitmap_no >= bitmap_maxno) {
+ /*
+ * Restart from the beginning if all areas were busy.
+ * This handles false failures when count is close
+ * to overall CMA size and the checked areas were
+ * busy temporarily.
+ */
+ if (start != 0 && retries--) {
+ start = 0;
+ goto scan_again;
+ }
mutex_unlock(&cma->lock);
break;
}
--
2.8.0-rc4
More information about the Kernelnewbies
mailing list