[PATCH v3] mm/page_io: use sio->len for PSWPIN accounting in sio_read_complete()

David Carlier posted 1 patch 13 hours ago
mm/page_io.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[PATCH v3] mm/page_io: use sio->len for PSWPIN accounting in sio_read_complete()
Posted by David Carlier 13 hours ago
sio_read_complete() uses sio->pages to account global PSWPIN vm events,
but sio->pages tracks the number of bvec entries (folios), not base
pages.

While large folios cannot currently reach this path (SWP_FS_OPS and
SWP_SYNCHRONOUS_IO are mutually exclusive, and mTHP swap-in allocation
is gated on SWP_SYNCHRONOUS_IO), the accounting is semantically
inconsistent with the per-memcg path which correctly uses
folio_nr_pages().

Use sio->len >> PAGE_SHIFT instead, which gives the correct base page
count since sio->len is accumulated via folio_size(folio).

Signed-off-by: David Carlier <devnexen@gmail.com>
---
 mm/page_io.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/page_io.c b/mm/page_io.c
index 63b262f4c5a9..1389cd57ca88 100644
--- a/mm/page_io.c
+++ b/mm/page_io.c
@@ -497,7 +497,7 @@ static void sio_read_complete(struct kiocb *iocb, long ret)
 			folio_mark_uptodate(folio);
 			folio_unlock(folio);
 		}
-		count_vm_events(PSWPIN, sio->pages);
+		count_vm_events(PSWPIN, sio->len >> PAGE_SHIFT);
 	} else {
 		for (p = 0; p < sio->pages; p++) {
 			struct folio *folio = page_folio(sio->bvec[p].bv_page);
-- 
2.53.0
Re: [PATCH v3] mm/page_io: use sio->len for PSWPIN accounting in sio_read_complete()
Posted by David Hildenbrand (Arm) 12 hours ago
On 4/1/26 09:47, David Carlier wrote:
> sio_read_complete() uses sio->pages to account global PSWPIN vm events,
> but sio->pages tracks the number of bvec entries (folios), not base
> pages.
> 
> While large folios cannot currently reach this path (SWP_FS_OPS and
> SWP_SYNCHRONOUS_IO are mutually exclusive, and mTHP swap-in allocation
> is gated on SWP_SYNCHRONOUS_IO), the accounting is semantically
> inconsistent with the per-memcg path which correctly uses
> folio_nr_pages().
> 
> Use sio->len >> PAGE_SHIFT instead, which gives the correct base page
> count since sio->len is accumulated via folio_size(folio).
> 
> Signed-off-by: David Carlier <devnexen@gmail.com>

For the next time: Please don't send new revisions as reply to other
revisions :)

> ---
>  mm/page_io.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/mm/page_io.c b/mm/page_io.c
> index 63b262f4c5a9..1389cd57ca88 100644
> --- a/mm/page_io.c
> +++ b/mm/page_io.c
> @@ -497,7 +497,7 @@ static void sio_read_complete(struct kiocb *iocb, long ret)
>  			folio_mark_uptodate(folio);
>  			folio_unlock(folio);
>  		}
> -		count_vm_events(PSWPIN, sio->pages);
> +		count_vm_events(PSWPIN, sio->len >> PAGE_SHIFT);
>  	} else {
>  		for (p = 0; p < sio->pages; p++) {
>  			struct folio *folio = page_folio(sio->bvec[p].bv_page);

sio->len always covers full pages as processed in swap_read_folio_fs(),
so there should not be any difference.


Acked-by: David Hildenbrand (Arm) <david@kernel.org>

-- 
Cheers,

David