driver core: auxiliary bus: Remove unneeded module bits
[linux-2.6-microblaze.git] / mm / memcontrol.c
index ed5cc78..e064ac0 100644 (file)
@@ -1047,29 +1047,6 @@ struct mem_cgroup *get_mem_cgroup_from_mm(struct mm_struct *mm)
 }
 EXPORT_SYMBOL(get_mem_cgroup_from_mm);
 
-/**
- * get_mem_cgroup_from_page: Obtain a reference on given page's memcg.
- * @page: page from which memcg should be extracted.
- *
- * Obtain a reference on page->memcg and returns it if successful. Otherwise
- * root_mem_cgroup is returned.
- */
-struct mem_cgroup *get_mem_cgroup_from_page(struct page *page)
-{
-       struct mem_cgroup *memcg = page_memcg(page);
-
-       if (mem_cgroup_disabled())
-               return NULL;
-
-       rcu_read_lock();
-       /* Page should not get uncharged and freed memcg under us. */
-       if (!memcg || WARN_ON_ONCE(!css_tryget(&memcg->css)))
-               memcg = root_mem_cgroup;
-       rcu_read_unlock();
-       return memcg;
-}
-EXPORT_SYMBOL(get_mem_cgroup_from_page);
-
 static __always_inline struct mem_cgroup *active_memcg(void)
 {
        if (in_interrupt())
@@ -1084,13 +1061,9 @@ static __always_inline struct mem_cgroup *get_active_memcg(void)
 
        rcu_read_lock();
        memcg = active_memcg();
-       if (memcg) {
-               /* current->active_memcg must hold a ref. */
-               if (WARN_ON_ONCE(!css_tryget(&memcg->css)))
-                       memcg = root_mem_cgroup;
-               else
-                       memcg = current->active_memcg;
-       }
+       /* remote memcg must hold a ref. */
+       if (memcg && WARN_ON_ONCE(!css_tryget(&memcg->css)))
+               memcg = root_mem_cgroup;
        rcu_read_unlock();
 
        return memcg;
@@ -3314,24 +3287,21 @@ void obj_cgroup_uncharge(struct obj_cgroup *objcg, size_t size)
 
 #endif /* CONFIG_MEMCG_KMEM */
 
-#ifdef CONFIG_TRANSPARENT_HUGEPAGE
 /*
- * Because page_memcg(head) is not set on compound tails, set it now.
+ * Because page_memcg(head) is not set on tails, set it now.
  */
-void mem_cgroup_split_huge_fixup(struct page *head)
+void split_page_memcg(struct page *head, unsigned int nr)
 {
        struct mem_cgroup *memcg = page_memcg(head);
        int i;
 
-       if (mem_cgroup_disabled())
+       if (mem_cgroup_disabled() || !memcg)
                return;
 
-       for (i = 1; i < HPAGE_PMD_NR; i++) {
-               css_get(&memcg->css);
-               head[i].memcg_data = (unsigned long)memcg;
-       }
+       for (i = 1; i < nr; i++)
+               head[i].memcg_data = head->memcg_data;
+       css_get_many(&memcg->css, nr - 1);
 }
-#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
 #ifdef CONFIG_MEMCG_SWAP
 /**
@@ -6771,7 +6741,19 @@ int mem_cgroup_charge(struct page *page, struct mm_struct *mm, gfp_t gfp_mask)
        memcg_check_events(memcg, page);
        local_irq_enable();
 
-       if (PageSwapCache(page)) {
+       /*
+        * Cgroup1's unified memory+swap counter has been charged with the
+        * new swapcache page, finish the transfer by uncharging the swap
+        * slot. The swap slot would also get uncharged when it dies, but
+        * it can stick around indefinitely and we'd count the page twice
+        * the entire time.
+        *
+        * Cgroup2 has separate resource counters for memory and swap,
+        * so this is a non-issue here. Memory and swap charge lifetimes
+        * correspond 1:1 to page and swap slot lifetimes: we charge the
+        * page to memory here, and uncharge swap when the slot is freed.
+        */
+       if (do_memsw_account() && PageSwapCache(page)) {
                swp_entry_t entry = { .val = page_private(page) };
                /*
                 * The swap entry might not get freed for a long time,
@@ -6862,31 +6844,6 @@ static void uncharge_page(struct page *page, struct uncharge_gather *ug)
        css_put(&ug->memcg->css);
 }
 
-static void uncharge_list(struct list_head *page_list)
-{
-       struct uncharge_gather ug;
-       struct list_head *next;
-
-       uncharge_gather_clear(&ug);
-
-       /*
-        * Note that the list can be a single page->lru; hence the
-        * do-while loop instead of a simple list_for_each_entry().
-        */
-       next = page_list->next;
-       do {
-               struct page *page;
-
-               page = list_entry(next, struct page, lru);
-               next = page->lru.next;
-
-               uncharge_page(page, &ug);
-       } while (next != page_list);
-
-       if (ug.memcg)
-               uncharge_batch(&ug);
-}
-
 /**
  * mem_cgroup_uncharge - uncharge a page
  * @page: page to uncharge
@@ -6918,11 +6875,17 @@ void mem_cgroup_uncharge(struct page *page)
  */
 void mem_cgroup_uncharge_list(struct list_head *page_list)
 {
+       struct uncharge_gather ug;
+       struct page *page;
+
        if (mem_cgroup_disabled())
                return;
 
-       if (!list_empty(page_list))
-               uncharge_list(page_list);
+       uncharge_gather_clear(&ug);
+       list_for_each_entry(page, page_list, lru)
+               uncharge_page(page, &ug);
+       if (ug.memcg)
+               uncharge_batch(&ug);
 }
 
 /**