mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-08-30 10:00:03 -04:00
mm: let node_reclaim() return the number of pages reclaimed
There is only one caller, get_page_from_freelist(), and it does not make any use of the reason for skipping the reclaim, nor does it make any distinction between a full and partially successful reclaim. Therefore, node_reclaim() can simply return the number of pages that have been reclaimed, same as __node_reclaim(), and the NODE_RECLAIM_xxx macros can be removed. There is one small change of behavior when __node_reclaim() was attempted but returned zero. The allocation now skips the zone immediately; before this patch, the zone watermarks were checked first. I believe it was an oversight rather than intention, because the chances that zone watermark is OK after __node_reclaim() did not reclaim any pages are very close to zero. Originally, I was looking for occurences of NODE_RECLAIM_SOME and NODE_RECLAIM_SUCCESS, but I couldn't find any. That's because they are typecast from the result of a relational operator. This seemed a bit fragile, so I dug a bit deeper and came up with this proposed cleanup. Link: https://lore.kernel.org/20260714132300.2136018-1-ptesarik@suse.com Signed-off-by: Petr Tesarik <ptesarik@suse.com> Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org> Reviewed-by: Zi Yan <ziy@nvidia.com> Acked-by: Johannes Weiner <hannes@cmpxchg.org> Cc: Brendan Jackman <jackmanb@google.com> Cc: Brendan Jackman <brendan.jackman@linux.dev> Cc: David Hildenbrand <david@kernel.org> Cc: Liam R. Howlett <liam@infradead.org> Cc: Lorenzo Stoakes <ljs@kernel.org> Cc: Michal Hocko <mhocko@suse.com> Cc: Mike Rapoport <rppt@kernel.org> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
committed by
Andrew Morton
parent
8315cf471e
commit
ff3d40545f
@@ -1098,23 +1098,19 @@ static inline void mlock_drain_local(void) { }
|
||||
static inline void mlock_drain_remote(int cpu) { }
|
||||
#endif /* !CONFIG_MMU */
|
||||
|
||||
#define NODE_RECLAIM_NOSCAN -2
|
||||
#define NODE_RECLAIM_FULL -1
|
||||
#define NODE_RECLAIM_SOME 0
|
||||
#define NODE_RECLAIM_SUCCESS 1
|
||||
|
||||
#ifdef CONFIG_NUMA
|
||||
extern int node_reclaim_mode;
|
||||
|
||||
extern int node_reclaim(struct pglist_data *, gfp_t, unsigned int);
|
||||
extern unsigned long node_reclaim(struct pglist_data *pgdat,
|
||||
gfp_t gfp_mask, unsigned int order);
|
||||
extern int find_next_best_node(int node, nodemask_t *used_node_mask);
|
||||
#else
|
||||
#define node_reclaim_mode 0
|
||||
|
||||
static inline int node_reclaim(struct pglist_data *pgdat, gfp_t mask,
|
||||
unsigned int order)
|
||||
static inline unsigned long node_reclaim(struct pglist_data *pgdat,
|
||||
gfp_t mask, unsigned int order)
|
||||
{
|
||||
return NODE_RECLAIM_NOSCAN;
|
||||
return 0;
|
||||
}
|
||||
static inline int find_next_best_node(int node, nodemask_t *used_node_mask)
|
||||
{
|
||||
|
||||
@@ -3908,8 +3908,6 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order, int alloc_flags,
|
||||
if (!zone_watermark_fast(zone, order, mark,
|
||||
ac->highest_zoneidx, alloc_flags,
|
||||
gfp_mask)) {
|
||||
int ret;
|
||||
|
||||
if (cond_accept_memory(zone, order, alloc_flags))
|
||||
goto try_this_zone;
|
||||
|
||||
@@ -3930,22 +3928,13 @@ get_page_from_freelist(gfp_t gfp_mask, unsigned int order, int alloc_flags,
|
||||
!zone_allows_reclaim(zonelist_zone(ac->preferred_zoneref), zone))
|
||||
continue;
|
||||
|
||||
ret = node_reclaim(zone->zone_pgdat, gfp_mask, order);
|
||||
switch (ret) {
|
||||
case NODE_RECLAIM_NOSCAN:
|
||||
/* did not scan */
|
||||
if (!node_reclaim(zone->zone_pgdat, gfp_mask, order))
|
||||
continue;
|
||||
case NODE_RECLAIM_FULL:
|
||||
/* scanned but unreclaimable */
|
||||
continue;
|
||||
default:
|
||||
/* did we reclaim enough */
|
||||
if (zone_watermark_ok(zone, order, mark,
|
||||
ac->highest_zoneidx, alloc_flags))
|
||||
goto try_this_zone;
|
||||
|
||||
/* did we reclaim enough */
|
||||
if (!zone_watermark_ok(zone, order, mark,
|
||||
ac->highest_zoneidx, alloc_flags))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
try_this_zone:
|
||||
|
||||
16
mm/vmscan.c
16
mm/vmscan.c
@@ -7773,9 +7773,9 @@ static unsigned long __node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask,
|
||||
return sc->nr_reclaimed;
|
||||
}
|
||||
|
||||
int node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned int order)
|
||||
unsigned long node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned int order)
|
||||
{
|
||||
int ret;
|
||||
unsigned long ret;
|
||||
/* Minimum pages needed in order to stay on node */
|
||||
const unsigned long nr_pages = 1 << order;
|
||||
struct scan_control sc = {
|
||||
@@ -7802,13 +7802,13 @@ int node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned int order)
|
||||
if (node_pagecache_reclaimable(pgdat) <= pgdat->min_unmapped_pages &&
|
||||
node_page_state_pages(pgdat, NR_SLAB_RECLAIMABLE_B) <=
|
||||
pgdat->min_slab_pages)
|
||||
return NODE_RECLAIM_FULL;
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Do not scan if the allocation should not be delayed.
|
||||
*/
|
||||
if (!gfpflags_allow_blocking(gfp_mask) || (current->flags & PF_MEMALLOC))
|
||||
return NODE_RECLAIM_NOSCAN;
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Only run node reclaim on the local node or on nodes that do not
|
||||
@@ -7817,15 +7817,15 @@ int node_reclaim(struct pglist_data *pgdat, gfp_t gfp_mask, unsigned int order)
|
||||
* as wide as possible.
|
||||
*/
|
||||
if (node_state(pgdat->node_id, N_CPU) && pgdat->node_id != numa_node_id())
|
||||
return NODE_RECLAIM_NOSCAN;
|
||||
return 0;
|
||||
|
||||
if (test_and_set_bit_lock(PGDAT_RECLAIM_LOCKED, &pgdat->flags))
|
||||
return NODE_RECLAIM_NOSCAN;
|
||||
return 0;
|
||||
|
||||
ret = __node_reclaim(pgdat, gfp_mask, nr_pages, &sc) >= nr_pages;
|
||||
ret = __node_reclaim(pgdat, gfp_mask, nr_pages, &sc);
|
||||
clear_bit_unlock(PGDAT_RECLAIM_LOCKED, &pgdat->flags);
|
||||
|
||||
if (ret)
|
||||
if (ret >= nr_pages)
|
||||
count_vm_event(PGSCAN_ZONE_RECLAIM_SUCCESS);
|
||||
else
|
||||
count_vm_event(PGSCAN_ZONE_RECLAIM_FAILED);
|
||||
|
||||
Reference in New Issue
Block a user