From: Chuanhua Han <chuanhuahan@gmail.com>
To: Ryan Roberts <ryan.roberts@arm.com>
Cc: Barry Song <21cnbao@gmail.com>,
akpm@linux-foundation.org, linux-mm@kvack.org,
chengming.zhou@linux.dev, chrisl@kernel.org, david@redhat.com,
hannes@cmpxchg.org, kasong@tencent.com,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, mhocko@suse.com,
nphamcs@gmail.com, shy828301@gmail.com, steven.price@arm.com,
surenb@google.com, wangkefeng.wang@huawei.com,
willy@infradead.org, xiang@kernel.org, ying.huang@intel.com,
yosryahmed@google.com, yuzhao@google.com,
Chuanhua Han <hanchuanhua@oppo.com>,
Barry Song <v-songbaohua@oppo.com>
Subject: Re: [RFC PATCH v3 2/5] mm: swap: introduce swap_nr_free() for batched swap_free()
Date: Mon, 18 Mar 2024 09:28:15 +0800 [thread overview]
Message-ID: <CANzGp4KY1z-EJVp+oYV9Ku7c=z=-gJMRt1wdYzKOMbKrLepizA@mail.gmail.com> (raw)
In-Reply-To: <76c16222-78fd-4d96-b9f7-13264bb37747@arm.com>
Ryan Roberts <ryan.roberts@arm.com> 于2024年3月15日周五 18:57写道:
>
> On 15/03/2024 08:34, Chuanhua Han wrote:
> > Ryan Roberts <ryan.roberts@arm.com> 于2024年3月14日周四 21:43写道:
> >>
> >> On 14/03/2024 13:12, Chuanhua Han wrote:
> >>> Ryan Roberts <ryan.roberts@arm.com> 于2024年3月12日周二 02:51写道:
> >>>>
> >>>> On 04/03/2024 08:13, Barry Song wrote:
> >>>>> From: Chuanhua Han <hanchuanhua@oppo.com>
> >>>>>
> >>>>> While swapping in a large folio, we need to free swaps related to the whole
> >>>>> folio. To avoid frequently acquiring and releasing swap locks, it is better
> >>>>> to introduce an API for batched free.
> >>>>>
> >>>>> Signed-off-by: Chuanhua Han <hanchuanhua@oppo.com>
> >>>>> Co-developed-by: Barry Song <v-songbaohua@oppo.com>
> >>>>> Signed-off-by: Barry Song <v-songbaohua@oppo.com>
> >>>>> ---
> >>>>> include/linux/swap.h | 6 ++++++
> >>>>> mm/swapfile.c | 35 +++++++++++++++++++++++++++++++++++
> >>>>> 2 files changed, 41 insertions(+)
> >>>>>
> >>>>> diff --git a/include/linux/swap.h b/include/linux/swap.h
> >>>>> index 2955f7a78d8d..d6ab27929458 100644
> >>>>> --- a/include/linux/swap.h
> >>>>> +++ b/include/linux/swap.h
> >>>>> @@ -481,6 +481,7 @@ extern void swap_shmem_alloc(swp_entry_t);
> >>>>> extern int swap_duplicate(swp_entry_t);
> >>>>> extern int swapcache_prepare(swp_entry_t);
> >>>>> extern void swap_free(swp_entry_t);
> >>>>> +extern void swap_nr_free(swp_entry_t entry, int nr_pages);
> >>>>
> >>>> nit: In my swap-out v4 series, I've created a batched version of
> >>>> free_swap_and_cache() and called it free_swap_and_cache_nr(). Perhaps it is
> >>>> preferable to align the naming schemes - i.e. call this swap_free_nr(). Your
> >>>> scheme doesn't really work when applied to free_swap_and_cache().
> >>> Thanks for your suggestions, and for the next version, we'll see which
> >>> package is more appropriate!
> >>>>
> >>>>> extern void swapcache_free_entries(swp_entry_t *entries, int n);
> >>>>> extern int free_swap_and_cache(swp_entry_t);
> >>>>> int swap_type_of(dev_t device, sector_t offset);
> >>>>> @@ -561,6 +562,11 @@ static inline void swap_free(swp_entry_t swp)
> >>>>> {
> >>>>> }
> >>>>>
> >>>>> +void swap_nr_free(swp_entry_t entry, int nr_pages)
> >>>>> +{
> >>>>> +
> >>>>> +}
> >>>>> +
> >>>>> static inline void put_swap_folio(struct folio *folio, swp_entry_t swp)
> >>>>> {
> >>>>> }
> >>>>> diff --git a/mm/swapfile.c b/mm/swapfile.c
> >>>>> index 3f594be83b58..244106998a69 100644
> >>>>> --- a/mm/swapfile.c
> >>>>> +++ b/mm/swapfile.c
> >>>>> @@ -1341,6 +1341,41 @@ void swap_free(swp_entry_t entry)
> >>>>> __swap_entry_free(p, entry);
> >>>>> }
> >>>>>
> >>>>> +/*
> >>>>> + * Called after swapping in a large folio, batched free swap entries
> >>>>> + * for this large folio, entry should be for the first subpage and
> >>>>> + * its offset is aligned with nr_pages
> >>>>> + */
> >>>>> +void swap_nr_free(swp_entry_t entry, int nr_pages)
> >>>>> +{
> >>>>> + int i;
> >>>>> + struct swap_cluster_info *ci;
> >>>>> + struct swap_info_struct *p;
> >>>>> + unsigned type = swp_type(entry);
> >>>>
> >>>> nit: checkpatch.py will complain about bare "unsigned", preferring "unsigned
> >>>> int" or at least it did for me when I did something similar in my swap-out patch
> >>>> set.
> >>> Gee, thanks for pointing that out!
> >>>>
> >>>>> + unsigned long offset = swp_offset(entry);
> >>>>> + DECLARE_BITMAP(usage, SWAPFILE_CLUSTER) = { 0 };
> >>>>
> >>>> I don't love this, as it could blow the stack if SWAPFILE_CLUSTER ever
> >>>> increases. But the only other way I can think of is to explicitly loop over
> >>>> fixed size chunks, and that's not much better.
> >>> Is it possible to save kernel stack better by using bit_map here? If
> >>> SWAPFILE_CLUSTER=512, we consume only (512/64)*8= 64 bytes.
> >>
> >> I'm not sure I've understood what you are saying? You're already using
> >> DECLARE_BITMAP(), so its already consuming 64 bytes if SWAPFILE_CLUSTER=512, no?
> >>
> >> I actually did a bad job of trying to express a couple of different points:
> >>
> >> - Are there any configurations today where SWAPFILE_CLUSTER > 512? I'm not sure.
> >> Certainly not for arm64, but not sure about other architectures. For example if
> >> an arch had 64K pages with 8192 entries per THP and supports SWAP_THP, that's 1K
> >> for the bitmap, which is now looking pretty big for the stack.
> > I agree with you.The current bit_map grows linearly with the
> > SWAPFILE_CLUSTER, which may cause the kernel stack to swell.
> > I need to think of a way to save more memory .
> >>
> >> - Would it be better to decouple stack usage from SWAPFILE_CLUSTER and instead
> >> define a fixed stack size (e.g. 64 bytes -> 512 entries). Then free the range of
> >> entries in batches no bigger than this size. This approach could also allow
> >> removing the constraint that the range has to be aligned and fit in a single
> >> cluster. Personally I think an approach like this would be much more robust, in
> >> return for a tiny bit more complexity.
> > Because we cannot determine how many swap entries a cluster has in an
> > architecture or a configuration, we do not know how large the variable
> > needs to be defined?
>
> My point is that we could define a fixed size, then loop through the passed in
> range, operating on batches of that fixed size. You could even take into
> consideration the cluster boundaries so that you take the correct lock for every
> batch and can drop the "must be naturally aligned, must be no bigger than
> cluster size" constraint.
Thank you. I understand it!
>
>
> >>
> >>>>
> >>>>> +
> >>>>> + /* all swap entries are within a cluster for mTHP */
> >>>>> + VM_BUG_ON(offset % SWAPFILE_CLUSTER + nr_pages > SWAPFILE_CLUSTER);
> >>>>> +
> >>>>> + if (nr_pages == 1) {
> >>>>> + swap_free(entry);
> >>>>> + return;
> >>>>> + }
> >>>>> +
> >>>>> + p = _swap_info_get(entry);
> >>>>
> >>>> You need to handle this returning NULL, like swap_free() does.
> >>> Yes, you're right! We did forget to judge NULL here.
> >>>>
> >>>>> +
> >>>>> + ci = lock_cluster(p, offset);
> >>>>
> >>>> The existing swap_free() calls lock_cluster_or_swap_info(). So if swap is backed
> >>>> by rotating media, and clusters are not in use, it will lock the whole swap
> >>>> info. But your new version only calls lock_cluster() which won't lock anything
> >>>> if clusters are not in use. So I think this is a locking bug.
> >>> Again, you're right, it's bug!
> >>>>
> >>>>> + for (i = 0; i < nr_pages; i++) {
> >>>>> + if (__swap_entry_free_locked(p, offset + i, 1))
> >>>>> + __bitmap_set(usage, i, 1);
> >>>>> + }
> >>>>> + unlock_cluster(ci);
> >>>>> +
> >>>>> + for_each_clear_bit(i, usage, nr_pages)
> >>>>> + free_swap_slot(swp_entry(type, offset + i));
> >>>>> +}
> >>>>> +
> >>>>> /*
> >>>>> * Called after dropping swapcache to decrease refcnt to swap entries.
> >>>>> */
> >>>>
> >>>> Thanks,
> >>>> Ryan
> >>>>
> >>>>
> >>>
> >>>
> >>
> >
> >
>
--
Thanks,
Chuanhua
next prev parent reply other threads:[~2024-03-18 1:28 UTC|newest]
Thread overview: 59+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-03-04 8:13 [RFC PATCH v3 0/5] mm: support large folios swap-in Barry Song
2024-03-04 8:13 ` [RFC PATCH v3 1/5] arm64: mm: swap: support THP_SWAP on hardware with MTE Barry Song
2024-03-11 16:55 ` Ryan Roberts
2024-03-21 8:42 ` Barry Song
2024-03-21 10:31 ` Ryan Roberts
2024-03-21 10:43 ` Barry Song
2024-03-22 2:51 ` Barry Song
2024-03-22 7:41 ` Barry Song
2024-03-22 10:19 ` Ryan Roberts
2024-03-23 2:15 ` Chris Li
2024-03-23 3:50 ` Barry Song
2024-03-04 8:13 ` [RFC PATCH v3 2/5] mm: swap: introduce swap_nr_free() for batched swap_free() Barry Song
2024-03-11 18:51 ` Ryan Roberts
2024-03-14 13:12 ` Chuanhua Han
2024-03-14 13:43 ` Ryan Roberts
2024-03-15 8:34 ` Chuanhua Han
2024-03-15 10:57 ` Ryan Roberts
2024-03-18 1:28 ` Chuanhua Han [this message]
2024-03-04 8:13 ` [RFC PATCH v3 3/5] mm: swap: make should_try_to_free_swap() support large-folio Barry Song
2024-03-12 12:34 ` Ryan Roberts
2024-03-13 2:21 ` Chuanhua Han
2024-03-13 9:09 ` Ryan Roberts
2024-03-13 9:24 ` Chuanhua Han
2024-03-04 8:13 ` [RFC PATCH v3 4/5] mm: swap: introduce swapcache_prepare_nr and swapcache_clear_nr for large folios swap-in Barry Song
2024-03-12 15:35 ` Ryan Roberts
2024-03-18 22:35 ` Barry Song
2024-03-04 8:13 ` [RFC PATCH v3 5/5] mm: support large folios swapin as a whole Barry Song
2024-03-12 16:33 ` Ryan Roberts
2024-03-14 12:56 ` Chuanhua Han
2024-03-14 13:57 ` Ryan Roberts
2024-03-14 20:43 ` Barry Song
2024-03-15 10:59 ` Ryan Roberts
2024-03-15 1:16 ` Chuanhua Han
2024-06-10 20:43 ` Shakeel Butt
2024-06-11 0:23 ` Barry Song
2024-06-11 17:24 ` Shakeel Butt
2024-06-11 22:13 ` Barry Song
2024-03-15 8:41 ` Huang, Ying
2024-03-15 8:54 ` Barry Song
2024-03-15 9:15 ` Huang, Ying
2024-03-15 10:01 ` Barry Song
2024-03-15 12:06 ` Ryan Roberts
2024-03-17 6:11 ` Barry Song
2024-03-18 1:52 ` Huang, Ying
2024-03-18 2:41 ` Barry Song
2024-03-18 16:45 ` Ryan Roberts
2024-03-19 6:27 ` Barry Song
2024-03-19 9:05 ` Ryan Roberts
2024-03-21 9:22 ` Barry Song
2024-03-21 11:13 ` Ryan Roberts
2024-03-19 9:20 ` Huang, Ying
2024-03-19 12:19 ` Ryan Roberts
2024-03-20 2:18 ` Huang, Ying
2024-03-20 2:47 ` Barry Song
2024-03-20 6:20 ` Huang, Ying
2024-03-20 18:38 ` Barry Song
2024-03-21 4:23 ` Huang, Ying
2024-03-21 5:12 ` Barry Song
2024-03-21 10:20 ` Barry Song
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='CANzGp4KY1z-EJVp+oYV9Ku7c=z=-gJMRt1wdYzKOMbKrLepizA@mail.gmail.com' \
--to=chuanhuahan@gmail.com \
--cc=21cnbao@gmail.com \
--cc=akpm@linux-foundation.org \
--cc=chengming.zhou@linux.dev \
--cc=chrisl@kernel.org \
--cc=david@redhat.com \
--cc=hanchuanhua@oppo.com \
--cc=hannes@cmpxchg.org \
--cc=kasong@tencent.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mhocko@suse.com \
--cc=nphamcs@gmail.com \
--cc=ryan.roberts@arm.com \
--cc=shy828301@gmail.com \
--cc=steven.price@arm.com \
--cc=surenb@google.com \
--cc=v-songbaohua@oppo.com \
--cc=wangkefeng.wang@huawei.com \
--cc=willy@infradead.org \
--cc=xiang@kernel.org \
--cc=ying.huang@intel.com \
--cc=yosryahmed@google.com \
--cc=yuzhao@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox