On Tue, May 15, 2018 at 11:55:04AM +0300, Kirill Tkhai wrote:
> >> @@ -586,8 +586,23 @@ static unsigned long shrink_slab_memcg(gfp_t 
> >> gfp_mask, int nid,
> >>                    continue;
> >>  
> >>            ret = do_shrink_slab(&sc, shrinker, priority);
> >> -          if (ret == SHRINK_EMPTY)
> >> -                  ret = 0;
> >> +          if (ret == SHRINK_EMPTY) {
> >> +                  clear_bit(i, map->map);
> >> +                  /*
> >> +                   * Pairs with mb in memcg_set_shrinker_bit():
> >> +                   *
> >> +                   * list_lru_add()     shrink_slab_memcg()
> >> +                   *   list_add_tail()    clear_bit()
> >> +                   *   <MB>               <MB>
> >> +                   *   set_bit()          do_shrink_slab()
> >> +                   */
> > 
> > Please improve the comment so that it isn't just a diagram.
> 
> Please, say, which comment you want to see here.

I want the reader to understand why we need to invoke the shrinker twice
if it returns SHRINK_EMPTY. The diagram doesn't really help here IMO. So
I'd write Something like this:

        ret = do_shrink_slab(&sc, shrinker, priority);
        if (ret == SHRINK_EMPTY) {
                clear_bit(i, map->map);
                /*
                 * After the shrinker reported that it had no objects to free,
                 * but before we cleared the corresponding bit in the memcg
                 * shrinker map, a new object might have been added. To make
                 * sure, we have the bit set in this case, we invoke the
                 * shrinker one more time and re-set the bit if it reports that
                 * it is not empty anymore. The memory barrier here pairs with
                 * the barrier in memcg_set_shrinker_bit():
                 *
                 * list_lru_add()     shrink_slab_memcg()
                 *   list_add_tail()    clear_bit()
                 *   <MB>               <MB>
                 *   set_bit()          do_shrink_slab()
                 */
                smp_mb__after_atomic();
                ret = do_shrink_slab(&sc, shrinker, priority);
                        if (ret == SHRINK_EMPTY)
                                ret = 0;
                        else
                                memcg_set_shrinker_bit(memcg, nid, i);

Reply via email to