|
@@ -30,6 +30,11 @@ static void list_lru_unregister(struct list_lru *lru)
|
|
|
mutex_unlock(&list_lrus_mutex);
|
|
|
}
|
|
|
|
|
|
+static int lru_shrinker_id(struct list_lru *lru)
|
|
|
+{
|
|
|
+ return lru->shrinker_id;
|
|
|
+}
|
|
|
+
|
|
|
static inline bool list_lru_memcg_aware(struct list_lru *lru)
|
|
|
{
|
|
|
/*
|
|
@@ -93,6 +98,11 @@ static void list_lru_unregister(struct list_lru *lru)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
+static int lru_shrinker_id(struct list_lru *lru)
|
|
|
+{
|
|
|
+ return -1;
|
|
|
+}
|
|
|
+
|
|
|
static inline bool list_lru_memcg_aware(struct list_lru *lru)
|
|
|
{
|
|
|
return false;
|
|
@@ -118,13 +128,17 @@ bool list_lru_add(struct list_lru *lru, struct list_head *item)
|
|
|
{
|
|
|
int nid = page_to_nid(virt_to_page(item));
|
|
|
struct list_lru_node *nlru = &lru->node[nid];
|
|
|
+ struct mem_cgroup *memcg;
|
|
|
struct list_lru_one *l;
|
|
|
|
|
|
spin_lock(&nlru->lock);
|
|
|
if (list_empty(item)) {
|
|
|
- l = list_lru_from_kmem(nlru, item, NULL);
|
|
|
+ l = list_lru_from_kmem(nlru, item, &memcg);
|
|
|
list_add_tail(item, &l->list);
|
|
|
- l->nr_items++;
|
|
|
+ /* Set shrinker bit if the first element was added */
|
|
|
+ if (!l->nr_items++)
|
|
|
+ memcg_set_shrinker_bit(memcg, nid,
|
|
|
+ lru_shrinker_id(lru));
|
|
|
nlru->nr_items++;
|
|
|
spin_unlock(&nlru->lock);
|
|
|
return true;
|
|
@@ -507,6 +521,7 @@ static void memcg_drain_list_lru_node(struct list_lru *lru, int nid,
|
|
|
struct list_lru_node *nlru = &lru->node[nid];
|
|
|
int dst_idx = dst_memcg->kmemcg_id;
|
|
|
struct list_lru_one *src, *dst;
|
|
|
+ bool set;
|
|
|
|
|
|
/*
|
|
|
* Since list_lru_{add,del} may be called under an IRQ-safe lock,
|
|
@@ -518,7 +533,10 @@ static void memcg_drain_list_lru_node(struct list_lru *lru, int nid,
|
|
|
dst = list_lru_from_memcg_idx(nlru, dst_idx);
|
|
|
|
|
|
list_splice_init(&src->list, &dst->list);
|
|
|
+ set = (!dst->nr_items && src->nr_items);
|
|
|
dst->nr_items += src->nr_items;
|
|
|
+ if (set)
|
|
|
+ memcg_set_shrinker_bit(dst_memcg, nid, lru_shrinker_id(lru));
|
|
|
src->nr_items = 0;
|
|
|
|
|
|
spin_unlock_irq(&nlru->lock);
|