Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/page_alloc: handle a missing case for memalloc_nocma_{save/restore} APIs

memalloc_nocma_{save/restore} APIs can be used to skip page allocation
on CMA area, but, there is a missing case and the page on CMA area could
be allocated even if APIs are used. This patch handles this case to fix
the potential issue.

For now, these APIs are used to prevent long-term pinning on the CMA
page. When the long-term pinning is requested on the CMA page, it is
migrated to the non-CMA page before pinning. This non-CMA page is
allocated by using memalloc_nocma_{save/restore} APIs. If APIs doesn't
work as intended, the CMA page is allocated and it is pinned for a long
time. This long-term pin for the CMA page causes cma_alloc() failure
and it could result in wrong behaviour on the device driver who uses the
cma_alloc().

Missing case is an allocation from the pcplist. MIGRATE_MOVABLE pcplist
could have the pages on CMA area so we need to skip it if ALLOC_CMA
isn't specified.

Fixes: 8510e69c8efe (mm/page_alloc: fix memalloc_nocma_{save/restore} APIs)
Signed-off-by: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Acked-by: Michal Hocko <mhocko@suse.com>
Cc: "Aneesh Kumar K . V" <aneesh.kumar@linux.ibm.com>
Cc: Mel Gorman <mgorman@techsingularity.net>
Link: https://lkml.kernel.org/r/1601429472-12599-1-git-send-email-iamjoonsoo.kim@lge.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Joonsoo Kim and committed by
Linus Torvalds
1d91df85 484cfaca

+16 -3
+16 -3
mm/page_alloc.c
··· 3367 3367 struct page *page; 3368 3368 3369 3369 if (likely(order == 0)) { 3370 - page = rmqueue_pcplist(preferred_zone, zone, gfp_flags, 3370 + /* 3371 + * MIGRATE_MOVABLE pcplist could have the pages on CMA area and 3372 + * we need to skip it when CMA area isn't allowed. 3373 + */ 3374 + if (!IS_ENABLED(CONFIG_CMA) || alloc_flags & ALLOC_CMA || 3375 + migratetype != MIGRATE_MOVABLE) { 3376 + page = rmqueue_pcplist(preferred_zone, zone, gfp_flags, 3371 3377 migratetype, alloc_flags); 3372 - goto out; 3378 + goto out; 3379 + } 3373 3380 } 3374 3381 3375 3382 /* ··· 3388 3381 3389 3382 do { 3390 3383 page = NULL; 3391 - if (alloc_flags & ALLOC_HARDER) { 3384 + /* 3385 + * order-0 request can reach here when the pcplist is skipped 3386 + * due to non-CMA allocation context. HIGHATOMIC area is 3387 + * reserved for high-order atomic allocation, so order-0 3388 + * request should skip it. 3389 + */ 3390 + if (order > 0 && alloc_flags & ALLOC_HARDER) { 3392 3391 page = __rmqueue_smallest(zone, order, MIGRATE_HIGHATOMIC); 3393 3392 if (page) 3394 3393 trace_mm_page_alloc_zone_locked(page, order, migratetype);