Loading mm/cma.c +20 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/log2.h> #include <linux/cma.h> #include <linux/highmem.h> #include <linux/delay.h> struct cma { unsigned long base_pfn; Loading Loading @@ -344,6 +345,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) unsigned long bitmap_maxno, bitmap_no, bitmap_count; struct page *page = NULL; int ret; int retry_after_sleep = 0; if (!cma || !cma->count) return NULL; Loading @@ -363,9 +365,25 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) bitmap_no = bitmap_find_next_zero_area(cma->bitmap, bitmap_maxno, start, bitmap_count, mask); if (bitmap_no >= bitmap_maxno) { if (retry_after_sleep < 2) { start = 0; /* * Page may be momentarily pinned by some other * process which has been scheduled out, eg. * in exit path, during unmap call, or process * fork and so cannot be freed there. Sleep * for 100ms and retry twice to see if it has * been freed later. */ mutex_unlock(&cma->lock); msleep(100); retry_after_sleep++; continue; } else { mutex_unlock(&cma->lock); break; } } bitmap_set(cma->bitmap, bitmap_no, bitmap_count); /* * It's safe to drop the lock here. We've marked this region for Loading Loading
mm/cma.c +20 −2 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ #include <linux/log2.h> #include <linux/cma.h> #include <linux/highmem.h> #include <linux/delay.h> struct cma { unsigned long base_pfn; Loading Loading @@ -344,6 +345,7 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) unsigned long bitmap_maxno, bitmap_no, bitmap_count; struct page *page = NULL; int ret; int retry_after_sleep = 0; if (!cma || !cma->count) return NULL; Loading @@ -363,9 +365,25 @@ struct page *cma_alloc(struct cma *cma, size_t count, unsigned int align) bitmap_no = bitmap_find_next_zero_area(cma->bitmap, bitmap_maxno, start, bitmap_count, mask); if (bitmap_no >= bitmap_maxno) { if (retry_after_sleep < 2) { start = 0; /* * Page may be momentarily pinned by some other * process which has been scheduled out, eg. * in exit path, during unmap call, or process * fork and so cannot be freed there. Sleep * for 100ms and retry twice to see if it has * been freed later. */ mutex_unlock(&cma->lock); msleep(100); retry_after_sleep++; continue; } else { mutex_unlock(&cma->lock); break; } } bitmap_set(cma->bitmap, bitmap_no, bitmap_count); /* * It's safe to drop the lock here. We've marked this region for Loading