From: Yosry Ahmed <yosryahmed@google.com>
To: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
Cc: vitaly.wool@konsulko.com, minchan@kernel.org,
senozhatsky@chromium.org, linux-mm@kvack.org, ddstreet@ieee.org,
sjenning@redhat.com, nphamcs@gmail.com, hannes@cmpxchg.org,
akpm@linux-foundation.org, linux-kernel@vger.kernel.org,
kernel-team@meta.com
Subject: Re: [RFC PATCH v2 6/7] mm: zswap: simplify writeback function
Date: Fri, 9 Jun 2023 04:01:46 -0700 [thread overview]
Message-ID: <CAJD7tkaHn8y6TsmOxwFWhCkhf9Sy++=3sN9x937EzKzHYbz5TA@mail.gmail.com> (raw)
In-Reply-To: <CA+CLi1iJ=PCoQJx_qF1tOnR61jXBXpLoNJUsFrtxaoFUC51OHQ@mail.gmail.com>
On Fri, Jun 9, 2023 at 3:23 AM Domenico Cerasuolo
<cerasuolodomenico@gmail.com> wrote:
>
> On Wed, Jun 7, 2023 at 11:27 AM Yosry Ahmed <yosryahmed@google.com> wrote:
> >
> > On Tue, Jun 6, 2023 at 7:56 AM Domenico Cerasuolo
> > <cerasuolodomenico@gmail.com> wrote:
> > >
> > > Previously, in zswap, the writeback function was passed to zpool drivers
> > > for their usage in calling the writeback operation. However, since the
> > > drivers did not possess references to entries and the function was
> > > specifically designed to work with handles, the writeback process has
> > > been modified to occur directly within zswap. Consequently, this change
> > > allows for some simplification of the writeback function, taking into
> > > account the updated workflow.
> > >
> > > Signed-off-by: Domenico Cerasuolo <cerasuolodomenico@gmail.com>
> > > ---
> > > mm/zswap.c | 69 ++++++++++++++----------------------------------------
> > > 1 file changed, 17 insertions(+), 52 deletions(-)
> > >
> > > diff --git a/mm/zswap.c b/mm/zswap.c
> > > index 2831bf56b168..ef8604812352 100644
> > > --- a/mm/zswap.c
> > > +++ b/mm/zswap.c
> > > @@ -250,7 +250,8 @@ static bool zswap_has_pool;
> > > pr_debug("%s pool %s/%s\n", msg, (p)->tfm_name, \
> > > zpool_get_type((p)->zpool))
> > >
> > > -static int zswap_writeback_entry(struct zpool *pool, unsigned long handle);
> > > +static int zswap_writeback_entry(struct zswap_entry *entry, struct zswap_header *zhdr,
> > > + struct zswap_tree *tree);
> > > static int zswap_pool_get(struct zswap_pool *pool);
> > > static void zswap_pool_put(struct zswap_pool *pool);
> > >
> > > @@ -632,15 +633,21 @@ static int zswap_shrink(struct zswap_pool *pool)
> > > }
> > > spin_unlock(&tree->lock);
> > >
> > > - ret = zswap_writeback_entry(pool->zpool, lru_entry->handle);
> > > + ret = zswap_writeback_entry(lru_entry, zhdr, tree);
> > >
> > > spin_lock(&tree->lock);
> > > if (ret) {
> > > spin_lock(&pool->lru_lock);
> > > list_move(&lru_entry->lru, &pool->lru);
> > > spin_unlock(&pool->lru_lock);
> > > + zswap_entry_put(tree, tree_entry);
> > > + } else {
> > > + /* free the local reference */
> > > + zswap_entry_put(tree, tree_entry);
> > > + /* free the entry if it's not been invalidated*/
> > > + if (lru_entry == zswap_rb_search(&tree->rbroot, swpoffset))
> > > + zswap_entry_put(tree, tree_entry);
> >
> > The comment that was here about the 2 possible cases was useful imo,
> > maybe keep it?
>
> I honestly found it brittle in that we're not interested in the refcount there,
> but rather in releasing the base reference that keeps the entry valid.
> There's not way to know which refcount value it should be though, consider
> that throughout this series the values can be 1 or 0, but also 2 or 1,
> depending on where this function is called (zpool_shrink or zswap_shrink).
Yeah looking at it with fresh eyes makes sense, we want to invalidate
the entry, not really caring about the refcount (see below).
>
> >
> > Also, I am not sure why we need to do a tree search vs. just reading
> > the refcount here before the first put. We can even make
> > zswap_entry_put() return the refcount after the put to know if we need
> > the additional put or not.
> >
> > Can anyone think of any reason why we need to explicitly search the tree here?
>
> I think that the reasoning here is that refcount > 0 doesn't necessarily mean
> that the entry is on the tree. I'm not sure if reading refcount directly here
> would cause an issue now, probably not, but I wonder if bugs could be
> introduced if the context in which this function is called changes.
Yeah I agree. As Johannes suggested, using zswap_invalidate_entry()
(from my exclusive loads patch in mm-unstable) would be best here imo.
>
> >
> > > }
> > > - zswap_entry_put(tree, tree_entry);
> > > spin_unlock(&tree->lock);
> > >
> > > return ret ? -EAGAIN : 0;
> > > @@ -1039,16 +1046,14 @@ static int zswap_get_swap_cache_page(swp_entry_t entry,
> > > * the swap cache, the compressed version stored by zswap can be
> > > * freed.
> > > */
> > > -static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
> > > +static int zswap_writeback_entry(struct zswap_entry *entry, struct zswap_header *zhdr,
> > > + struct zswap_tree *tree)
> > > {
> > > - struct zswap_header *zhdr;
> > > - swp_entry_t swpentry;
> > > - struct zswap_tree *tree;
> > > - pgoff_t offset;
> > > - struct zswap_entry *entry;
> > > + swp_entry_t swpentry = zhdr->swpentry;
> > > struct page *page;
> > > struct scatterlist input, output;
> > > struct crypto_acomp_ctx *acomp_ctx;
> > > + struct zpool *pool = entry->pool->zpool;
> > >
> > > u8 *src, *tmp = NULL;
> > > unsigned int dlen;
> > > @@ -1063,25 +1068,6 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
> > > return -ENOMEM;
> > > }
> > >
> > > - /* extract swpentry from data */
> > > - zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
> > > - swpentry = zhdr->swpentry; /* here */
> > > - tree = zswap_trees[swp_type(swpentry)];
> > > - offset = swp_offset(swpentry);
> > > - zpool_unmap_handle(pool, handle);
> > > -
> > > - /* find and ref zswap entry */
> > > - spin_lock(&tree->lock);
> > > - entry = zswap_entry_find_get(&tree->rbroot, offset);
> > > - if (!entry) {
> > > - /* entry was invalidated */
> > > - spin_unlock(&tree->lock);
> > > - kfree(tmp);
> > > - return 0;
> > > - }
> > > - spin_unlock(&tree->lock);
> > > - BUG_ON(offset != entry->offset);
> > > -
> > > /* try to allocate swap cache page */
> > > switch (zswap_get_swap_cache_page(swpentry, &page)) {
> > > case ZSWAP_SWAPCACHE_FAIL: /* no memory or invalidate happened */
> > > @@ -1115,12 +1101,12 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
> > > acomp_ctx = raw_cpu_ptr(entry->pool->acomp_ctx);
> > > dlen = PAGE_SIZE;
> > >
> > > - zhdr = zpool_map_handle(pool, handle, ZPOOL_MM_RO);
> > > + zhdr = zpool_map_handle(pool, entry->handle, ZPOOL_MM_RO);
> > > src = (u8 *)zhdr + sizeof(struct zswap_header);
> > > if (!zpool_can_sleep_mapped(pool)) {
> > > memcpy(tmp, src, entry->length);
> > > src = tmp;
> > > - zpool_unmap_handle(pool, handle);
> > > + zpool_unmap_handle(pool, entry->handle);
> > > }
> > >
> > > mutex_lock(acomp_ctx->mutex);
> > > @@ -1135,7 +1121,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
> > > if (!zpool_can_sleep_mapped(pool))
> > > kfree(tmp);
> > > else
> > > - zpool_unmap_handle(pool, handle);
> > > + zpool_unmap_handle(pool, entry->handle);
> > >
> > > BUG_ON(ret);
> > > BUG_ON(dlen != PAGE_SIZE);
> > > @@ -1152,23 +1138,7 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
> > > put_page(page);
> > > zswap_written_back_pages++;
> > >
> > > - spin_lock(&tree->lock);
> > > - /* drop local reference */
> > > - zswap_entry_put(tree, entry);
> > > -
> > > - /*
> > > - * There are two possible situations for entry here:
> > > - * (1) refcount is 1(normal case), entry is valid and on the tree
> > > - * (2) refcount is 0, entry is freed and not on the tree
> > > - * because invalidate happened during writeback
> > > - * search the tree and free the entry if find entry
> > > - */
> > > - if (entry == zswap_rb_search(&tree->rbroot, offset))
> > > - zswap_entry_put(tree, entry);
> > > - spin_unlock(&tree->lock);
> > > -
> > > return ret;
> > > -
> > > fail:
> > > if (!zpool_can_sleep_mapped(pool))
> > > kfree(tmp);
> > > @@ -1177,13 +1147,8 @@ static int zswap_writeback_entry(struct zpool *pool, unsigned long handle)
> > > * if we get here due to ZSWAP_SWAPCACHE_EXIST
> > > * a load may be happening concurrently.
> > > * it is safe and okay to not free the entry.
> > > - * if we free the entry in the following put
> > > * it is also okay to return !0
> > > */
> > > - spin_lock(&tree->lock);
> > > - zswap_entry_put(tree, entry);
> > > - spin_unlock(&tree->lock);
> > > -
> > > return ret;
> > > }
> > >
> > > --
> > > 2.34.1
> > >
next prev parent reply other threads:[~2023-06-09 11:02 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20230606145611.704392-1-cerasuolodomenico@gmail.com>
2023-06-07 9:16 ` [RFC PATCH v2 0/7] mm: zswap: move writeback LRU from zpool to zswap Yosry Ahmed
2023-06-07 9:23 ` Domenico Cerasuolo
2023-06-07 9:32 ` Yosry Ahmed
[not found] ` <20230606145611.704392-8-cerasuolodomenico@gmail.com>
2023-06-07 9:30 ` [RFC PATCH v2 7/7] mm: zswap: remove zswap_header Yosry Ahmed
2023-06-09 16:10 ` Domenico Cerasuolo
2023-06-09 17:13 ` Yosry Ahmed
[not found] ` <20230606145611.704392-5-cerasuolodomenico@gmail.com>
2023-06-07 17:23 ` [RFC PATCH v2 4/7] mm: zswap: remove page reclaim logic from zsmalloc Nhat Pham
2023-06-07 17:45 ` Minchan Kim
2023-06-08 16:07 ` Johannes Weiner
[not found] ` <20230606145611.704392-3-cerasuolodomenico@gmail.com>
2023-06-08 16:02 ` [RFC PATCH v2 2/7] mm: zswap: remove page reclaim logic from zbud Johannes Weiner
[not found] ` <20230606145611.704392-4-cerasuolodomenico@gmail.com>
2023-06-08 16:05 ` [RFC PATCH v2 3/7] mm: zswap: remove page reclaim logic from z3fold Johannes Weiner
[not found] ` <20230606145611.704392-7-cerasuolodomenico@gmail.com>
2023-06-07 9:26 ` [RFC PATCH v2 6/7] mm: zswap: simplify writeback function Yosry Ahmed
2023-06-09 10:23 ` Domenico Cerasuolo
2023-06-09 11:01 ` Yosry Ahmed [this message]
2023-06-08 16:48 ` Johannes Weiner
2023-06-09 11:05 ` Domenico Cerasuolo
[not found] ` <20230606145611.704392-2-cerasuolodomenico@gmail.com>
2023-06-07 8:14 ` [RFC PATCH v2 1/7] mm: zswap: add pool shrinking mechanism Yosry Ahmed
2023-06-07 9:22 ` Domenico Cerasuolo
2023-06-07 9:31 ` Yosry Ahmed
2023-06-07 21:39 ` Nhat Pham
2023-06-08 15:58 ` Johannes Weiner
2023-06-08 16:52 ` Johannes Weiner
2023-06-08 17:04 ` Johannes Weiner
2023-06-08 18:45 ` Johannes Weiner
2023-06-09 8:39 ` Domenico Cerasuolo
[not found] ` <20230606145611.704392-6-cerasuolodomenico@gmail.com>
2023-06-07 9:19 ` [RFC PATCH v2 5/7] mm: zswap: remove shrink from zpool interface Yosry Ahmed
2023-06-08 16:10 ` Johannes Weiner
2023-06-08 17:51 ` Nhat Pham
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='CAJD7tkaHn8y6TsmOxwFWhCkhf9Sy++=3sN9x937EzKzHYbz5TA@mail.gmail.com' \
--to=yosryahmed@google.com \
--cc=akpm@linux-foundation.org \
--cc=cerasuolodomenico@gmail.com \
--cc=ddstreet@ieee.org \
--cc=hannes@cmpxchg.org \
--cc=kernel-team@meta.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=minchan@kernel.org \
--cc=nphamcs@gmail.com \
--cc=senozhatsky@chromium.org \
--cc=sjenning@redhat.com \
--cc=vitaly.wool@konsulko.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