#define FLUSHALL_BAR   16
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+static inline unsigned long has_large_page(struct mm_struct *mm,
+                                unsigned long start, unsigned long end)
+{
+       pgd_t *pgd;
+       pud_t *pud;
+       pmd_t *pmd;
+       unsigned long addr = ALIGN(start, HPAGE_SIZE);
+       for (; addr < end; addr += HPAGE_SIZE) {
+               pgd = pgd_offset(mm, addr);
+               if (likely(!pgd_none(*pgd))) {
+                       pud = pud_offset(pgd, addr);
+                       if (likely(!pud_none(*pud))) {
+                               pmd = pmd_offset(pud, addr);
+                               if (likely(!pmd_none(*pmd)))
+                                       if (pmd_large(*pmd))
+                                               return addr;
+                       }
+               }
+       }
+       return 0;
+}
+#else
+static inline unsigned long has_large_page(struct mm_struct *mm,
+                                unsigned long start, unsigned long end)
+{
+       return 0;
+}
+#endif
 void flush_tlb_range(struct vm_area_struct *vma,
                                   unsigned long start, unsigned long end)
 {
        struct mm_struct *mm;
 
        if (!cpu_has_invlpg || vma->vm_flags & VM_HUGETLB) {
+flush_all:
                flush_tlb_mm(vma->vm_mm);
                return;
        }
                        if ((end - start)/PAGE_SIZE > act_entries/FLUSHALL_BAR)
                                local_flush_tlb();
                        else {
+                               if (has_large_page(mm, start, end)) {
+                                       preempt_enable();
+                                       goto flush_all;
+                               }
                                for (addr = start; addr < end;
                                                addr += PAGE_SIZE)
                                        __flush_tlb_single(addr);