Re: [PATCH] zswap: initialize entry->pool on same filled entry

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, Mar 21, 2024 at 8:19 PM Johannes Weiner <hannes@xxxxxxxxxxx> wrote:
>
> On Thu, Mar 21, 2024 at 04:56:05PM -0700, Yosry Ahmed wrote:
> > On Thu, Mar 21, 2024 at 4:53 PM Chris Li <chrisl@xxxxxxxxxx> wrote:
> > >
> > > Current zswap will leave the entry->pool uninitialized if
> > > the page is same  filled. The entry->pool pointer can
> > > contain data written by previous usage.
> > >
> > > Initialize entry->pool to zero for the same filled zswap entry.
> > >
> > > Signed-off-by: Chris Li <chrisl@xxxxxxxxxx>
> > > ---
> > > Per Yosry's suggestion to split out this clean up
> > > from the zxwap rb tree to xarray patch.
> > >
> > > https://lore.kernel.org/all/ZemDuW25YxjqAjm-@xxxxxxxxxx/
> > > ---
> > >  mm/zswap.c | 1 +
> > >  1 file changed, 1 insertion(+)
> > >
> > > diff --git a/mm/zswap.c b/mm/zswap.c
> > > index b31c977f53e9..f04a75a36236 100644
> > > --- a/mm/zswap.c
> > > +++ b/mm/zswap.c
> > > @@ -1527,6 +1527,7 @@ bool zswap_store(struct folio *folio)
> > >                         kunmap_local(src);
> > >                         entry->length = 0;
> > >                         entry->value = value;
> > > +                       entry->pool = 0;
> >
> > This should be NULL.
> >
> > That being said, I am working on a series that should make non-filled
> > entries not use a zswap_entry at all. So I think this cleanup is
> > unnecessary, especially that it is documented in the definition of
> > struct zswap_entry that entry->pool is invalid for same-filled
> > entries.
>
> Yeah I don't think it's necessary to initialize. The field isn't valid
> when it's a same-filled entry, just like `handle` would contain
> nonsense as it's unionized with value.
>
> What would actually be safer is to make the two subtypes explicit, and
> not have unused/ambiguous/overloaded members at all:
>
> struct zswap_entry {
>         unsigned int length;
>         struct obj_cgroup *objcg;
> };
>
> struct zswap_compressed_entry {
>         struct zswap_entry entry;
>         struct zswap_pool *pool;
>         unsigned long handle;
>         struct list_head lru;
>         swp_entry_t swpentry;
> };
>
> struct zswap_samefilled_entry {
>         struct zswap_entry entry;
>         unsigned long value;
> };

I think the 3 struct with embedded and container of is a bit complex,
because the state breaks into different struct members

How about:

struct zswap_entry {
        unsigned int length;
        struct obj_cgroup *objcg;
        union {
                struct /* compressed */ {
                         struct zswap_pool *pool;
                         unsigned long handle;
                         swp_entry_t swpentry;
                         struct list_head lru;
                };
               struct /* same filled */ {
                       unsigned long value;
                };
        };
};

That should have the same effect of the above three structures. Easier
to visualize the containing structure.

What do you say?

Chris

>
> Then put zswap_entry pointers in the tree and use the appropriate
> container_of() calls in just a handful of central places. This would
> limit the the points where mistakes can be made, and suggests how the
> code paths to handle them should split naturally.
>
> Might be useful even with your series, since it disambiguates things
> first, and separates the cleanup bits from any functional changes,
> instead of having to do kind of everything at once...
>





[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux