Re: [RFC PATCH v5 2/4] mm: distinguish large folio swap allocation failures
"David Hildenbrand (Arm)" <[email protected]> Thu, 6 Aug 2026 15:56:35 +0200
| Newsgroups | org.kernel.vger.cgroups,org.kernel.vger.linux-kernel,org.kvack.linux-mm |
|---|---|
| Message-ID | <[email protected]> |
On 7/30/26 14:23, Xueyuan Chen wrote: > folio_alloc_swap() reports most allocation failures with a generic > negative error code. Reclaim cannot tell whether splitting a large folio > could make progress or whether there is no backing space at all. > > Keep the global free swap count and the remaining hierarchical memcg swap > margin as separate inputs. The memcg charge path reports only its own > margin; folio_alloc_swap() combines the two layers when classifying an > allocation failure. > > Return -E2BIG for large folios when a smaller allocation might still fit, > -ENOSPC when no global swap space is available, and -ENOMEM when the > failure is not helped by splitting. > > For early large-folio rejections, check global and memcg swap availability > instead of returning -E2BIG unconditionally. On a memcg charge failure, > swap slot allocation has already succeeded, so use the remaining memcg > margin to decide whether a smaller charge might fit. > > This only refines folio_alloc_swap() return codes. The reclaim callers are > updated separately. > > Suggested-by: Barry Song <[email protected]> > Suggested-by: Youngjun Park <[email protected]> > Signed-off-by: Xueyuan Chen <[email protected]> > --- > include/linux/swap.h | 16 ++++++++++++---- > mm/memcontrol.c | 32 +++++++++++++++++++++++++++++++- > mm/swapfile.c | 32 ++++++++++++++++++++++++-------- > 3 files changed, 67 insertions(+), 13 deletions(-) > > diff --git a/include/linux/swap.h b/include/linux/swap.h > index 0544b2ec4c56..7d12058174ae 100644 > --- a/include/linux/swap.h > +++ b/include/linux/swap.h > @@ -509,12 +509,13 @@ static inline void folio_throttle_swaprate(struct folio *folio, gfp_t gfp) > #endif > > #if defined(CONFIG_MEMCG) && defined(CONFIG_SWAP) > -int __mem_cgroup_try_charge_swap(struct folio *folio); > -static inline int mem_cgroup_try_charge_swap(struct folio *folio) > +int __mem_cgroup_try_charge_swap(struct folio *folio, long *swap_margin); > +static inline int mem_cgroup_try_charge_swap(struct folio *folio, > + long *swap_margin) Nit: two tab indent [...] > -static inline int mem_cgroup_try_charge_swap(struct folio *folio) > +static inline int mem_cgroup_try_charge_swap(struct folio *folio, > + long *swap_margin) Nothing else jumped at me Acked-by: David Hildenbrand (Arm) <[email protected]> -- Cheers, David