Memory controller: memory accounting
[linux-2.6.git] / mm / swap_state.c
index ec42f01..f96e3ff 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/backing-dev.h>
 #include <linux/pagevec.h>
 #include <linux/migrate.h>
+#include <linux/memcontrol.h>
 
 #include <asm/pgtable.h>
 
@@ -76,6 +77,11 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask)
        BUG_ON(PagePrivate(page));
        error = radix_tree_preload(gfp_mask);
        if (!error) {
+
+               error = mem_cgroup_charge(page, current->mm);
+               if (error)
+                       goto out;
+
                write_lock_irq(&swapper_space.tree_lock);
                error = radix_tree_insert(&swapper_space.page_tree,
                                                entry.val, page);
@@ -86,10 +92,13 @@ int add_to_swap_cache(struct page *page, swp_entry_t entry, gfp_t gfp_mask)
                        total_swapcache_pages++;
                        __inc_zone_page_state(page, NR_FILE_PAGES);
                        INC_CACHE_INFO(add_total);
+               } else {
+                       mem_cgroup_uncharge_page(page);
                }
                write_unlock_irq(&swapper_space.tree_lock);
                radix_tree_preload_end();
        }
+out:
        return error;
 }
 
@@ -104,6 +113,7 @@ void __delete_from_swap_cache(struct page *page)
        BUG_ON(PageWriteback(page));
        BUG_ON(PagePrivate(page));
 
+       mem_cgroup_uncharge_page(page);
        radix_tree_delete(&swapper_space.page_tree, page_private(page));
        set_page_private(page, 0);
        ClearPageSwapCache(page);