@@ -53,6 +53,8 @@ extern int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data)
extern void cma_reserve_pages_on_error(struct cma *cma);
+extern bool cma_set_concurrency(struct cma *cma, bool concurrency);
+
#ifdef CONFIG_CMA
struct folio *cma_alloc_folio(struct cma *cma, int order, gfp_t gfp);
bool cma_free_folio(struct cma *cma, const struct folio *folio);
@@ -460,9 +460,17 @@ static struct page *__cma_alloc(struct cma *cma, unsigned long count,
spin_unlock_irq(&cma->lock);
pfn = cma->base_pfn + (bitmap_no << cma->order_per_bit);
- mutex_lock(&cma_mutex);
+
+ /*
+ * If the user sets the concurr_alloc of CMA to true, concurrent
+ * memory allocation is allowed. If the user sets it to false or
+ * does not set it, concurrent memory allocation is not allowed.
+ */
+ if (!cma->concurr_alloc)
+ mutex_lock(&cma_mutex);
ret = alloc_contig_range(pfn, pfn + count, MIGRATE_CMA, gfp);
- mutex_unlock(&cma_mutex);
+ if (!cma->concurr_alloc)
+ mutex_unlock(&cma_mutex);
if (ret == 0) {
page = pfn_to_page(pfn);
break;
@@ -610,3 +618,13 @@ int cma_for_each_area(int (*it)(struct cma *cma, void *data), void *data)
return 0;
}
+
+bool cma_set_concurrency(struct cma *cma, bool concurrency)
+{
+ if (!cma)
+ return false;
+
+ cma->concurr_alloc = concurrency;
+
+ return true;
+}
@@ -16,6 +16,7 @@ struct cma {
unsigned long *bitmap;
unsigned int order_per_bit; /* Order of pages represented by one bit */
spinlock_t lock;
+ bool concurr_alloc;
#ifdef CONFIG_CMA_DEBUGFS
struct hlist_head mem_head;
spinlock_t mem_head_lock;