list_lru: organize all list_lrus to list
[linux-2.6-block.git] / mm / list_lru.c
index 07e198c778888f91f12625aaa44de5735f15bb70..a9021cb3ccdebe7204ef3207106ba33a1b17e145 100644 (file)
@@ -9,6 +9,34 @@
 #include <linux/mm.h>
 #include <linux/list_lru.h>
 #include <linux/slab.h>
+#include <linux/mutex.h>
+
+#ifdef CONFIG_MEMCG_KMEM
+static LIST_HEAD(list_lrus);
+static DEFINE_MUTEX(list_lrus_mutex);
+
+static void list_lru_register(struct list_lru *lru)
+{
+       mutex_lock(&list_lrus_mutex);
+       list_add(&lru->list, &list_lrus);
+       mutex_unlock(&list_lrus_mutex);
+}
+
+static void list_lru_unregister(struct list_lru *lru)
+{
+       mutex_lock(&list_lrus_mutex);
+       list_del(&lru->list);
+       mutex_unlock(&list_lrus_mutex);
+}
+#else
+static void list_lru_register(struct list_lru *lru)
+{
+}
+
+static void list_lru_unregister(struct list_lru *lru)
+{
+}
+#endif /* CONFIG_MEMCG_KMEM */
 
 bool list_lru_add(struct list_lru *lru, struct list_head *item)
 {
@@ -137,12 +165,18 @@ int list_lru_init_key(struct list_lru *lru, struct lock_class_key *key)
                INIT_LIST_HEAD(&lru->node[i].list);
                lru->node[i].nr_items = 0;
        }
+       list_lru_register(lru);
        return 0;
 }
 EXPORT_SYMBOL_GPL(list_lru_init_key);
 
 void list_lru_destroy(struct list_lru *lru)
 {
+       /* Already destroyed or not yet initialized? */
+       if (!lru->node)
+               return;
+       list_lru_unregister(lru);
        kfree(lru->node);
+       lru->node = NULL;
 }
 EXPORT_SYMBOL_GPL(list_lru_destroy);