ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / ppc64 / mm / tlb.c
1 /*
2  * This file contains the routines for flushing entries from the
3  * TLB and MMU hash table.
4  *
5  *  Derived from arch/ppc64/mm/init.c:
6  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
7  *
8  *  Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au)
9  *  and Cort Dougan (PReP) (cort@cs.nmt.edu)
10  *    Copyright (C) 1996 Paul Mackerras
11  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
12  *
13  *  Derived from "arch/i386/mm/init.c"
14  *    Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
15  *
16  *  Dave Engebretsen <engebret@us.ibm.com>
17  *      Rework for PPC64 port.
18  *
19  *  This program is free software; you can redistribute it and/or
20  *  modify it under the terms of the GNU General Public License
21  *  as published by the Free Software Foundation; either version
22  *  2 of the License, or (at your option) any later version.
23  */
24 #include <linux/config.h>
25 #include <linux/kernel.h>
26 #include <linux/mm.h>
27 #include <linux/init.h>
28 #include <linux/percpu.h>
29 #include <asm/pgalloc.h>
30 #include <asm/tlbflush.h>
31 #include <asm/tlb.h>
32 #include <asm/hardirq.h>
33 #include <linux/highmem.h>
34 #include <asm/rmap.h>
35
36 DEFINE_PER_CPU(struct ppc64_tlb_batch, ppc64_tlb_batch);
37
38 /* This is declared as we are using the more or less generic
39  * include/asm-ppc64/tlb.h file -- tgall
40  */
41 DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
42 DEFINE_PER_CPU(struct pte_freelist_batch *, pte_freelist_cur);
43 unsigned long pte_freelist_forced_free;
44
45 /*
46  * Update the MMU hash table to correspond with a change to
47  * a Linux PTE.  If wrprot is true, it is permissible to
48  * change the existing HPTE to read-only rather than removing it
49  * (if we remove it we should clear the _PTE_HPTEFLAGS bits).
50  */
51 void hpte_update(pte_t *ptep, unsigned long pte, int wrprot)
52 {
53         struct page *ptepage;
54         struct mm_struct *mm;
55         unsigned long addr;
56         int i;
57         unsigned long context = 0;
58         struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);
59
60         ptepage = virt_to_page(ptep);
61         mm = (struct mm_struct *) ptepage->mapping;
62         addr = ptep_to_address(ptep);
63
64         if (REGION_ID(addr) == USER_REGION_ID)
65                 context = mm->context.id;
66         i = batch->index;
67
68         /*
69          * This can happen when we are in the middle of a TLB batch and
70          * we encounter memory pressure (eg copy_page_range when it tries
71          * to allocate a new pte). If we have to reclaim memory and end
72          * up scanning and resetting referenced bits then our batch context
73          * will change mid stream.
74          */
75         if (unlikely(i != 0 && context != batch->context)) {
76                 flush_tlb_pending();
77                 i = 0;
78         }
79
80         if (i == 0) {
81                 batch->context = context;
82                 batch->mm = mm;
83         }
84         batch->pte[i] = __pte(pte);
85         batch->addr[i] = addr;
86         batch->index = ++i;
87         if (i >= PPC64_TLB_BATCH_NR)
88                 flush_tlb_pending();
89 }
90
91 void __flush_tlb_pending(struct ppc64_tlb_batch *batch)
92 {
93         int i;
94         cpumask_t tmp = cpumask_of_cpu(smp_processor_id());
95         int local = 0;
96
97         BUG_ON(in_interrupt());
98
99         i = batch->index;
100         if (cpus_equal(batch->mm->cpu_vm_mask, tmp))
101                 local = 1;
102
103         if (i == 1)
104                 flush_hash_page(batch->context, batch->addr[0], batch->pte[0],
105                                 local);
106         else
107                 flush_hash_range(batch->context, i, local);
108         batch->index = 0;
109 }
110
111 #ifdef CONFIG_SMP
112 static void pte_free_smp_sync(void *arg)
113 {
114         /* Do nothing, just ensure we sync with all CPUs */
115 }
116 #endif
117
118 /* This is only called when we are critically out of memory
119  * (and fail to get a page in pte_free_tlb).
120  */
121 void pte_free_now(struct page *ptepage)
122 {
123         pte_freelist_forced_free++;
124
125         smp_call_function(pte_free_smp_sync, NULL, 0, 1);
126
127         pte_free(ptepage);
128 }
129
130 static void pte_free_rcu_callback(void *arg)
131 {
132         struct pte_freelist_batch *batch = arg;
133         unsigned int i;
134
135         for (i = 0; i < batch->index; i++)
136                 pte_free(batch->pages[i]);
137         free_page((unsigned long)batch);
138 }
139
140 void pte_free_submit(struct pte_freelist_batch *batch)
141 {
142         INIT_RCU_HEAD(&batch->rcu);
143         call_rcu(&batch->rcu, pte_free_rcu_callback, batch);
144 }
145
146 void pte_free_finish(void)
147 {
148         /* This is safe as we are holding page_table_lock */
149         struct pte_freelist_batch **batchp = &__get_cpu_var(pte_freelist_cur);
150
151         if (*batchp == NULL)
152                 return;
153         pte_free_submit(*batchp);
154         *batchp = NULL;
155 }