On Thu, Dec 29 2016, Michal Hocko wrote: > On Thu 29-12-16 11:28:02, Jaewon Kim wrote: >> There are many reasons of CMA allocation failure such as EBUSY, ENOMEM, EINTR. >> This patch prints the error value and bitmap status to know available pages >> regarding fragmentation. >> >> This is an ENOMEM example with this patch. >> [ 11.616321] [2: Binder:711_1: 740] cma: cma_alloc: alloc failed, req-size: 256 pages, ret: -12 > >> [ 11.616365] [2: Binder:711_1: 740] number of available pages: 4+7+7+8+38+166+127=>357 pages, total: 2048 pages > > Could you be more specific why this part is useful? > >> Signed-off-by: Jaewon Kim <jaewon31.kim@xxxxxxxxxxx> >> --- >> mm/cma.c | 29 ++++++++++++++++++++++++++++- >> 1 file changed, 28 insertions(+), 1 deletion(-) >> >> diff --git a/mm/cma.c b/mm/cma.c >> index c960459..535aa39 100644 >> --- a/mm/cma.c >> +++ b/mm/cma.c >> @@ -369,7 +369,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) >> unsigned long start = 0; >> unsigned long bitmap_maxno, bitmap_no, bitmap_count; >> struct page *page = NULL; >> - int ret; >> + int ret = -ENOMEM; >> >> if (!cma || !cma->count) >> return NULL; >> @@ -427,6 +427,33 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) >> trace_cma_alloc(pfn, page, count, align); >> >> pr_debug("%s(): returned %p\n", __func__, page); >> + >> + if (ret != 0) { >> + unsigned int nr, nr_total = 0; >> + unsigned long next_set_bit; >> + >> + pr_info("%s: alloc failed, req-size: %zu pages, ret: %d\n", >> + __func__, count, ret); >> + mutex_lock(&cma->lock); >> + printk("number of available pages: "); >> + start = 0; >> + for (;;) { >> + bitmap_no = find_next_zero_bit(cma->bitmap, cma->count, start); >> + next_set_bit = find_next_bit(cma->bitmap, cma->count, bitmap_no); >> + nr = next_set_bit - bitmap_no; >> + if (bitmap_no >= cma->count) >> + break; Put this just next to ‘bitmap_no = …’ line. No need to call find_next_bit if we’re gonna break anyway. >> + if (nr_total == 0) >> + printk("%u", nr); >> + else >> + printk("+%u", nr); Perhaps also include location of the hole? Something like: pr_cont("%s%u@%u", nr_total ? "+" : "", nr, bitmap_no); >> + nr_total += nr; >> + start = bitmap_no + nr; >> + } >> + printk("=>%u pages, total: %lu pages\n", nr_total, cma->count); >> + mutex_unlock(&cma->lock); >> + } >> + I wonder if this should be wrapped in #ifdef CMA_DEBUG … #endif On one hand it’s relatively expensive (even involving mutex locking) on the other it’s in allocation failure path. >> return page; >> } >> >> -- >> 1.9.1 >> >> -- >> To unsubscribe, send a message with 'unsubscribe linux-mm' in >> the body to majordomo@xxxxxxxxx. For more info on Linux MM, >> see: http://www.linux-mm.org/ . >> Don't email: <a href=mailto:"dont@xxxxxxxxx"> email@xxxxxxxxx </a> > > -- > Michal Hocko > SUSE Labs -- Best regards ミハウ “𝓶𝓲𝓷𝓪86” ナザレヴイツ «If at first you don’t succeed, give up skydiving» -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@xxxxxxxxx. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href