From: Usama Arif <usamaarif642@gmail.com>
To: Yosry Ahmed <yosryahmed@google.com>
Cc: 21cnbao@gmail.com, akpm@linux-foundation.org, hannes@cmpxchg.org,
david@redhat.com, ying.huang@intel.com, hughd@google.com,
willy@infradead.org, nphamcs@gmail.com, chengming.zhou@linux.dev,
linux-mm@kvack.org, linux-kernel@vger.kernel.org,
kernel-team@meta.com, Shakeel Butt <shakeel.butt@linux.dev>
Subject: Re: [PATCH v3 1/2] mm: store zero pages to be swapped out in a bitmap
Date: Tue, 11 Jun 2024 19:43:41 +0100 [thread overview]
Message-ID: <622bc591-ad14-448e-a9f3-988976fbb98a@gmail.com> (raw)
In-Reply-To: <CAJD7tkZC8e8ZTBSOGZH-1srTeC=jqxwWchd-BjvNsV2FR0oT8Q@mail.gmail.com>
On 11/06/2024 18:51, Yosry Ahmed wrote:
> [..]
>>>> I think its better to handle this in Barrys patch. I feel this series is
>>>> close to its final state, i.e. the only diff I have for the next
>>>> revision is below to remove start/end_writeback for zer_filled case. I
>>>> will comment on Barrys patch once the I send out the next revision of this.
>>> Sorry I did not make myself clearer. I did not mean that you should
>>> handle the large folio swapin here. This needs to be handled at a
>>> higher level because as you mentioned, a large folio may be partially
>>> in the zeromap, zswap, swapcache, disk, etc.
>>>
>>> What I meant is that we should probably have a debug check to make
>>> sure this doesn't go unhandled. For zswap, I am trying to add a
>>> warning and fail the swapin operation if a large folio slips through
>>> to zswap. We can do something similar here if folks agree this is the
>>> right way in the interim:
>>> https://lore.kernel.org/lkml/20240611024516.1375191-3-yosryahmed@google.com/.
>>>
>>> Maybe I am too paranoid, but I think it's easy to mess up these things
>>> when working on large folio swapin imo.
>> So there is a difference between zswap and this optimization. In this
>> optimization, if the zeromap is set for all the folio bits, then we
>> should do large folio swapin. There still needs to be a change in Barrys
>> patch in alloc_swap_folio, but apart from that does the below diff over
>> v3 make it better? I will send a v4 with this if it sounds good.
>>
>>
>> diff --git a/mm/page_io.c b/mm/page_io.c
>> index 6400be6e4291..bf01364748a9 100644
>> --- a/mm/page_io.c
>> +++ b/mm/page_io.c
>> @@ -234,18 +234,24 @@ static void swap_zeromap_folio_clear(struct folio
>> *folio)
>> }
>> }
>>
>> -static bool swap_zeromap_folio_test(struct folio *folio)
>> +/*
>> + * Return the index of the first subpage which is not zero-filled
>> + * according to swap_info_struct->zeromap.
>> + * If all pages are zero-filled according to zeromap, it will return
>> + * folio_nr_pages(folio).
>> + */
>> +static long swap_zeromap_folio_test(struct folio *folio)
>> {
>> struct swap_info_struct *sis = swp_swap_info(folio->swap);
>> swp_entry_t entry;
>> - unsigned int i;
>> + long i;
> Why long?
folio_nr_pages returns long, but I just checked that
folio->_folio_nr_pages is unsigned int, but that will probably be
typecasted to long :). I will switch to unsigned int as its not really
going to go to long for CONFIG_64BIT
>> for (i = 0; i < folio_nr_pages(folio); i++) {
>> entry = page_swap_entry(folio_page(folio, i));
>> if (!test_bit(swp_offset(entry), sis->zeromap))
>> - return false;
>> + return i;
>> }
>> - return true;
>> + return i;
>> }
>>
>> /*
>> @@ -581,6 +587,7 @@ void swap_read_folio(struct folio *folio, bool
>> synchronous,
>> {
>> struct swap_info_struct *sis = swp_swap_info(folio->swap);
>> bool workingset = folio_test_workingset(folio);
>> + long first_non_zero_page_idx;
>> unsigned long pflags;
>> bool in_thrashing;
>>
>> @@ -598,10 +605,19 @@ void swap_read_folio(struct folio *folio, bool
>> synchronous,
>> psi_memstall_enter(&pflags);
>> }
>> delayacct_swapin_start();
>> - if (swap_zeromap_folio_test(folio)) {
>> + first_non_zero_page_idx = swap_zeromap_folio_test(folio);
>> + if (first_non_zero_page_idx == folio_nr_pages(folio)) {
>> folio_zero_fill(folio);
>> folio_mark_uptodate(folio);
>> folio_unlock(folio);
>> + } else if (first_non_zero_page_idx != 0) {
>> + /*
>> + * The case for when only *some* of subpages being
>> swapped-in were recorded
>> + * in sis->zeromap, while the rest are in zswap/disk is
>> currently not handled.
>> + * WARN in this case and return without marking the
>> folio uptodate so that
>> + * an IO error is emitted (e.g. do_swap_page() will sigbus).
>> + */
>> + WARN_ON_ONCE(1);
>> } else if (zswap_load(folio)) {
>> folio_mark_uptodate(folio);
>> folio_unlock(folio);
>>
>>
> This is too much noise for swap_read_folio(). How about adding
> swap_read_folio_zeromap() that takes care of this and decides whether
> or not to call folio_mark_uptodate()?
Sounds good, will do as below. Thanks!
>
> -static bool swap_zeromap_folio_test(struct folio *folio)
> +/*
> + * Return the index of the first subpage which is not zero-filled according to
> + * swap_info_struct->zeromap. If all pages are zero-filled according to
> + * zeromap, it will return folio_nr_pages(folio).
> + */
> +static unsigned int swap_zeromap_folio_test(struct folio *folio)
> {
> struct swap_info_struct *sis = swp_swap_info(folio->swap);
> swp_entry_t entry;
> @@ -243,9 +248,9 @@ static bool swap_zeromap_folio_test(struct folio *folio)
> for (i = 0; i < folio_nr_pages(folio); i++) {
> entry = page_swap_entry(folio_page(folio, i));
> if (!test_bit(swp_offset(entry), sis->zeromap))
> - return false;
> + return i;
> }
> - return true;
> + return i;
> }
>
> /*
> @@ -511,6 +516,25 @@ static void sio_read_complete(struct kiocb *iocb, long ret)
> mempool_free(sio, sio_pool);
> }
>
> +static bool swap_read_folio_zeromap(struct folio *folio)
> +{
> + unsigned int idx = swap_zeromap_folio_test(folio);
> +
> + if (idx == 0)
> + return false;
> +
> + /*
> + * Swapping in a large folio that is partially in the zeromap is not
> + * currently handled. Return true without marking the folio uptodate so
> + * that an IO error is emitted (e.g. do_swap_page() will sigbus).
> + */
> + if (WARN_ON_ONCE(idx < folio_nr_pages(folio)))
> + return true;
> +
> + folio_zero_fill(folio);
> + folio_mark_uptodate(folio);
> + return true
> +}
> +
> static void swap_read_folio_fs(struct folio *folio, struct swap_iocb **plug)
> {
> struct swap_info_struct *sis = swp_swap_info(folio->swap);
> @@ -600,9 +624,7 @@ void swap_read_folio(struct folio *folio, bool synchronous,
> psi_memstall_enter(&pflags);
> }
> delayacct_swapin_start();
> - if (swap_zeromap_folio_test(folio)) {
> - folio_zero_fill(folio);
> - folio_mark_uptodate(folio);
> + if (swap_read_folio_zeromap(folio)) {
> folio_unlock(folio);
> } else if (zswap_load(folio)) {
> folio_mark_uptodate(folio);
next prev parent reply other threads:[~2024-06-11 18:43 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-10 12:15 [PATCH v3 0/2] mm: store zero pages to be swapped out in a bitmap Usama Arif
2024-06-10 12:15 ` [PATCH v3 1/2] " Usama Arif
2024-06-10 13:07 ` Matthew Wilcox
2024-06-10 13:56 ` Usama Arif
2024-06-10 14:06 ` Matthew Wilcox
2024-06-10 14:14 ` Usama Arif
2024-06-10 14:33 ` Usama Arif
2024-06-10 17:57 ` Yosry Ahmed
2024-06-10 18:36 ` Usama Arif
2024-06-10 18:47 ` Yosry Ahmed
2024-06-11 11:49 ` Usama Arif
2024-06-11 15:42 ` Yosry Ahmed
2024-06-11 16:52 ` Usama Arif
2024-06-11 17:51 ` Yosry Ahmed
2024-06-11 18:43 ` Usama Arif [this message]
2024-06-11 18:39 ` Nhat Pham
2024-06-11 18:46 ` Yosry Ahmed
2024-06-11 18:53 ` Nhat Pham
2024-06-11 18:50 ` Usama Arif
2024-06-11 19:33 ` Nhat Pham
2024-06-12 10:42 ` Usama Arif
2024-06-10 12:16 ` [PATCH v3 2/2] mm: remove code to handle same filled pages Usama Arif
2024-06-13 21:21 ` [PATCH v3 0/2] mm: store zero pages to be swapped out in a bitmap Yosry Ahmed
2024-06-14 9:22 ` Usama Arif
2024-06-14 9:28 ` Yosry Ahmed
2024-06-13 21:50 ` Yosry Ahmed
2024-06-13 22:41 ` Shakeel Butt
2024-06-13 22:59 ` Yosry Ahmed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=622bc591-ad14-448e-a9f3-988976fbb98a@gmail.com \
--to=usamaarif642@gmail.com \
--cc=21cnbao@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=chengming.zhou@linux.dev \
--cc=david@redhat.com \
--cc=hannes@cmpxchg.org \
--cc=hughd@google.com \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nphamcs@gmail.com \
--cc=shakeel.butt@linux.dev \
--cc=willy@infradead.org \
--cc=ying.huang@intel.com \
--cc=yosryahmed@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.