/* Heavily inspired by the ppc64 code.  */
 
-DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) =
-       { NULL, 0, 0, 0, 0, 0, { 0 }, { NULL }, };
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, };
 
 void flush_tlb_pending(void)
 {
 
  */
 struct mmu_gather {
        struct mm_struct        *mm;
-       unsigned int            freed;
        unsigned int            fullmm;
-
-       unsigned int            flushes;
-       unsigned int            avoided_flushes;
 };
 
 DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
        struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
 
        tlb->mm = mm;
-       tlb->freed = 0;
        tlb->fullmm = full_mm_flush;
 
        return tlb;
 static inline void
 tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
-       struct mm_struct *mm = tlb->mm;
-       unsigned long freed = tlb->freed;
-       int rss = get_mm_counter(mm, rss);
-
-       if (rss < freed)
-               freed = rss;
-       add_mm_counter(mm, rss, -freed);
-
        if (tlb->fullmm)
-               flush_tlb_mm(mm);
+               flush_tlb_mm(tlb->mm);
 
        /* keep the page table cache within bounds */
        check_pgt_cache();
 
  */
 struct mmu_gather {
         struct mm_struct        *mm;
-        unsigned int            freed;
-       unsigned int            fullmm;
-
-        unsigned int            flushes;
-        unsigned int            avoided_flushes;
+        unsigned int            need_flush;
+        unsigned int            fullmm;
 };
 
 DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
         struct mmu_gather *tlb = &get_cpu_var(mmu_gathers);
 
         tlb->mm = mm;
-        tlb->freed = 0;
-       tlb->fullmm = full_mm_flush;
+        tlb->need_flush = 0;
+        tlb->fullmm = full_mm_flush;
 
         return tlb;
 }
 static inline void
 tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
-        struct mm_struct *mm = tlb->mm;
-        unsigned long freed = tlb->freed;
-        int rss = get_mm_counter(mm, rss);
-
-        if (rss < freed)
-                freed = rss;
-        add_mm_counter(mm, rss, -freed);
-
-        if (freed) {
-                flush_tlb_mm(mm);
-                tlb->flushes++;
-        } else {
-                tlb->avoided_flushes++;
-        }
+        if (tlb->need_flush)
+                flush_tlb_mm(tlb->mm);
 
         /* keep the page table cache within bounds */
         check_pgt_cache();
         } while (0)
 #define tlb_end_vma(tlb,vma)                    do { } while (0)
 
-#define tlb_remove_page(tlb,page)       free_page_and_swap_cache(page)
+static inline void
+tlb_remove_page(struct mmu_gather *tlb, struct page *page)
+{
+        tlb->need_flush = 1;
+        free_page_and_swap_cache(page);
+}
+
 #define pte_free_tlb(tlb,ptep)          pte_free(ptep)
 #define pmd_free_tlb(tlb,pmdp)          pmd_free(pmdp)
 
 
        unsigned int            nr;     /* set to ~0U means fast mode */
        unsigned int            need_flush;/* Really unmapped some ptes? */
        unsigned int            fullmm; /* non-zero means full mm flush */
-       unsigned long           freed;
        struct page *           pages[FREE_PTE_NR];
 };
 
        tlb->nr = num_online_cpus() > 1 ? 0U : ~0U;
 
        tlb->fullmm = full_mm_flush;
-       tlb->freed = 0;
 
        return tlb;
 }
 static inline void
 tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
-       int freed = tlb->freed;
-       struct mm_struct *mm = tlb->mm;
-       int rss = get_mm_counter(mm, rss);
-
-       if (rss < freed)
-               freed = rss;
-       add_mm_counter(mm, rss, -freed);
        tlb_flush_mmu(tlb, start, end);
 
        /* keep the page table cache within bounds */
 
        unsigned int            nr;             /* == ~0U => fast mode */
        unsigned char           fullmm;         /* non-zero means full mm flush */
        unsigned char           need_flush;     /* really unmapped some PTEs? */
-       unsigned long           freed;          /* number of pages freed */
        unsigned long           start_addr;
        unsigned long           end_addr;
        struct page             *pages[FREE_PTE_NR];
         */
        tlb->nr = (num_online_cpus() == 1) ? ~0U : 0;
        tlb->fullmm = full_mm_flush;
-       tlb->freed = 0;
        tlb->start_addr = ~0UL;
        return tlb;
 }
 static inline void
 tlb_finish_mmu (struct mmu_gather *tlb, unsigned long start, unsigned long end)
 {
-       unsigned long freed = tlb->freed;
-       struct mm_struct *mm = tlb->mm;
-       unsigned long rss = get_mm_counter(mm, rss);
-
-       if (rss < freed)
-               freed = rss;
-       add_mm_counter(mm, rss, -freed);
        /*
         * Note: tlb->nr may be 0 at this point, so we can't rely on tlb->start_addr and
         * tlb->end_addr.
 
        unsigned int need_flush;
        unsigned int fullmm;
        unsigned int tlb_nr;
-       unsigned long freed;
        unsigned long vaddrs[TLB_BATCH_NR];
        struct page *pages[FREE_PTE_NR];
 };
        mp->mm = mm;
        mp->pages_nr = num_online_cpus() > 1 ? 0U : ~0U;
        mp->fullmm = full_mm_flush;
-       mp->freed = 0;
 
        return mp;
 }
 
 static inline void tlb_finish_mmu(struct mmu_gather *mp, unsigned long start, unsigned long end)
 {
-       unsigned long freed = mp->freed;
-       struct mm_struct *mm = mp->mm;
-       unsigned long rss = get_mm_counter(mm, rss);
-
-       if (rss < freed)
-               freed = rss;
-       add_mm_counter(mm, rss, -freed);
-
        tlb_flush_mmu(mp);
 
        if (mp->fullmm) {
-               if (CTX_VALID(mm->context))
-                       do_flush_tlb_mm(mm);
+               if (CTX_VALID(mp->mm->context))
+                       do_flush_tlb_mm(mp->mm);
                mp->fullmm = 0;
        } else
                flush_tlb_pending();
 
                                if (pte_young(ptent))
                                        mark_page_accessed(page);
                        }
-                       tlb->freed++;
+                       dec_mm_counter(tlb->mm, rss);
                        page_remove_rmap(page);
                        tlb_remove_page(tlb, page);
                        continue;