Re: [PATCH v6 12/16] mm: list_lru: replace linear array with xarray

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

 



On Thu, Mar 31, 2022 at 11:01 PM Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote:
>
> On Mon, Feb 28, 2022 at 08:21:22PM +0800, Muchun Song wrote:
> > @@ -586,27 +508,48 @@ int memcg_list_lru_alloc(struct mem_cgroup *memcg, struct list_lru *lru,
> >               }
> >       }
> >
> > +     xas_lock_irqsave(&xas, flags);
> >       while (i--) {
> > +             int index = READ_ONCE(table[i].memcg->kmemcg_id);
> >               struct list_lru_per_memcg *mlru = table[i].mlru;
> >
> > +             xas_set(&xas, index);
> > +retry:
> > +             if (unlikely(index < 0 || xas_error(&xas) || xas_load(&xas))) {
> >                       kfree(mlru);
> > +             } else {
> > +                     xas_store(&xas, mlru);
> > +                     if (xas_error(&xas) == -ENOMEM) {
> > +                             xas_unlock_irqrestore(&xas, flags);
> > +                             if (xas_nomem(&xas, gfp))
> > +                                     xas_set_err(&xas, 0);
> > +                             xas_lock_irqsave(&xas, flags);
> > +                             /*
> > +                              * The xas lock has been released, this memcg
> > +                              * can be reparented before us. So reload
> > +                              * memcg id. More details see the comments
> > +                              * in memcg_reparent_list_lrus().
> > +                              */
> > +                             index = READ_ONCE(table[i].memcg->kmemcg_id);
> > +                             if (index < 0)
> > +                                     xas_set_err(&xas, 0);
> > +                             else if (!xas_error(&xas) && index != xas.xa_index)
> > +                                     xas_set(&xas, index);
> > +                             goto retry;
> > +                     }
> > +             }
> >       }
> > +     /* xas_nomem() is used to free memory instead of memory allocation. */
> > +     if (xas.xa_alloc)
> > +             xas_nomem(&xas, gfp);
> > +     xas_unlock_irqrestore(&xas, flags);
> >       kfree(table);
> >
> > +     return xas_error(&xas);
> >  }
>
> This is really unidiomatic.  And so much more complicated than it needs
> to be.
>
>         while (i--) {
>                 do {
>                         int index = READ_ONCE(table[i].memcg->kmemcg_id);
>                         struct list_lru_per_memcg *mlru = table[i].mlru;
>
>                         xas_set(&xas, index);
>                         xas_lock_irqsave(&xas, flags);
>                         if (index < 0 || xas_load(&xas))
>                                 xas_set_err(&xas, -EBUSY);
>                         xas_store(&xas, mlru);
>                         if (!xas_error(&xas))
>                                 break;
>                         xas_unlock_irqrestore(&xas, flags);
>                 } while (xas_nomem(&xas, gfp));
>
>                 if (xas_error(&xas))
>                         kfree(mlru);
>         }
>
>         kfree(table);
>         return xas_error(&xas);
>
> (you might want to mask out the EBUSY error here)
>

I'm not familiar with xarray APIs.  I'll dig deeper to see if this code works
properly.  Thanks for your suggestions.



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux