|
@@ -596,8 +596,30 @@ static unsigned long shrink_slab_memcg(gfp_t gfp_mask, int nid,
|
|
continue;
|
|
continue;
|
|
|
|
|
|
ret = do_shrink_slab(&sc, shrinker, priority);
|
|
ret = do_shrink_slab(&sc, shrinker, priority);
|
|
- if (ret == SHRINK_EMPTY)
|
|
|
|
- ret = 0;
|
|
|
|
|
|
+ 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 reset
|
|
|
|
+ * 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);
|
|
|
|
+ }
|
|
freed += ret;
|
|
freed += ret;
|
|
|
|
|
|
if (rwsem_is_contended(&shrinker_rwsem)) {
|
|
if (rwsem_is_contended(&shrinker_rwsem)) {
|