2006-10-04 05:01:26 +08:00
|
|
|
/* include/asm-generic/tlb.h
|
2005-04-17 06:20:36 +08:00
|
|
|
*
|
|
|
|
* Generic TLB shootdown code
|
|
|
|
*
|
|
|
|
* Copyright 2001 Red Hat, Inc.
|
|
|
|
* Based on code from mm/memory.c Copyright Linus Torvalds and others.
|
|
|
|
*
|
2011-05-25 08:11:45 +08:00
|
|
|
* Copyright 2011 Red Hat, Inc., Peter Zijlstra <pzijlstr@redhat.com>
|
|
|
|
*
|
2005-04-17 06:20:36 +08:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version
|
|
|
|
* 2 of the License, or (at your option) any later version.
|
|
|
|
*/
|
|
|
|
#ifndef _ASM_GENERIC__TLB_H
|
|
|
|
#define _ASM_GENERIC__TLB_H
|
|
|
|
|
|
|
|
#include <linux/swap.h>
|
2008-02-01 05:05:48 +08:00
|
|
|
#include <asm/pgalloc.h>
|
2005-04-17 06:20:36 +08:00
|
|
|
#include <asm/tlbflush.h>
|
|
|
|
|
2011-05-25 08:12:00 +08:00
|
|
|
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
|
|
/*
|
|
|
|
* Semi RCU freeing of the page directories.
|
|
|
|
*
|
|
|
|
* This is needed by some architectures to implement software pagetable walkers.
|
|
|
|
*
|
|
|
|
* gup_fast() and other software pagetable walkers do a lockless page-table
|
|
|
|
* walk and therefore needs some synchronization with the freeing of the page
|
|
|
|
* directories. The chosen means to accomplish that is by disabling IRQs over
|
|
|
|
* the walk.
|
|
|
|
*
|
|
|
|
* Architectures that use IPIs to flush TLBs will then automagically DTRT,
|
|
|
|
* since we unlink the page, flush TLBs, free the page. Since the disabling of
|
|
|
|
* IRQs delays the completion of the TLB flush we can never observe an already
|
|
|
|
* freed page.
|
|
|
|
*
|
|
|
|
* Architectures that do not have this (PPC) need to delay the freeing by some
|
|
|
|
* other means, this is that means.
|
|
|
|
*
|
|
|
|
* What we do is batch the freed directory pages (tables) and RCU free them.
|
|
|
|
* We use the sched RCU variant, as that guarantees that IRQ/preempt disabling
|
|
|
|
* holds off grace periods.
|
|
|
|
*
|
|
|
|
* However, in order to batch these pages we need to allocate storage, this
|
|
|
|
* allocation is deep inside the MM code and can thus easily fail on memory
|
|
|
|
* pressure. To guarantee progress we fall back to single table freeing, see
|
|
|
|
* the implementation of tlb_remove_table_one().
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
struct mmu_table_batch {
|
|
|
|
struct rcu_head rcu;
|
|
|
|
unsigned int nr;
|
|
|
|
void *tables[0];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MAX_TABLE_BATCH \
|
|
|
|
((PAGE_SIZE - sizeof(struct mmu_table_batch)) / sizeof(void *))
|
|
|
|
|
|
|
|
extern void tlb_table_flush(struct mmu_gather *tlb);
|
|
|
|
extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2011-05-25 08:11:45 +08:00
|
|
|
/*
|
|
|
|
* If we can't allocate a page to make a big batch of page pointers
|
|
|
|
* to work on, then just handle a few from the on-stack structure.
|
|
|
|
*/
|
|
|
|
#define MMU_GATHER_BUNDLE 8
|
|
|
|
|
2011-05-25 08:12:01 +08:00
|
|
|
struct mmu_gather_batch {
|
|
|
|
struct mmu_gather_batch *next;
|
|
|
|
unsigned int nr;
|
|
|
|
unsigned int max;
|
|
|
|
struct page *pages[0];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define MAX_GATHER_BATCH \
|
|
|
|
((PAGE_SIZE - sizeof(struct mmu_gather_batch)) / sizeof(void *))
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
/* struct mmu_gather is an opaque type used by the mm code for passing around
|
2005-10-30 09:16:01 +08:00
|
|
|
* any data needed by arch specific code for tlb_remove_page.
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
|
|
|
struct mmu_gather {
|
|
|
|
struct mm_struct *mm;
|
2011-05-25 08:12:00 +08:00
|
|
|
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
|
|
struct mmu_table_batch *batch;
|
|
|
|
#endif
|
2011-05-25 08:12:01 +08:00
|
|
|
unsigned int need_flush : 1, /* Did free PTEs */
|
|
|
|
fast_mode : 1; /* No batching */
|
|
|
|
|
|
|
|
unsigned int fullmm;
|
|
|
|
|
|
|
|
struct mmu_gather_batch *active;
|
|
|
|
struct mmu_gather_batch local;
|
|
|
|
struct page *__pages[MMU_GATHER_BUNDLE];
|
2005-04-17 06:20:36 +08:00
|
|
|
};
|
|
|
|
|
2011-05-25 08:12:01 +08:00
|
|
|
/*
|
|
|
|
* For UP we don't need to worry about TLB flush
|
|
|
|
* and page free order so much..
|
|
|
|
*/
|
|
|
|
#ifdef CONFIG_SMP
|
|
|
|
#define tlb_fast_mode(tlb) (tlb->fast_mode)
|
|
|
|
#else
|
|
|
|
#define tlb_fast_mode(tlb) 1
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static inline int tlb_next_batch(struct mmu_gather *tlb)
|
2011-05-25 08:11:45 +08:00
|
|
|
{
|
2011-05-25 08:12:01 +08:00
|
|
|
struct mmu_gather_batch *batch;
|
2011-05-25 08:11:45 +08:00
|
|
|
|
2011-05-25 08:12:01 +08:00
|
|
|
batch = tlb->active;
|
|
|
|
if (batch->next) {
|
|
|
|
tlb->active = batch->next;
|
|
|
|
return 1;
|
2011-05-25 08:11:45 +08:00
|
|
|
}
|
2011-05-25 08:12:01 +08:00
|
|
|
|
|
|
|
batch = (void *)__get_free_pages(GFP_NOWAIT | __GFP_NOWARN, 0);
|
|
|
|
if (!batch)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
batch->next = NULL;
|
|
|
|
batch->nr = 0;
|
|
|
|
batch->max = MAX_GATHER_BATCH;
|
|
|
|
|
|
|
|
tlb->active->next = batch;
|
|
|
|
tlb->active = batch;
|
|
|
|
|
|
|
|
return 1;
|
2011-05-25 08:11:45 +08:00
|
|
|
}
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/* tlb_gather_mmu
|
2011-05-25 08:11:45 +08:00
|
|
|
* Called to initialize an (on-stack) mmu_gather structure for page-table
|
|
|
|
* tear-down from @mm. The @fullmm argument is used when @mm is without
|
|
|
|
* users and we're going to destroy the full address space (exit/execve).
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
2011-05-25 08:11:45 +08:00
|
|
|
static inline void
|
|
|
|
tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm, bool fullmm)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
|
|
|
tlb->mm = mm;
|
|
|
|
|
2011-05-25 08:12:01 +08:00
|
|
|
tlb->fullmm = fullmm;
|
|
|
|
tlb->need_flush = 0;
|
|
|
|
tlb->fast_mode = (num_possible_cpus() == 1);
|
|
|
|
tlb->local.next = NULL;
|
|
|
|
tlb->local.nr = 0;
|
|
|
|
tlb->local.max = ARRAY_SIZE(tlb->__pages);
|
|
|
|
tlb->active = &tlb->local;
|
2005-04-17 06:20:36 +08:00
|
|
|
|
2011-05-25 08:12:00 +08:00
|
|
|
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
|
|
tlb->batch = NULL;
|
2011-05-25 08:11:45 +08:00
|
|
|
#endif
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
2011-05-25 08:11:45 +08:00
|
|
|
tlb_flush_mmu(struct mmu_gather *tlb)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2011-05-25 08:12:01 +08:00
|
|
|
struct mmu_gather_batch *batch;
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
if (!tlb->need_flush)
|
|
|
|
return;
|
|
|
|
tlb->need_flush = 0;
|
|
|
|
tlb_flush(tlb);
|
2011-05-25 08:12:00 +08:00
|
|
|
#ifdef CONFIG_HAVE_RCU_TABLE_FREE
|
|
|
|
tlb_table_flush(tlb);
|
|
|
|
#endif
|
2011-05-25 08:12:01 +08:00
|
|
|
|
|
|
|
if (tlb_fast_mode(tlb))
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (batch = &tlb->local; batch; batch = batch->next) {
|
|
|
|
free_pages_and_swap_cache(batch->pages, batch->nr);
|
|
|
|
batch->nr = 0;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2011-05-25 08:12:01 +08:00
|
|
|
tlb->active = &tlb->local;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* tlb_finish_mmu
|
|
|
|
* Called at the end of the shootdown operation to free up any resources
|
2005-10-30 09:16:01 +08:00
|
|
|
* that were required.
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
|
|
|
static inline void
|
|
|
|
tlb_finish_mmu(struct mmu_gather *tlb, unsigned long start, unsigned long end)
|
|
|
|
{
|
2011-05-25 08:12:01 +08:00
|
|
|
struct mmu_gather_batch *batch, *next;
|
|
|
|
|
2011-05-25 08:11:45 +08:00
|
|
|
tlb_flush_mmu(tlb);
|
2005-04-17 06:20:36 +08:00
|
|
|
|
|
|
|
/* keep the page table cache within bounds */
|
|
|
|
check_pgt_cache();
|
2005-10-30 09:16:01 +08:00
|
|
|
|
2011-05-25 08:12:01 +08:00
|
|
|
for (batch = tlb->local.next; batch; batch = next) {
|
|
|
|
next = batch->next;
|
|
|
|
free_pages((unsigned long)batch, 0);
|
|
|
|
}
|
|
|
|
tlb->local.next = NULL;
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
2011-05-25 08:11:45 +08:00
|
|
|
/* __tlb_remove_page
|
2005-04-17 06:20:36 +08:00
|
|
|
* Must perform the equivalent to __free_pte(pte_get_and_clear(ptep)), while
|
|
|
|
* handling the additional races in SMP caused by other CPUs caching valid
|
2011-05-25 08:11:45 +08:00
|
|
|
* mappings in their TLBs. Returns the number of free page slots left.
|
|
|
|
* When out of page slots we must call tlb_flush_mmu().
|
2005-04-17 06:20:36 +08:00
|
|
|
*/
|
2011-05-25 08:11:45 +08:00
|
|
|
static inline int __tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
2005-04-17 06:20:36 +08:00
|
|
|
{
|
2011-05-25 08:12:01 +08:00
|
|
|
struct mmu_gather_batch *batch;
|
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
tlb->need_flush = 1;
|
2011-05-25 08:12:01 +08:00
|
|
|
|
2005-04-17 06:20:36 +08:00
|
|
|
if (tlb_fast_mode(tlb)) {
|
|
|
|
free_page_and_swap_cache(page);
|
2011-05-25 08:11:45 +08:00
|
|
|
return 1; /* avoid calling tlb_flush_mmu() */
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
2011-05-25 08:11:45 +08:00
|
|
|
|
2011-05-25 08:12:01 +08:00
|
|
|
batch = tlb->active;
|
|
|
|
batch->pages[batch->nr++] = page;
|
|
|
|
VM_BUG_ON(batch->nr > batch->max);
|
|
|
|
if (batch->nr == batch->max) {
|
|
|
|
if (!tlb_next_batch(tlb))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return batch->max - batch->nr;
|
2011-05-25 08:11:45 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* tlb_remove_page
|
|
|
|
* Similar to __tlb_remove_page but will call tlb_flush_mmu() itself when
|
|
|
|
* required.
|
|
|
|
*/
|
|
|
|
static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
|
|
|
|
{
|
|
|
|
if (!__tlb_remove_page(tlb, page))
|
|
|
|
tlb_flush_mmu(tlb);
|
2005-04-17 06:20:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* tlb_remove_tlb_entry - remember a pte unmapping for later tlb invalidation.
|
|
|
|
*
|
|
|
|
* Record the fact that pte's were really umapped in ->need_flush, so we can
|
|
|
|
* later optimise away the tlb invalidate. This helps when userspace is
|
|
|
|
* unmapping already-unmapped pages, which happens quite a lot.
|
|
|
|
*/
|
|
|
|
#define tlb_remove_tlb_entry(tlb, ptep, address) \
|
|
|
|
do { \
|
|
|
|
tlb->need_flush = 1; \
|
|
|
|
__tlb_remove_tlb_entry(tlb, ptep, address); \
|
|
|
|
} while (0)
|
|
|
|
|
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
Upcoming paches to support the new 64-bit "BookE" powerpc architecture
will need to have the virtual address corresponding to PTE page when
freeing it, due to the way the HW table walker works.
Basically, the TLB can be loaded with "large" pages that cover the whole
virtual space (well, sort-of, half of it actually) represented by a PTE
page, and which contain an "indirect" bit indicating that this TLB entry
RPN points to an array of PTEs from which the TLB can then create direct
entries. Thus, in order to invalidate those when PTE pages are deleted,
we need the virtual address to pass to tlbilx or tlbivax instructions.
The old trick of sticking it somewhere in the PTE page struct page sucks
too much, the address is almost readily available in all call sites and
almost everybody implemets these as macros, so we may as well add the
argument everywhere. I added it to the pmd and pud variants for consistency.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: David Howells <dhowells@redhat.com> [MN10300 & FRV]
Acked-by: Nick Piggin <npiggin@suse.de>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [s390]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-07-22 13:44:28 +08:00
|
|
|
#define pte_free_tlb(tlb, ptep, address) \
|
2005-04-17 06:20:36 +08:00
|
|
|
do { \
|
|
|
|
tlb->need_flush = 1; \
|
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
Upcoming paches to support the new 64-bit "BookE" powerpc architecture
will need to have the virtual address corresponding to PTE page when
freeing it, due to the way the HW table walker works.
Basically, the TLB can be loaded with "large" pages that cover the whole
virtual space (well, sort-of, half of it actually) represented by a PTE
page, and which contain an "indirect" bit indicating that this TLB entry
RPN points to an array of PTEs from which the TLB can then create direct
entries. Thus, in order to invalidate those when PTE pages are deleted,
we need the virtual address to pass to tlbilx or tlbivax instructions.
The old trick of sticking it somewhere in the PTE page struct page sucks
too much, the address is almost readily available in all call sites and
almost everybody implemets these as macros, so we may as well add the
argument everywhere. I added it to the pmd and pud variants for consistency.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: David Howells <dhowells@redhat.com> [MN10300 & FRV]
Acked-by: Nick Piggin <npiggin@suse.de>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [s390]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-07-22 13:44:28 +08:00
|
|
|
__pte_free_tlb(tlb, ptep, address); \
|
2005-04-17 06:20:36 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#ifndef __ARCH_HAS_4LEVEL_HACK
|
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
Upcoming paches to support the new 64-bit "BookE" powerpc architecture
will need to have the virtual address corresponding to PTE page when
freeing it, due to the way the HW table walker works.
Basically, the TLB can be loaded with "large" pages that cover the whole
virtual space (well, sort-of, half of it actually) represented by a PTE
page, and which contain an "indirect" bit indicating that this TLB entry
RPN points to an array of PTEs from which the TLB can then create direct
entries. Thus, in order to invalidate those when PTE pages are deleted,
we need the virtual address to pass to tlbilx or tlbivax instructions.
The old trick of sticking it somewhere in the PTE page struct page sucks
too much, the address is almost readily available in all call sites and
almost everybody implemets these as macros, so we may as well add the
argument everywhere. I added it to the pmd and pud variants for consistency.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: David Howells <dhowells@redhat.com> [MN10300 & FRV]
Acked-by: Nick Piggin <npiggin@suse.de>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [s390]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-07-22 13:44:28 +08:00
|
|
|
#define pud_free_tlb(tlb, pudp, address) \
|
2005-04-17 06:20:36 +08:00
|
|
|
do { \
|
|
|
|
tlb->need_flush = 1; \
|
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
Upcoming paches to support the new 64-bit "BookE" powerpc architecture
will need to have the virtual address corresponding to PTE page when
freeing it, due to the way the HW table walker works.
Basically, the TLB can be loaded with "large" pages that cover the whole
virtual space (well, sort-of, half of it actually) represented by a PTE
page, and which contain an "indirect" bit indicating that this TLB entry
RPN points to an array of PTEs from which the TLB can then create direct
entries. Thus, in order to invalidate those when PTE pages are deleted,
we need the virtual address to pass to tlbilx or tlbivax instructions.
The old trick of sticking it somewhere in the PTE page struct page sucks
too much, the address is almost readily available in all call sites and
almost everybody implemets these as macros, so we may as well add the
argument everywhere. I added it to the pmd and pud variants for consistency.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: David Howells <dhowells@redhat.com> [MN10300 & FRV]
Acked-by: Nick Piggin <npiggin@suse.de>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [s390]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-07-22 13:44:28 +08:00
|
|
|
__pud_free_tlb(tlb, pudp, address); \
|
2005-04-17 06:20:36 +08:00
|
|
|
} while (0)
|
|
|
|
#endif
|
|
|
|
|
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
Upcoming paches to support the new 64-bit "BookE" powerpc architecture
will need to have the virtual address corresponding to PTE page when
freeing it, due to the way the HW table walker works.
Basically, the TLB can be loaded with "large" pages that cover the whole
virtual space (well, sort-of, half of it actually) represented by a PTE
page, and which contain an "indirect" bit indicating that this TLB entry
RPN points to an array of PTEs from which the TLB can then create direct
entries. Thus, in order to invalidate those when PTE pages are deleted,
we need the virtual address to pass to tlbilx or tlbivax instructions.
The old trick of sticking it somewhere in the PTE page struct page sucks
too much, the address is almost readily available in all call sites and
almost everybody implemets these as macros, so we may as well add the
argument everywhere. I added it to the pmd and pud variants for consistency.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: David Howells <dhowells@redhat.com> [MN10300 & FRV]
Acked-by: Nick Piggin <npiggin@suse.de>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [s390]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-07-22 13:44:28 +08:00
|
|
|
#define pmd_free_tlb(tlb, pmdp, address) \
|
2005-04-17 06:20:36 +08:00
|
|
|
do { \
|
|
|
|
tlb->need_flush = 1; \
|
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
Upcoming paches to support the new 64-bit "BookE" powerpc architecture
will need to have the virtual address corresponding to PTE page when
freeing it, due to the way the HW table walker works.
Basically, the TLB can be loaded with "large" pages that cover the whole
virtual space (well, sort-of, half of it actually) represented by a PTE
page, and which contain an "indirect" bit indicating that this TLB entry
RPN points to an array of PTEs from which the TLB can then create direct
entries. Thus, in order to invalidate those when PTE pages are deleted,
we need the virtual address to pass to tlbilx or tlbivax instructions.
The old trick of sticking it somewhere in the PTE page struct page sucks
too much, the address is almost readily available in all call sites and
almost everybody implemets these as macros, so we may as well add the
argument everywhere. I added it to the pmd and pud variants for consistency.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Acked-by: David Howells <dhowells@redhat.com> [MN10300 & FRV]
Acked-by: Nick Piggin <npiggin@suse.de>
Acked-by: Martin Schwidefsky <schwidefsky@de.ibm.com> [s390]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2009-07-22 13:44:28 +08:00
|
|
|
__pmd_free_tlb(tlb, pmdp, address); \
|
2005-04-17 06:20:36 +08:00
|
|
|
} while (0)
|
|
|
|
|
|
|
|
#define tlb_migrate_finish(mm) do {} while (0)
|
|
|
|
|
|
|
|
#endif /* _ASM_GENERIC__TLB_H */
|