Skip to content

Commit

Permalink
[IA64] Quicklist support for IA64
Browse files Browse the repository at this point in the history
IA64 is the origin of the quicklist implementation.  So cut out the pieces
that are now in core code and modify the functions called.

Signed-off-by: Christoph Lameter <clameter@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Tony Luck <tony.luck@intel.com>
  • Loading branch information
Christoph Lameter authored and Tony Luck committed May 11, 2007
1 parent cdc7dbd commit 2bd62a4
Show file tree
Hide file tree
Showing 5 changed files with 22 additions and 119 deletions.
4 changes: 4 additions & 0 deletions arch/ia64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ config ZONE_DMA
def_bool y
depends on !IA64_SGI_SN2

config QUICKLIST
bool
default y

config MMU
bool
default y
Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/mm/contig.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void show_mem(void)
printk(KERN_INFO "%d pages shared\n", total_shared);
printk(KERN_INFO "%d pages swap cached\n", total_cached);
printk(KERN_INFO "Total of %ld pages in page table cache\n",
pgtable_quicklist_total_size());
quicklist_total_size());
printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
}

Expand Down
2 changes: 1 addition & 1 deletion arch/ia64/mm/discontig.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ void show_mem(void)
printk(KERN_INFO "%d pages shared\n", total_shared);
printk(KERN_INFO "%d pages swap cached\n", total_cached);
printk(KERN_INFO "Total of %ld pages in page table cache\n",
pgtable_quicklist_total_size());
quicklist_total_size());
printk(KERN_INFO "%d free buffer pages\n", nr_free_buffer_pages());
}

Expand Down
51 changes: 0 additions & 51 deletions arch/ia64/mm/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@

DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);

DEFINE_PER_CPU(unsigned long *, __pgtable_quicklist);
DEFINE_PER_CPU(long, __pgtable_quicklist_size);

extern void ia64_tlb_init (void);

unsigned long MAX_DMA_ADDRESS = PAGE_OFFSET + 0x100000000UL;
Expand All @@ -56,54 +53,6 @@ EXPORT_SYMBOL(vmem_map);
struct page *zero_page_memmap_ptr; /* map entry for zero page */
EXPORT_SYMBOL(zero_page_memmap_ptr);

#define MIN_PGT_PAGES 25UL
#define MAX_PGT_FREES_PER_PASS 16L
#define PGT_FRACTION_OF_NODE_MEM 16

static inline long
max_pgt_pages(void)
{
u64 node_free_pages, max_pgt_pages;

#ifndef CONFIG_NUMA
node_free_pages = nr_free_pages();
#else
node_free_pages = node_page_state(numa_node_id(), NR_FREE_PAGES);
#endif
max_pgt_pages = node_free_pages / PGT_FRACTION_OF_NODE_MEM;
max_pgt_pages = max(max_pgt_pages, MIN_PGT_PAGES);
return max_pgt_pages;
}

static inline long
min_pages_to_free(void)
{
long pages_to_free;

pages_to_free = pgtable_quicklist_size - max_pgt_pages();
pages_to_free = min(pages_to_free, MAX_PGT_FREES_PER_PASS);
return pages_to_free;
}

void
check_pgt_cache(void)
{
long pages_to_free;

if (unlikely(pgtable_quicklist_size <= MIN_PGT_PAGES))
return;

preempt_disable();
while (unlikely((pages_to_free = min_pages_to_free()) > 0)) {
while (pages_to_free--) {
free_page((unsigned long)pgtable_quicklist_alloc());
}
preempt_enable();
preempt_disable();
}
preempt_enable();
}

void
lazy_mmu_prot_update (pte_t pte)
{
Expand Down
82 changes: 16 additions & 66 deletions include/asm-ia64/pgalloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,71 +18,18 @@
#include <linux/mm.h>
#include <linux/page-flags.h>
#include <linux/threads.h>
#include <linux/quicklist.h>

#include <asm/mmu_context.h>

DECLARE_PER_CPU(unsigned long *, __pgtable_quicklist);
#define pgtable_quicklist __ia64_per_cpu_var(__pgtable_quicklist)
DECLARE_PER_CPU(long, __pgtable_quicklist_size);
#define pgtable_quicklist_size __ia64_per_cpu_var(__pgtable_quicklist_size)

static inline long pgtable_quicklist_total_size(void)
{
long ql_size = 0;
int cpuid;

for_each_online_cpu(cpuid) {
ql_size += per_cpu(__pgtable_quicklist_size, cpuid);
}
return ql_size;
}

static inline void *pgtable_quicklist_alloc(void)
{
unsigned long *ret = NULL;

preempt_disable();

ret = pgtable_quicklist;
if (likely(ret != NULL)) {
pgtable_quicklist = (unsigned long *)(*ret);
ret[0] = 0;
--pgtable_quicklist_size;
preempt_enable();
} else {
preempt_enable();
ret = (unsigned long *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
}

return ret;
}

static inline void pgtable_quicklist_free(void *pgtable_entry)
{
#ifdef CONFIG_NUMA
int nid = page_to_nid(virt_to_page(pgtable_entry));

if (unlikely(nid != numa_node_id())) {
free_page((unsigned long)pgtable_entry);
return;
}
#endif

preempt_disable();
*(unsigned long *)pgtable_entry = (unsigned long)pgtable_quicklist;
pgtable_quicklist = (unsigned long *)pgtable_entry;
++pgtable_quicklist_size;
preempt_enable();
}

static inline pgd_t *pgd_alloc(struct mm_struct *mm)
{
return pgtable_quicklist_alloc();
return quicklist_alloc(0, GFP_KERNEL, NULL);
}

static inline void pgd_free(pgd_t * pgd)
{
pgtable_quicklist_free(pgd);
quicklist_free(0, NULL, pgd);
}

#ifdef CONFIG_PGTABLE_4
Expand All @@ -94,12 +41,12 @@ pgd_populate(struct mm_struct *mm, pgd_t * pgd_entry, pud_t * pud)

static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
{
return pgtable_quicklist_alloc();
return quicklist_alloc(0, GFP_KERNEL, NULL);
}

static inline void pud_free(pud_t * pud)
{
pgtable_quicklist_free(pud);
quicklist_free(0, NULL, pud);
}
#define __pud_free_tlb(tlb, pud) pud_free(pud)
#endif /* CONFIG_PGTABLE_4 */
Expand All @@ -112,12 +59,12 @@ pud_populate(struct mm_struct *mm, pud_t * pud_entry, pmd_t * pmd)

static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)
{
return pgtable_quicklist_alloc();
return quicklist_alloc(0, GFP_KERNEL, NULL);
}

static inline void pmd_free(pmd_t * pmd)
{
pgtable_quicklist_free(pmd);
quicklist_free(0, NULL, pmd);
}

#define __pmd_free_tlb(tlb, pmd) pmd_free(pmd)
Expand All @@ -137,28 +84,31 @@ pmd_populate_kernel(struct mm_struct *mm, pmd_t * pmd_entry, pte_t * pte)
static inline struct page *pte_alloc_one(struct mm_struct *mm,
unsigned long addr)
{
void *pg = pgtable_quicklist_alloc();
void *pg = quicklist_alloc(0, GFP_KERNEL, NULL);
return pg ? virt_to_page(pg) : NULL;
}

static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
unsigned long addr)
{
return pgtable_quicklist_alloc();
return quicklist_alloc(0, GFP_KERNEL, NULL);
}

static inline void pte_free(struct page *pte)
{
pgtable_quicklist_free(page_address(pte));
quicklist_free_page(0, NULL, pte);
}

static inline void pte_free_kernel(pte_t * pte)
{
pgtable_quicklist_free(pte);
quicklist_free(0, NULL, pte);
}

#define __pte_free_tlb(tlb, pte) pte_free(pte)
static inline void check_pgt_cache(void)
{
quicklist_trim(0, NULL, 25, 16);
}

extern void check_pgt_cache(void);
#define __pte_free_tlb(tlb, pte) pte_free(pte)

#endif /* _ASM_IA64_PGALLOC_H */

0 comments on commit 2bd62a4

Please sign in to comment.