mm/khugepaged.c | 1 + 1 file changed, 1 insertion(+)
MADV_COLLAPSE uses errno values to provide actionable feedback to
userspace. Temporary resource constraints are mapped to -EAGAIN so the
caller may retry, while intrinsic failures of the specified range are
mapped to -EINVAL.
collapse_file() returns SCAN_PAGE_HAS_PRIVATE when
filemap_release_folio() fails while isolating file-backed folios for
collapse. This currently falls through the default case in
madvise_collapse_errno() and is reported to userspace as -EINVAL.
However, filemap_release_folio() failure commonly reflects temporary
folio state rather than a permanently uncollapsible range.
For example, ext4 returns false when a folio still has dirty
journalled data, btrfs returns false for dirty or writeback folios
before extent state release, and NFS may return false while reclaiming
filesystem-private folio state.
In such cases, retrying MADV_COLLAPSE after writeback, reclaim or
journal progress may succeed. This matches the existing -EAGAIN
handling for SCAN_PAGE_DIRTY_OR_WRITEBACK and other transient collapse
failures more closely than -EINVAL.
Therefore, map SCAN_PAGE_HAS_PRIVATE to -EAGAIN so userspace receives
retryable feedback for this temporary failure path.
Signed-off-by: Vineet Agarwal <agarwal.vineet2006@gmail.com>
---
mm/khugepaged.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/mm/khugepaged.c b/mm/khugepaged.c
index b8452dbdb043..58f55115d7d8 100644
--- a/mm/khugepaged.c
+++ b/mm/khugepaged.c
@@ -2808,6 +2808,7 @@ static int madvise_collapse_errno(enum scan_result r)
case SCAN_PAGE_LRU:
case SCAN_DEL_PAGE_LRU:
case SCAN_PAGE_FILLED:
+ case SCAN_PAGE_HAS_PRIVATE:
case SCAN_PAGE_DIRTY_OR_WRITEBACK:
return -EAGAIN;
/*
--
2.54.0
On Wed, 29 Apr 2026 19:34:34 +0530 Vineet Agarwal <agarwal.vineet2006@gmail.com> wrote: > MADV_COLLAPSE uses errno values to provide actionable feedback to > userspace. Temporary resource constraints are mapped to -EAGAIN so the > caller may retry, while intrinsic failures of the specified range are > mapped to -EINVAL. > > collapse_file() returns SCAN_PAGE_HAS_PRIVATE when > filemap_release_folio() fails while isolating file-backed folios for > collapse. This currently falls through the default case in > madvise_collapse_errno() and is reported to userspace as -EINVAL. > > However, filemap_release_folio() failure commonly reflects temporary > folio state rather than a permanently uncollapsible range. > > For example, ext4 returns false when a folio still has dirty > journalled data, btrfs returns false for dirty or writeback folios > before extent state release, and NFS may return false while reclaiming > filesystem-private folio state. > > In such cases, retrying MADV_COLLAPSE after writeback, reclaim or > journal progress may succeed. This matches the existing -EAGAIN > handling for SCAN_PAGE_DIRTY_OR_WRITEBACK and other transient collapse > failures more closely than -EINVAL. > > Therefore, map SCAN_PAGE_HAS_PRIVATE to -EAGAIN so userspace receives > retryable feedback for this temporary failure path. Seems very reasonable to me. The madvise(2) manpage could be a lot more helpful here. EAGAIN A kernel resource was temporarily unavailable. and that's it!
On 29/04/26 7:34 pm, Vineet Agarwal wrote: > MADV_COLLAPSE uses errno values to provide actionable feedback to > userspace. Temporary resource constraints are mapped to -EAGAIN so the > caller may retry, while intrinsic failures of the specified range are > mapped to -EINVAL. > > collapse_file() returns SCAN_PAGE_HAS_PRIVATE when > filemap_release_folio() fails while isolating file-backed folios for > collapse. This currently falls through the default case in > madvise_collapse_errno() and is reported to userspace as -EINVAL. > > However, filemap_release_folio() failure commonly reflects temporary > folio state rather than a permanently uncollapsible range. > > For example, ext4 returns false when a folio still has dirty > journalled data, btrfs returns false for dirty or writeback folios > before extent state release, and NFS may return false while reclaiming > filesystem-private folio state. > > In such cases, retrying MADV_COLLAPSE after writeback, reclaim or > journal progress may succeed. This matches the existing -EAGAIN > handling for SCAN_PAGE_DIRTY_OR_WRITEBACK and other transient collapse > failures more closely than -EINVAL. > > Therefore, map SCAN_PAGE_HAS_PRIVATE to -EAGAIN so userspace receives > retryable feedback for this temporary failure path. > > Signed-off-by: Vineet Agarwal <agarwal.vineet2006@gmail.com> > --- > mm/khugepaged.c | 1 + > 1 file changed, 1 insertion(+) > > diff --git a/mm/khugepaged.c b/mm/khugepaged.c > index b8452dbdb043..58f55115d7d8 100644 > --- a/mm/khugepaged.c > +++ b/mm/khugepaged.c > @@ -2808,6 +2808,7 @@ static int madvise_collapse_errno(enum scan_result r) > case SCAN_PAGE_LRU: > case SCAN_DEL_PAGE_LRU: > case SCAN_PAGE_FILLED: > + case SCAN_PAGE_HAS_PRIVATE: > case SCAN_PAGE_DIRTY_OR_WRITEBACK: > return -EAGAIN; > /* https://lore.kernel.org/all/4ab54ae0-2607-443d-8698-788d8e951bdd@arm.com/ I had mentioned at that time, other error codes may fit the -EAGAIN (or something else) definition as well, for example, probably SCAN_TRUNCATED. Could you please audit other error codes as well? Anyhow to your patch here: Reviewed-by: Dev Jain <dev.jain@arm.com>
On 4/29/26 16:20, Dev Jain wrote: > > > On 29/04/26 7:34 pm, Vineet Agarwal wrote: >> MADV_COLLAPSE uses errno values to provide actionable feedback to >> userspace. Temporary resource constraints are mapped to -EAGAIN so the >> caller may retry, while intrinsic failures of the specified range are >> mapped to -EINVAL. >> >> collapse_file() returns SCAN_PAGE_HAS_PRIVATE when >> filemap_release_folio() fails while isolating file-backed folios for >> collapse. This currently falls through the default case in >> madvise_collapse_errno() and is reported to userspace as -EINVAL. >> >> However, filemap_release_folio() failure commonly reflects temporary >> folio state rather than a permanently uncollapsible range. >> >> For example, ext4 returns false when a folio still has dirty >> journalled data, btrfs returns false for dirty or writeback folios >> before extent state release, and NFS may return false while reclaiming >> filesystem-private folio state. >> >> In such cases, retrying MADV_COLLAPSE after writeback, reclaim or >> journal progress may succeed. This matches the existing -EAGAIN >> handling for SCAN_PAGE_DIRTY_OR_WRITEBACK and other transient collapse >> failures more closely than -EINVAL. >> >> Therefore, map SCAN_PAGE_HAS_PRIVATE to -EAGAIN so userspace receives >> retryable feedback for this temporary failure path. >> >> Signed-off-by: Vineet Agarwal <agarwal.vineet2006@gmail.com> >> --- >> mm/khugepaged.c | 1 + >> 1 file changed, 1 insertion(+) >> >> diff --git a/mm/khugepaged.c b/mm/khugepaged.c >> index b8452dbdb043..58f55115d7d8 100644 >> --- a/mm/khugepaged.c >> +++ b/mm/khugepaged.c >> @@ -2808,6 +2808,7 @@ static int madvise_collapse_errno(enum scan_result r) >> case SCAN_PAGE_LRU: >> case SCAN_DEL_PAGE_LRU: >> case SCAN_PAGE_FILLED: >> + case SCAN_PAGE_HAS_PRIVATE: >> case SCAN_PAGE_DIRTY_OR_WRITEBACK: >> return -EAGAIN; >> /* > > https://lore.kernel.org/all/4ab54ae0-2607-443d-8698-788d8e951bdd@arm.com/ > > I had mentioned at that time, other error codes may fit the -EAGAIN > (or something else) definition as well, for example, probably SCAN_TRUNCATED. In folio_split(), we such events as a mixture of EAGAIN and EBUSY. filemap_release_folio() errors are, for example, handles as EBUSY. So in that regard, using EAGAIN here (as we don't use EBUSY) makes sense for SCAN_PAGE_HAS_PRIVATE. -- Cheers, David
© 2016 - 2026 Red Hat, Inc.