linux-mips
[Top] [All Lists]

[RFC] Flush huge TLB

To: linux-mips@linux-mips.org
Subject: [RFC] Flush huge TLB
From: Hillf Danton <dhillf@gmail.com>
Date: Sun, 9 Oct 2011 20:53:57 +0800
Cc: Ralf Baechle <ralf@linux-mips.org>, "Jayachandran C." <jayachandranc@netlogicmicro.com>
Dkim-signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:date:message-id:subject:from:to:cc:content-type; bh=GmbfinFG3O5ZGHcYzjyE1iEYGbOVdh2Vrs5sqV/KF6k=; b=DcLnqZ2iuypdhaMVhMsX93cjeXBTI+rNT9Rkb0/RioT0cDFXrednbGP9mpn1Z/YfJ+ r6U+wO4w7QAMNy9e1EUM/PSPrZTLLAUdiYiJtRGyvn+knmjhnouH9k3i5pu/wEPcVBLK lZbgTvO8uqbOFRn88JoKNh2BCrAin9RT+JrLU=
Sender: linux-mips-bounce@linux-mips.org
When flushing TLB, if @vma is backed by huge page, huge TLB should be flushed,
due to the fact that huge page is defined to be far from normal page, and the
flushing is shorten a bit.

Any comment is welcome.

Thanks

Signed-off-by: Hillf Danton <dhillf@gmail.com>
---

--- a/arch/mips/mm/tlb-r4k.c    Mon May 30 21:17:04 2011
+++ b/arch/mips/mm/tlb-r4k.c    Sun Oct  9 20:50:06 2011
@@ -120,22 +120,35 @@ void local_flush_tlb_range(struct vm_are

        if (cpu_context(cpu, mm) != 0) {
                unsigned long size, flags;
+               int huge = is_vm_hugetlb_page(vma);

                ENTER_CRITICAL(flags);
-               size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
-               size = (size + 1) >> 1;
+               if (huge) {
+                       size = (end - start) / HPAGE_SIZE;
+               } else {
+                       size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
+                       size = (size + 1) >> 1;
+               }
                if (size <= current_cpu_data.tlbsize/2) {
                        int oldpid = read_c0_entryhi();
                        int newpid = cpu_asid(cpu, mm);

-                       start &= (PAGE_MASK << 1);
-                       end += ((PAGE_SIZE << 1) - 1);
-                       end &= (PAGE_MASK << 1);
+                       if (huge) {
+                               start &= HPAGE_MASK;
+                               end &= HPAGE_MASK;
+                       } else {
+                               start &= (PAGE_MASK << 1);
+                               end += ((PAGE_SIZE << 1) - 1);
+                               end &= (PAGE_MASK << 1);
+                       }
                        while (start < end) {
                                int idx;

                                write_c0_entryhi(start | newpid);
-                               start += (PAGE_SIZE << 1);
+                               if (huge)
+                                       start += HPAGE_SIZE;
+                               else
+                                       start += (PAGE_SIZE << 1);
                                mtc0_tlbw_hazard();
                                tlb_probe();
                                tlb_probe_hazard();

<Prev in Thread] Current Thread [Next in Thread>