Commit 9326a730 authored by Ivan Kokshaysky's avatar Ivan Kokshaysky Committed by Richard Henderson

[PATCH] alpha numa update

From Jeff.Wiedemeier@hp.com:

numa mm update including moving alpha numa support into 
machine vector so a generic numa kernel can be used.
parent ecb581fd
...@@ -228,6 +228,13 @@ EXPORT_SYMBOL(_raw_read_lock); ...@@ -228,6 +228,13 @@ EXPORT_SYMBOL(_raw_read_lock);
EXPORT_SYMBOL(cpu_present_mask); EXPORT_SYMBOL(cpu_present_mask);
#endif /* CONFIG_SMP */ #endif /* CONFIG_SMP */
/*
* NUMA specific symbols
*/
#ifdef CONFIG_DISCONTIGMEM
EXPORT_SYMBOL(node_data);
#endif /* CONFIG_DISCONTIGMEM */
EXPORT_SYMBOL(rtc_lock); EXPORT_SYMBOL(rtc_lock);
/* /*
......
...@@ -442,6 +442,33 @@ struct pci_ops wildfire_pci_ops = ...@@ -442,6 +442,33 @@ struct pci_ops wildfire_pci_ops =
.write = wildfire_write_config, .write = wildfire_write_config,
}; };
/*
* NUMA Support
*/
int wildfire_pa_to_nid(unsigned long pa)
{
return pa >> 36;
}
int wildfire_cpuid_to_nid(int cpuid)
{
/* assume 4 CPUs per node */
return cpuid >> 2;
}
unsigned long wildfire_node_mem_start(int nid)
{
/* 64GB per node */
return (unsigned long)nid * (64UL * 1024 * 1024 * 1024);
}
unsigned long wildfire_node_mem_size(int nid)
{
/* 64GB per node */
return 64UL * 1024 * 1024 * 1024;
}
#if DEBUG_DUMP_REGS #if DEBUG_DUMP_REGS
static void __init static void __init
......
...@@ -82,6 +82,10 @@ extern void wildfire_init_arch(void); ...@@ -82,6 +82,10 @@ extern void wildfire_init_arch(void);
extern void wildfire_kill_arch(int); extern void wildfire_kill_arch(int);
extern void wildfire_machine_check(u64, u64, struct pt_regs *); extern void wildfire_machine_check(u64, u64, struct pt_regs *);
extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t); extern void wildfire_pci_tbi(struct pci_controller *, dma_addr_t, dma_addr_t);
extern int wildfire_pa_to_nid(unsigned long);
extern int wildfire_cpuid_to_nid(int);
extern unsigned long wildfire_node_mem_start(int);
extern unsigned long wildfire_node_mem_size(int);
/* setup.c */ /* setup.c */
extern unsigned long srm_hae; extern unsigned long srm_hae;
......
...@@ -353,5 +353,10 @@ struct alpha_machine_vector wildfire_mv __initmv = { ...@@ -353,5 +353,10 @@ struct alpha_machine_vector wildfire_mv __initmv = {
.kill_arch = wildfire_kill_arch, .kill_arch = wildfire_kill_arch,
.pci_map_irq = wildfire_map_irq, .pci_map_irq = wildfire_map_irq,
.pci_swizzle = common_swizzle, .pci_swizzle = common_swizzle,
.pa_to_nid = wildfire_pa_to_nid,
.cpuid_to_nid = wildfire_cpuid_to_nid,
.node_mem_start = wildfire_node_mem_start,
.node_mem_size = wildfire_node_mem_size,
}; };
ALIAS_MV(wildfire) ALIAS_MV(wildfire)
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
#include <asm/hwrpb.h> #include <asm/hwrpb.h>
#include <asm/pgalloc.h> #include <asm/pgalloc.h>
plat_pg_data_t *plat_node_data[MAX_NUMNODES]; pg_data_t node_data[MAX_NUMNODES];
bootmem_data_t plat_node_bdata[MAX_NUMNODES]; bootmem_data_t node_bdata[MAX_NUMNODES];
#undef DEBUG_DISCONTIG #undef DEBUG_DISCONTIG
#ifdef DEBUG_DISCONTIG #ifdef DEBUG_DISCONTIG
...@@ -65,12 +65,12 @@ setup_memory_node(int nid, void *kernel_end) ...@@ -65,12 +65,12 @@ setup_memory_node(int nid, void *kernel_end)
unsigned long start, end; unsigned long start, end;
unsigned long node_pfn_start, node_pfn_end; unsigned long node_pfn_start, node_pfn_end;
int i; int i;
unsigned long node_datasz = PFN_UP(sizeof(plat_pg_data_t)); unsigned long node_datasz = PFN_UP(sizeof(pg_data_t));
int show_init = 0; int show_init = 0;
/* Find the bounds of current node */ /* Find the bounds of current node */
node_pfn_start = (nid * NODE_MAX_MEM_SIZE) >> PAGE_SHIFT; node_pfn_start = (node_mem_start(nid)) >> PAGE_SHIFT;
node_pfn_end = node_pfn_start + (NODE_MAX_MEM_SIZE >> PAGE_SHIFT); node_pfn_end = node_pfn_start + (node_mem_size(nid) >> PAGE_SHIFT);
/* Find free clusters, and init and free the bootmem accordingly. */ /* Find free clusters, and init and free the bootmem accordingly. */
memdesc = (struct memdesc_struct *) memdesc = (struct memdesc_struct *)
...@@ -93,7 +93,7 @@ setup_memory_node(int nid, void *kernel_end) ...@@ -93,7 +93,7 @@ setup_memory_node(int nid, void *kernel_end)
if (!show_init) { if (!show_init) {
show_init = 1; show_init = 1;
printk("Initialing bootmem allocator on Node ID %d\n", nid); printk("Initializing bootmem allocator on Node ID %d\n", nid);
} }
printk(" memcluster %2d, usage %1lx, start %8lu, end %8lu\n", printk(" memcluster %2d, usage %1lx, start %8lu, end %8lu\n",
i, cluster->usage, cluster->start_pfn, i, cluster->usage, cluster->start_pfn,
...@@ -107,13 +107,17 @@ setup_memory_node(int nid, void *kernel_end) ...@@ -107,13 +107,17 @@ setup_memory_node(int nid, void *kernel_end)
if (start < min_low_pfn) if (start < min_low_pfn)
min_low_pfn = start; min_low_pfn = start;
if (end > max_low_pfn) if (end > max_low_pfn)
max_low_pfn = end; max_pfn = max_low_pfn = end;
} }
if (mem_size_limit && max_low_pfn >= mem_size_limit) { if (mem_size_limit && max_low_pfn > mem_size_limit) {
static int msg_shown = 0;
if (!msg_shown) {
msg_shown = 1;
printk("setup: forcing memory size to %ldK (from %ldK).\n", printk("setup: forcing memory size to %ldK (from %ldK).\n",
mem_size_limit << (PAGE_SHIFT - 10), mem_size_limit << (PAGE_SHIFT - 10),
max_low_pfn << (PAGE_SHIFT - 10)); max_low_pfn << (PAGE_SHIFT - 10));
}
max_low_pfn = mem_size_limit; max_low_pfn = mem_size_limit;
} }
...@@ -122,20 +126,22 @@ setup_memory_node(int nid, void *kernel_end) ...@@ -122,20 +126,22 @@ setup_memory_node(int nid, void *kernel_end)
num_physpages += max_low_pfn - min_low_pfn; num_physpages += max_low_pfn - min_low_pfn;
#if 0 /* we'll try this one again in a little while */
/* Cute trick to make sure our local node data is on local memory */ /* Cute trick to make sure our local node data is on local memory */
PLAT_NODE_DATA(nid) = (plat_pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT)); node_data[nid] = (pg_data_t *)(__va(min_low_pfn << PAGE_SHIFT));
/* Quasi-mark the plat_pg_data_t as in-use */ #endif
/* Quasi-mark the pg_data_t as in-use */
min_low_pfn += node_datasz; min_low_pfn += node_datasz;
if (min_low_pfn >= max_low_pfn) { if (min_low_pfn >= max_low_pfn) {
printk(" not enough mem to reserve PLAT_NODE_DATA"); printk(" not enough mem to reserve NODE_DATA");
return; return;
} }
NODE_DATA(nid)->bdata = &plat_node_bdata[nid]; NODE_DATA(nid)->bdata = &node_bdata[nid];
printk(" Detected node memory: start %8lu, end %8lu\n", printk(" Detected node memory: start %8lu, end %8lu\n",
min_low_pfn, max_low_pfn); min_low_pfn, max_low_pfn);
DBGDCONT(" DISCONTIG: plat_node_data[%d] is at 0x%p\n", nid, PLAT_NODE_DATA(nid)); DBGDCONT(" DISCONTIG: node_data[%d] is at 0x%p\n", nid, NODE_DATA(nid));
DBGDCONT(" DISCONTIG: NODE_DATA(%d)->bdata is at 0x%p\n", nid, NODE_DATA(nid)->bdata); DBGDCONT(" DISCONTIG: NODE_DATA(%d)->bdata is at 0x%p\n", nid, NODE_DATA(nid)->bdata);
/* Find the bounds of kernel memory. */ /* Find the bounds of kernel memory. */
...@@ -286,8 +292,8 @@ void __init paging_init(void) ...@@ -286,8 +292,8 @@ void __init paging_init(void)
dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; dma_local_pfn = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
for (nid = 0; nid < numnodes; nid++) { for (nid = 0; nid < numnodes; nid++) {
unsigned long start_pfn = plat_node_bdata[nid].node_boot_start >> PAGE_SHIFT; unsigned long start_pfn = node_bdata[nid].node_boot_start >> PAGE_SHIFT;
unsigned long end_pfn = plat_node_bdata[nid].node_low_pfn; unsigned long end_pfn = node_bdata[nid].node_low_pfn;
if (dma_local_pfn >= end_pfn - start_pfn) if (dma_local_pfn >= end_pfn - start_pfn)
zones_size[ZONE_DMA] = end_pfn - start_pfn; zones_size[ZONE_DMA] = end_pfn - start_pfn;
...@@ -302,52 +308,6 @@ void __init paging_init(void) ...@@ -302,52 +308,6 @@ void __init paging_init(void)
memset((void *)ZERO_PGE, 0, PAGE_SIZE); memset((void *)ZERO_PGE, 0, PAGE_SIZE);
} }
#define printkdot() \
do { \
if (!(i++ % ((100UL*1024*1024)>>PAGE_SHIFT))) \
printk("."); \
} while(0)
#define clobber(p, size) memset((p)->virtual, 0xaa, (size))
void __init mem_stress(void)
{
LIST_HEAD(x);
LIST_HEAD(xx);
struct page * p;
unsigned long i = 0;
printk("starting memstress");
while ((p = alloc_pages(GFP_ATOMIC, 1))) {
clobber(p, PAGE_SIZE*2);
list_add(&p->list, &x);
printkdot();
}
while ((p = alloc_page(GFP_ATOMIC))) {
clobber(p, PAGE_SIZE);
list_add(&p->list, &xx);
printkdot();
}
while (!list_empty(&x)) {
p = list_entry(x.next, struct page, list);
clobber(p, PAGE_SIZE*2);
list_del(x.next);
__free_pages(p, 1);
printkdot();
}
while (!list_empty(&xx)) {
p = list_entry(xx.next, struct page, list);
clobber(p, PAGE_SIZE);
list_del(xx.next);
__free_pages(p, 0);
printkdot();
}
printk("I'm still alive duh!\n");
}
#undef printkdot
#undef clobber
void __init mem_init(void) void __init mem_init(void)
{ {
unsigned long codesize, reservedpages, datasize, initsize, pfn; unsigned long codesize, reservedpages, datasize, initsize, pfn;
...@@ -355,9 +315,9 @@ void __init mem_init(void) ...@@ -355,9 +315,9 @@ void __init mem_init(void)
extern char _text, _etext, _data, _edata; extern char _text, _etext, _data, _edata;
extern char __init_begin, __init_end; extern char __init_begin, __init_end;
unsigned long nid, i; unsigned long nid, i;
mem_map_t * lmem_map; struct page * lmem_map;
high_memory = (void *) __va(max_mapnr <<PAGE_SHIFT); high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT);
reservedpages = 0; reservedpages = 0;
for (nid = 0; nid < numnodes; nid++) { for (nid = 0; nid < numnodes; nid++) {
...@@ -366,9 +326,9 @@ void __init mem_init(void) ...@@ -366,9 +326,9 @@ void __init mem_init(void)
*/ */
totalram_pages += free_all_bootmem_node(NODE_DATA(nid)); totalram_pages += free_all_bootmem_node(NODE_DATA(nid));
lmem_map = NODE_MEM_MAP(nid); lmem_map = node_mem_map(nid);
pfn = NODE_DATA(nid)->node_start_pfn; pfn = NODE_DATA(nid)->node_start_pfn;
for (i = 0; i < PLAT_NODE_DATA_SIZE(nid); i++, pfn++) for (i = 0; i < node_size(nid); i++, pfn++)
if (page_is_ram(pfn) && PageReserved(lmem_map+i)) if (page_is_ram(pfn) && PageReserved(lmem_map+i))
reservedpages++; reservedpages++;
} }
...@@ -401,8 +361,8 @@ show_mem(void) ...@@ -401,8 +361,8 @@ show_mem(void)
show_free_areas(); show_free_areas();
printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
for (nid = 0; nid < numnodes; nid++) { for (nid = 0; nid < numnodes; nid++) {
mem_map_t * lmem_map = NODE_MEM_MAP(nid); struct page * lmem_map = node_mem_map(nid);
i = PLAT_NODE_DATA_SIZE(nid); i = node_size(nid);
while (i-- > 0) { while (i-- > 0) {
total++; total++;
if (PageReserved(lmem_map+i)) if (PageReserved(lmem_map+i))
...@@ -420,5 +380,4 @@ show_mem(void) ...@@ -420,5 +380,4 @@ show_mem(void)
printk("%ld reserved pages\n",reserved); printk("%ld reserved pages\n",reserved);
printk("%ld pages shared\n",shared); printk("%ld pages shared\n",shared);
printk("%ld pages swap cached\n",cached); printk("%ld pages swap cached\n",cached);
printk("%ld pages in page table cache\n",pgtable_cache_size);
} }
...@@ -83,7 +83,7 @@ static inline void * phys_to_virt(unsigned long address) ...@@ -83,7 +83,7 @@ static inline void * phys_to_virt(unsigned long address)
} }
#endif #endif
#define page_to_phys(page) PAGE_TO_PA(page) #define page_to_phys(page) page_to_pa(page)
/* This depends on working iommu. */ /* This depends on working iommu. */
#define BIO_VMERGE_BOUNDARY (alpha_mv.mv_pci_tbi ? PAGE_SIZE : 0) #define BIO_VMERGE_BOUNDARY (alpha_mv.mv_pci_tbi ? PAGE_SIZE : 0)
......
...@@ -92,6 +92,12 @@ struct alpha_machine_vector ...@@ -92,6 +92,12 @@ struct alpha_machine_vector
const char *vector_name; const char *vector_name;
/* NUMA information */
int (*pa_to_nid)(unsigned long);
int (*cpuid_to_nid)(int);
unsigned long (*node_mem_start)(int);
unsigned long (*node_mem_size)(int);
/* System specific parameters. */ /* System specific parameters. */
union { union {
struct { struct {
......
...@@ -6,25 +6,7 @@ ...@@ -6,25 +6,7 @@
#define _ASM_MMZONE_H_ #define _ASM_MMZONE_H_
#include <linux/config.h> #include <linux/config.h>
#ifdef CONFIG_NUMA_SCHED #include <asm/smp.h>
#include <linux/numa_sched.h>
#endif
#ifdef NOTYET
#include <asm/sn/types.h>
#include <asm/sn/addrs.h>
#include <asm/sn/arch.h>
#include <asm/sn/klkernvars.h>
#endif /* NOTYET */
typedef struct plat_pglist_data {
pg_data_t gendata;
#ifdef NOTYET
kern_vars_t kern_vars;
#endif
#if defined(CONFIG_NUMA) && defined(CONFIG_NUMA_SCHED)
struct numa_schedule_data schedule_data;
#endif
} plat_pg_data_t;
struct bootmem_data_t; /* stupid forward decl. */ struct bootmem_data_t; /* stupid forward decl. */
...@@ -32,19 +14,26 @@ struct bootmem_data_t; /* stupid forward decl. */ ...@@ -32,19 +14,26 @@ struct bootmem_data_t; /* stupid forward decl. */
* Following are macros that are specific to this numa platform. * Following are macros that are specific to this numa platform.
*/ */
extern plat_pg_data_t *plat_node_data[]; extern pg_data_t node_data[];
#ifdef CONFIG_ALPHA_WILDFIRE #define alpha_pa_to_nid(pa) \
# define ALPHA_PA_TO_NID(pa) ((pa) >> 36) /* 16 nodes max due 43bit kseg */ (alpha_mv.pa_to_nid \
# define NODE_MAX_MEM_SIZE (64L * 1024L * 1024L * 1024L) /* 64 GB */ ? alpha_mv.pa_to_nid(pa) \
#else : (0))
# define ALPHA_PA_TO_NID(pa) (0) #define node_mem_start(nid) \
# define NODE_MAX_MEM_SIZE (~0UL) (alpha_mv.node_mem_start \
#endif ? alpha_mv.node_mem_start(nid) \
: (0UL))
#define node_mem_size(nid) \
(alpha_mv.node_mem_size \
? alpha_mv.node_mem_size(nid) \
: ((nid) ? (0UL) : (~0UL)))
#define pa_to_nid(pa) alpha_pa_to_nid(pa)
#define NODE_DATA(nid) (&node_data[(nid)])
#define node_size(nid) (NODE_DATA(nid)->node_size)
#define PHYSADDR_TO_NID(pa) ALPHA_PA_TO_NID(pa) #define node_localnr(pfn, nid) ((pfn) - NODE_DATA(nid)->node_start_pfn)
#define PLAT_NODE_DATA(n) (plat_node_data[(n)])
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#if 1 #if 1
#define PLAT_NODE_DATA_LOCALNR(p, n) \ #define PLAT_NODE_DATA_LOCALNR(p, n) \
...@@ -68,46 +57,76 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n) ...@@ -68,46 +57,76 @@ PLAT_NODE_DATA_LOCALNR(unsigned long p, int n)
/* /*
* Given a kernel address, find the home node of the underlying memory. * Given a kernel address, find the home node of the underlying memory.
*/ */
#define KVADDR_TO_NID(kaddr) PHYSADDR_TO_NID(__pa(kaddr)) #define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
/* #define local_mapnr(kvaddr) \
* Return a pointer to the node data for node n. ((__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)))
*/
#define NODE_DATA(n) (&((PLAT_NODE_DATA(n))->gendata))
/*
* NODE_MEM_MAP gives the kaddr for the mem_map of the node.
*/
#define NODE_MEM_MAP(nid) (NODE_DATA(nid)->node_mem_map)
/*
* Given a kaddr, ADDR_TO_MAPBASE finds the owning node of the memory
* and returns the mem_map of that node.
*/
#define ADDR_TO_MAPBASE(kaddr) \
NODE_MEM_MAP(KVADDR_TO_NID((unsigned long)(kaddr)))
/* /*
* Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory * Given a kaddr, LOCAL_BASE_ADDR finds the owning node of the memory
* and returns the kaddr corresponding to first physical page in the * and returns the kaddr corresponding to first physical page in the
* node's mem_map. * node's mem_map.
*/ */
#define LOCAL_BASE_ADDR(kaddr) ((unsigned long)__va(NODE_DATA(KVADDR_TO_NID(kaddr))->node_start_pfn << PAGE_SHIFT)) #define LOCAL_BASE_ADDR(kaddr) \
((unsigned long)__va(NODE_DATA(kvaddr_to_nid(kaddr))->node_start_pfn \
<< PAGE_SHIFT))
#define LOCAL_MAP_NR(kvaddr) \ #define kern_addr_valid(kaddr) \
(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT) test_bit(local_mapnr(kaddr), \
NODE_DATA(kvaddr_to_nid(kaddr))->valid_addr_bitmap)
#define kern_addr_valid(kaddr) test_bit(LOCAL_MAP_NR(kaddr), \ #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap)
#define virt_to_page(kaddr) (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr))
#define VALID_PAGE(page) (((page) - mem_map) < max_mapnr) #define VALID_PAGE(page) (((page) - mem_map) < max_mapnr)
#ifdef CONFIG_NUMA #define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> 32))
#ifdef CONFIG_NUMA_SCHED #define pte_pfn(pte) (pte_val(pte) >> 32)
#define NODE_SCHEDULE_DATA(nid) (&((PLAT_NODE_DATA(nid))->schedule_data))
#endif #define mk_pte(page, pgprot) \
#endif /* CONFIG_NUMA */ ({ \
pte_t pte; \
unsigned long pfn; \
\
pfn = ((unsigned long)((page)-page_zone(page)->zone_mem_map)) << 32; \
pfn += page_zone(page)->zone_start_pfn << 32; \
pte_val(pte) = pfn | pgprot_val(pgprot); \
\
pte; \
})
#define pte_page(x) \
({ \
unsigned long kvirt; \
struct page * __xx; \
\
kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT)); \
__xx = virt_to_page(kvirt); \
\
__xx; \
})
#define pfn_to_page(pfn) \
({ \
unsigned long kaddr = (unsigned long)__va(pfn << PAGE_SHIFT); \
(node_mem_map(kvaddr_to_nid(kaddr)) + local_mapnr(kaddr)); \
})
#define page_to_pfn(page) \
((page) - page_zone(page)->zone_mem_map + \
(page_zone(page)->zone_start_pfn))
#define page_to_pa(page) \
((( (page) - page_zone(page)->zone_mem_map ) \
+ page_zone(page)->zone_start_pfn) << PAGE_SHIFT)
#define pfn_to_nid(pfn) pa_to_nid(((u64)pfn << PAGE_SHIFT))
#define pfn_valid(pfn) \
(((pfn) - node_start_pfn(pfn_to_nid(pfn))) < \
node_size(pfn_to_nid(pfn))) \
#define virt_addr_valid(kaddr) pfn_valid((__pa(kaddr) >> PAGE_SHIFT))
#endif /* CONFIG_DISCONTIGMEM */ #endif /* CONFIG_DISCONTIGMEM */
......
#ifndef _ASM_MAX_NUMNODES_H #ifndef _ASM_MAX_NUMNODES_H
#define _ASM_MAX_NUMNODES_H #define _ASM_MAX_NUMNODES_H
/* #define MAX_NUMNODES 128 /* Marvel */
* Currently the Wildfire is the only discontigmem/NUMA capable Alpha core.
*/
#if defined(CONFIG_ALPHA_WILDFIRE) || defined(CONFIG_ALPHA_GENERIC)
# include <asm/core_wildfire.h>
# define MAX_NUMNODES WILDFIRE_MAX_QBB
#endif
#endif /* _ASM_MAX_NUMNODES_H */ #endif /* _ASM_MAX_NUMNODES_H */
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
#include <linux/config.h> #include <linux/config.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/mmzone.h>
/* /*
* Allocate and free page tables. The xxx_kernel() versions are * Allocate and free page tables. The xxx_kernel() versions are
...@@ -13,7 +14,7 @@ ...@@ -13,7 +14,7 @@
static inline void static inline void
pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte) pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *pte)
{ {
pmd_set(pmd, (pte_t *)(((pte - mem_map) << PAGE_SHIFT) + PAGE_OFFSET)); pmd_set(pmd, (pte_t *)(page_to_pa(pte) + PAGE_OFFSET));
} }
static inline void static inline void
......
...@@ -192,14 +192,8 @@ extern unsigned long __zero_page(void); ...@@ -192,14 +192,8 @@ extern unsigned long __zero_page(void);
* and a page entry and page directory to the page they refer to. * and a page entry and page directory to the page they refer to.
*/ */
#ifndef CONFIG_DISCONTIGMEM #ifndef CONFIG_DISCONTIGMEM
#define PAGE_TO_PA(page) ((page - mem_map) << PAGE_SHIFT) #define page_to_pa(page) ((page - mem_map) << PAGE_SHIFT)
#else
#define PAGE_TO_PA(page) \
((( (page) - (page)->zone->zone_mem_map ) \
+ (page)->zone->zone_start_pfn) << PAGE_SHIFT)
#endif
#ifndef CONFIG_DISCONTIGMEM
#define pte_pfn(pte) (pte_val(pte) >> 32) #define pte_pfn(pte) (pte_val(pte) >> 32)
#define pte_page(pte) pfn_to_page(pte_pfn(pte)) #define pte_page(pte) pfn_to_page(pte_pfn(pte))
#define mk_pte(page, pgprot) \ #define mk_pte(page, pgprot) \
...@@ -209,28 +203,6 @@ extern unsigned long __zero_page(void); ...@@ -209,28 +203,6 @@ extern unsigned long __zero_page(void);
pte_val(pte) = (page_to_pfn(page) << 32) | pgprot_val(pgprot); \ pte_val(pte) = (page_to_pfn(page) << 32) | pgprot_val(pgprot); \
pte; \ pte; \
}) })
#else
#define mk_pte(page, pgprot) \
({ \
pte_t pte; \
unsigned long pfn; \
\
pfn = ((unsigned long)((page)-(page)->zone->zone_mem_map)) << 32; \
pfn += (page)->zone->zone_start_pfn << 32); \
pte_val(pte) = pfn | pgprot_val(pgprot); \
\
pte; \
})
#define pte_page(x) \
({ \
unsigned long kvirt; \
struct page * __xx; \
\
kvirt = (unsigned long)__va(pte_val(x) >> (32-PAGE_SHIFT)); \
__xx = virt_to_page(kvirt); \
\
__xx; \
})
#endif #endif
extern inline pte_t pfn_pte(unsigned long physpfn, pgprot_t pgprot) extern inline pte_t pfn_pte(unsigned long physpfn, pgprot_t pgprot)
...@@ -252,7 +224,9 @@ pmd_page_kernel(pmd_t pmd) ...@@ -252,7 +224,9 @@ pmd_page_kernel(pmd_t pmd)
return ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)) + PAGE_OFFSET; return ((pmd_val(pmd) & _PFN_MASK) >> (32-PAGE_SHIFT)) + PAGE_OFFSET;
} }
#ifndef CONFIG_DISCONTIGMEM
#define pmd_page(pmd) (mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32)) #define pmd_page(pmd) (mem_map + ((pmd_val(pmd) & _PFN_MASK) >> 32))
#endif
extern inline unsigned long pgd_page(pgd_t pgd) extern inline unsigned long pgd_page(pgd_t pgd)
{ return PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); } { return PAGE_OFFSET + ((pgd_val(pgd) & _PFN_MASK) >> (32-PAGE_SHIFT)); }
......
#ifndef _ASM_ALPHA_TOPOLOGY_H #ifndef _ASM_ALPHA_TOPOLOGY_H
#define _ASM_ALPHA_TOPOLOGY_H #define _ASM_ALPHA_TOPOLOGY_H
#if defined(CONFIG_NUMA) && defined(CONFIG_ALPHA_WILDFIRE) #include <linux/smp.h>
#include <linux/threads.h>
#include <asm/machvec.h>
/* With wildfire assume 4 CPUs per node */ #ifdef CONFIG_NUMA
#define __cpu_to_node(cpu) ((cpu) >> 2) static inline int __cpu_to_node(int cpu)
{
int node;
#else /* !CONFIG_NUMA || !CONFIG_ALPHA_WILDFIRE */ if (!alpha_mv.cpuid_to_nid)
return 0;
#include <asm-generic/topology.h> node = alpha_mv.cpuid_to_nid(cpu);
#endif /* CONFIG_NUMA && CONFIG_ALPHA_WILDFIRE */ #ifdef DEBUG_NUMA
if (node < 0)
BUG();
#endif
return node;
}
static inline int __node_to_cpu_mask(int node)
{
unsigned long node_cpu_mask = 0;
int cpu;
for(cpu = 0; cpu < NR_CPUS; cpu++) {
if (cpu_online(cpu) && (__cpu_to_node(cpu) == node))
node_cpu_mask |= 1UL << cpu;
}
#if DEBUG_NUMA
printk("node %d: cpu_mask: %016lx\n", node, node_cpu_mask);
#endif
return node_cpu_mask;
}
# define __node_to_memblk(node) (node)
# define __memblk_to_node(memblk) (memblk)
#else /* CONFIG_NUMA */
# include <asm-generic/topology.h>
#endif /* !CONFIG_NUMA */
#endif /* _ASM_ALPHA_TOPOLOGY_H */ #endif /* _ASM_ALPHA_TOPOLOGY_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment