Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
6a7644b2
Commit
6a7644b2
authored
Jun 07, 2002
by
Anton Blanchard
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
ppc64: Initial DISCONTIGMEM and NUMA support
parent
c49b18d3
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
105 additions
and
260 deletions
+105
-260
arch/ppc64/config.in
arch/ppc64/config.in
+4
-0
arch/ppc64/xmon/xmon.c
arch/ppc64/xmon/xmon.c
+0
-259
include/asm-ppc64/mmzone.h
include/asm-ppc64/mmzone.h
+93
-0
include/asm-ppc64/page.h
include/asm-ppc64/page.h
+8
-1
No files found.
arch/ppc64/config.in
View file @
6a7644b2
...
...
@@ -23,6 +23,10 @@ if [ "$CONFIG_SMP" = "y" ]; then
bool ' Distribute interrupts on all CPUs by default' CONFIG_IRQ_ALL_CPUS
if [ "$CONFIG_PPC_PSERIES" = "y" ]; then
bool ' Hardware multithreading' CONFIG_HMT
bool ' Discontiguous Memory Support' CONFIG_DISCONTIGMEM
if [ "$CONFIG_DISCONTIGMEM" = "y" ]; then
bool ' NUMA support' CONFIG_NUMA
fi
fi
fi
define_bool CONFIG_PREEMPT n
...
...
arch/ppc64/xmon/xmon.c
View file @
6a7644b2
...
...
@@ -123,11 +123,7 @@ static void mem_translate(void);
static
void
mem_check
(
void
);
static
void
mem_find_real
(
void
);
static
void
mem_find_vsid
(
void
);
static
void
mem_check_pagetable_vsids
(
void
);
static
void
mem_map_check_slab
(
void
);
static
void
mem_map_lock_pages
(
void
);
static
void
mem_check_dup_rpn
(
void
);
static
void
debug_trace
(
void
);
extern
int
print_insn_big_powerpc
(
FILE
*
,
unsigned
long
,
unsigned
long
);
...
...
@@ -642,27 +638,15 @@ cmds(struct pt_regs *excp)
case
'c'
:
mem_check
();
break
;
case
'j'
:
mem_map_check_slab
();
break
;
case
'f'
:
mem_find_real
();
break
;
case
'e'
:
mem_find_vsid
();
break
;
case
'r'
:
mem_check_dup_rpn
();
break
;
case
'i'
:
show_mem
();
break
;
case
'o'
:
mem_check_pagetable_vsids
();
break
;
case
'q'
:
mem_map_lock_pages
()
;
break
;
default:
termch
=
cmd
;
memex
();
...
...
@@ -2458,249 +2442,6 @@ void mem_find_vsid()
printf
(
"
\n
Done -------------------
\n
"
);
}
void
mem_map_check_slab
()
{
int
i
,
slab_count
;
i
=
max_mapnr
;
slab_count
=
0
;
while
(
i
--
>
0
)
{
if
(
PageSlab
(
mem_map
+
i
)){
printf
(
" slab entry - mem_map entry =%p
\n
"
,
mem_map
+
i
);
slab_count
++
;
}
}
printf
(
" count of pages for slab = %d
\n
"
,
slab_count
);
}
void
mem_map_lock_pages
()
{
int
i
,
lock_count
;
i
=
max_mapnr
;
lock_count
=
0
;
while
(
i
--
>
0
)
{
if
(
PageLocked
(
mem_map
+
i
)){
printf
(
" locked entry - mem_map entry =%p
\n
"
,
mem_map
+
i
);
lock_count
++
;
}
}
printf
(
" count of locked pages = %d
\n
"
,
lock_count
);
}
void
mem_check_dup_rpn
()
{
unsigned
long
htab_size_bytes
;
unsigned
long
htab_end
;
unsigned
long
last_rpn
;
HPTE
*
hpte1
,
*
hpte2
;
int
dup_count
;
struct
task_struct
*
p
;
unsigned
long
kernel_vsid_c0
,
kernel_vsid_c1
,
kernel_vsid_c2
,
kernel_vsid_c3
;
unsigned
long
kernel_vsid_c4
,
kernel_vsid_c5
,
kernel_vsid_d
,
kernel_vsid_e
;
unsigned
long
kernel_vsid_f
;
unsigned
long
vsid0
,
vsid1
,
vsidB
,
vsid2
;
htab_size_bytes
=
htab_data
.
htab_num_ptegs
*
128
;
// 128B / PTEG
htab_end
=
(
unsigned
long
)
htab_data
.
htab
+
htab_size_bytes
;
// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
last_rpn
=
0xfffff
;
printf
(
"
\n
Hardware Page Table Check
\n
-------------------
\n
"
);
printf
(
"htab base : %.16lx
\n
"
,
htab_data
.
htab
);
printf
(
"htab size : %.16lx
\n
"
,
htab_size_bytes
);
for
(
hpte1
=
htab_data
.
htab
;
hpte1
<
(
HPTE
*
)
htab_end
;
hpte1
++
)
{
if
(
hpte1
->
dw0
.
dw0
.
v
!=
0
)
{
if
(
hpte1
->
dw1
.
dw1
.
rpn
<=
last_rpn
)
{
dup_count
=
0
;
for
(
hpte2
=
hpte1
+
1
;
hpte2
<
(
HPTE
*
)
htab_end
;
hpte2
++
)
{
if
(
hpte2
->
dw0
.
dw0
.
v
!=
0
)
{
if
(
hpte1
->
dw1
.
dw1
.
rpn
==
hpte2
->
dw1
.
dw1
.
rpn
)
{
dup_count
++
;
}
}
}
if
(
dup_count
>
5
)
{
printf
(
" Duplicate rpn: %.13lx
\n
"
,
(
hpte1
->
dw1
.
dw1
.
rpn
));
printf
(
" mem map array entry %p count = %d
\n
"
,
(
mem_map
+
(
hpte1
->
dw1
.
dw1
.
rpn
)),
(
mem_map
+
(
hpte1
->
dw1
.
dw1
.
rpn
))
->
count
);
for
(
hpte2
=
hpte1
+
1
;
hpte2
<
(
HPTE
*
)
htab_end
;
hpte2
++
)
{
if
(
hpte2
->
dw0
.
dw0
.
v
!=
0
)
{
if
(
hpte1
->
dw1
.
dw1
.
rpn
==
hpte2
->
dw1
.
dw1
.
rpn
)
{
printf
(
" hpte2: %16.16lx *hpte2: %16.16lx %16.16lx
\n
"
,
hpte2
,
hpte2
->
dw0
.
dword0
,
hpte2
->
dw1
.
dword1
);
}
}
}
}
}
else
{
printf
(
" Bogus rpn: %.13lx
\n
"
,
(
hpte1
->
dw1
.
dw1
.
rpn
));
printf
(
" hpte: %16.16lx *hpte: %16.16lx %16.16lx
\n
"
,
hpte1
,
hpte1
->
dw0
.
dword0
,
hpte1
->
dw1
.
dword1
);
}
}
if
(
xmon_interrupted
())
return
;
}
// print the kernel vsids
kernel_vsid_c0
=
get_kernel_vsid
(
0xC000000000000000
);
kernel_vsid_c1
=
get_kernel_vsid
(
0xC000000010000000
);
kernel_vsid_c2
=
get_kernel_vsid
(
0xC000000020000000
);
kernel_vsid_c3
=
get_kernel_vsid
(
0xC000000030000000
);
kernel_vsid_c4
=
get_kernel_vsid
(
0xC000000040000000
);
kernel_vsid_c5
=
get_kernel_vsid
(
0xC000000050000000
);
kernel_vsid_d
=
get_kernel_vsid
(
0xD000000000000000
);
kernel_vsid_e
=
get_kernel_vsid
(
0xE000000000000000
);
kernel_vsid_f
=
get_kernel_vsid
(
0xF000000000000000
);
printf
(
" kernel vsid - seg c0 = %lx
\n
"
,
kernel_vsid_c0
);
printf
(
" kernel vsid - seg c1 = %lx
\n
"
,
kernel_vsid_c1
);
printf
(
" kernel vsid - seg c2 = %lx
\n
"
,
kernel_vsid_c2
);
printf
(
" kernel vsid - seg c3 = %lx
\n
"
,
kernel_vsid_c3
);
printf
(
" kernel vsid - seg c4 = %lx
\n
"
,
kernel_vsid_c4
);
printf
(
" kernel vsid - seg c5 = %lx
\n
"
,
kernel_vsid_c5
);
printf
(
" kernel vsid - seg d = %lx
\n
"
,
kernel_vsid_d
);
printf
(
" kernel vsid - seg e = %lx
\n
"
,
kernel_vsid_e
);
printf
(
" kernel vsid - seg f = %lx
\n
"
,
kernel_vsid_f
);
// print a list of valid vsids for the tasks
read_lock
(
&
tasklist_lock
);
for_each_task
(
p
)
if
(
p
->
mm
)
{
struct
mm_struct
*
mm
=
p
->
mm
;
printf
(
" task = %p mm = %lx pgd %lx
\n
"
,
p
,
mm
,
mm
->
pgd
);
vsid0
=
get_vsid
(
mm
->
context
,
0
);
vsid1
=
get_vsid
(
mm
->
context
,
0x10000000
);
vsid2
=
get_vsid
(
mm
->
context
,
0x20000000
);
vsidB
=
get_vsid
(
mm
->
context
,
0xB0000000
);
printf
(
" context = %lx vsid seg 0 = %lx
\n
"
,
mm
->
context
,
vsid0
);
printf
(
" vsid seg 1 = %lx
\n
"
,
vsid1
);
printf
(
" vsid seg 2 = %lx
\n
"
,
vsid2
);
printf
(
" vsid seg 2 = %lx
\n
"
,
vsidB
);
printf
(
"
\n
"
);
};
read_unlock
(
&
tasklist_lock
);
printf
(
"
\n
Done -------------------
\n
"
);
}
void
mem_check_pagetable_vsids
()
{
unsigned
long
htab_size_bytes
;
unsigned
long
htab_end
;
unsigned
long
last_rpn
;
struct
task_struct
*
p
;
unsigned
long
valid_table_count
,
invalid_table_count
,
bogus_rpn_count
;
int
found
;
unsigned
long
user_address_table_count
,
kernel_page_table_count
;
unsigned
long
pt_vsid
;
HPTE
*
hpte1
;
htab_size_bytes
=
htab_data
.
htab_num_ptegs
*
128
;
// 128B / PTEG
htab_end
=
(
unsigned
long
)
htab_data
.
htab
+
htab_size_bytes
;
// last_rpn = (naca->physicalMemorySize-1) >> PAGE_SHIFT;
last_rpn
=
0xfffff
;
printf
(
"
\n
Hardware Page Table Check
\n
-------------------
\n
"
);
printf
(
"htab base : %.16lx
\n
"
,
htab_data
.
htab
);
printf
(
"htab size : %.16lx
\n
"
,
htab_size_bytes
);
valid_table_count
=
0
;
invalid_table_count
=
0
;
bogus_rpn_count
=
0
;
user_address_table_count
=
0
;
kernel_page_table_count
=
0
;
for
(
hpte1
=
htab_data
.
htab
;
hpte1
<
(
HPTE
*
)
htab_end
;
hpte1
++
)
{
if
(
hpte1
->
dw0
.
dw0
.
v
!=
0
)
{
valid_table_count
++
;
if
(
hpte1
->
dw1
.
dw1
.
rpn
<=
last_rpn
)
{
pt_vsid
=
(
hpte1
->
dw0
.
dw0
.
avpn
)
>>
5
;
if
((
pt_vsid
==
get_kernel_vsid
(
0xC000000000000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xC000000010000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xC000000020000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xC000000030000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xC000000040000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xC000000050000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xD000000000000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xE000000000000000
))
|
(
pt_vsid
==
get_kernel_vsid
(
0xF000000000000000
))
)
{
kernel_page_table_count
++
;
}
else
{
read_lock
(
&
tasklist_lock
);
found
=
0
;
for_each_task
(
p
)
{
if
(
p
->
mm
&&
(
found
==
0
))
{
struct
mm_struct
*
mm
=
p
->
mm
;
if
((
pt_vsid
==
get_vsid
(
mm
->
context
,
0
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x10000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x20000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x30000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x40000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x50000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x60000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x70000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x80000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0x90000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0xA0000000
))
|
(
pt_vsid
==
get_vsid
(
mm
->
context
,
0xB0000000
)))
{
user_address_table_count
++
;
found
=
1
;
}
}
}
read_unlock
(
&
tasklist_lock
);
if
(
found
==
0
)
{
printf
(
" vsid not found vsid = %lx, hpte = %p
\n
"
,
pt_vsid
,
hpte1
);
printf
(
" rpn in entry = %lx
\n
"
,
hpte1
->
dw1
.
dw1
.
rpn
);
printf
(
" mem map address = %lx
\n
"
,
mem_map
+
(
hpte1
->
dw1
.
dw1
.
rpn
));
}
else
// found
{
}
}
// good rpn
}
else
{
bogus_rpn_count
++
;
}
}
else
{
invalid_table_count
++
;
}
}
printf
(
" page table valid counts - valid entries = %lx invalid entries = %lx
\n
"
,
valid_table_count
,
invalid_table_count
);
printf
(
" bogus rpn entries ( probably io) = %lx
\n
"
,
bogus_rpn_count
);
printf
(
" page table counts - kernel entries = %lx user entries = %lx
\n
"
,
kernel_page_table_count
,
user_address_table_count
);
printf
(
"
\n
Done -------------------
\n
"
);
}
static
void
debug_trace
(
void
)
{
unsigned
long
val
,
cmd
,
on
;
...
...
include/asm-ppc64/mmzone.h
0 → 100644
View file @
6a7644b2
/*
* Written by Kanoj Sarcar (kanoj@sgi.com) Aug 99
*
* PowerPC64 port:
* Copyright (C) 2002 Anton Blanchard, IBM Corp.
*/
#ifndef _ASM_MMZONE_H_
#define _ASM_MMZONE_H_
#include <linux/config.h>
typedef
struct
plat_pglist_data
{
pg_data_t
gendata
;
}
plat_pg_data_t
;
/*
* Following are macros that are specific to this numa platform.
*/
extern
plat_pg_data_t
plat_node_data
[];
#define MAX_NUMNODES 4
/* XXX grab this from the device tree - Anton */
#define PHYSADDR_TO_NID(pa) ((pa) >> 36)
#define PLAT_NODE_DATA(n) (&plat_node_data[(n)])
#define PLAT_NODE_DATA_STARTNR(n) \
(PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#define PLAT_NODE_DATA_LOCALNR(p, n) \
(((p) - PLAT_NODE_DATA(n)->gendata.node_start_paddr) >> PAGE_SHIFT)
#ifdef CONFIG_DISCONTIGMEM
/*
* Following are macros that each numa implmentation must define.
*/
/*
* Given a kernel address, find the home node of the underlying memory.
*/
#define KVADDR_TO_NID(kaddr) PHYSADDR_TO_NID(__pa(kaddr))
/*
* Return a pointer to the node data for node n.
*/
#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
* and returns the kaddr corresponding to first physical page in the
* node's mem_map.
*/
#define LOCAL_BASE_ADDR(kaddr) \
((unsigned long)__va(NODE_DATA(KVADDR_TO_NID(kaddr))->node_start_paddr))
#define LOCAL_MAP_NR(kvaddr) \
(((unsigned long)(kvaddr)-LOCAL_BASE_ADDR(kvaddr)) >> PAGE_SHIFT)
#if 0
/* XXX fix - Anton */
#define kern_addr_valid(kaddr) test_bit(LOCAL_MAP_NR(kaddr), \
NODE_DATA(KVADDR_TO_NID(kaddr))->valid_addr_bitmap)
#endif
#define discontigmem_pfn_to_page(pfn) \
({ \
unsigned long kaddr = (unsigned long)__va(pfn << PAGE_SHIFT); \
(ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)); \
})
#ifdef CONFIG_NUMA
/* XXX grab this from the device tree - Anton */
#define cputonode(cpu) ((cpu) >> 3)
#define numa_node_id() cputonode(smp_processor_id())
#endif
/* CONFIG_NUMA */
#endif
/* CONFIG_DISCONTIGMEM */
#endif
/* _ASM_MMZONE_H_ */
include/asm-ppc64/page.h
View file @
6a7644b2
...
...
@@ -215,8 +215,15 @@ static inline int get_order(unsigned long size)
#define __a2p(x) ((void *) absolute_to_phys(x))
#define __a2v(x) ((void *) __va(absolute_to_phys(x)))
#ifdef CONFIG_DISCONTIGMEM
#define page_to_pfn(page) \
((page) - page_zone(page)->zone_mem_map + \
(page_zone(page)->zone_start_paddr >> PAGE_SHIFT))
#define pfn_to_page(pfn) discontigmem_pfn_to_page(pfn)
#else
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(pfn) ((unsigned long)((pfn) - mem_map))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
#endif
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
#define pfn_valid(pfn) ((pfn) < max_mapnr)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment