#include <linux/cma.h>
#include <linux/highmem.h>
#include <linux/io.h>
+#include <linux/delay.h>
#include <trace/events/cma.h>
#include "cma.h"
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;
bitmap_maxno, start, bitmap_count, mask,
offset);
if (bitmap_no >= bitmap_maxno) {
- mutex_unlock(&cma->lock);
- break;
+ 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);
/*