Root/
1 | /* |
2 | * This file is subject to the terms and conditions of the GNU General Public |
3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. |
5 | * |
6 | * This file contains NUMA specific variables and functions which can |
7 | * be split away from DISCONTIGMEM and are used on NUMA machines with |
8 | * contiguous memory. |
9 | * |
10 | * 2002/08/07 Erich Focht <efocht@ess.nec.de> |
11 | */ |
12 | |
13 | #include <linux/cpu.h> |
14 | #include <linux/kernel.h> |
15 | #include <linux/mm.h> |
16 | #include <linux/node.h> |
17 | #include <linux/init.h> |
18 | #include <linux/bootmem.h> |
19 | #include <linux/module.h> |
20 | #include <asm/mmzone.h> |
21 | #include <asm/numa.h> |
22 | |
23 | |
24 | /* |
25 | * The following structures are usually initialized by ACPI or |
26 | * similar mechanisms and describe the NUMA characteristics of the machine. |
27 | */ |
28 | int num_node_memblks; |
29 | struct node_memblk_s node_memblk[NR_NODE_MEMBLKS]; |
30 | struct node_cpuid_s node_cpuid[NR_CPUS] = |
31 | { [0 ... NR_CPUS-1] = { .phys_id = 0, .nid = NUMA_NO_NODE } }; |
32 | |
33 | /* |
34 | * This is a matrix with "distances" between nodes, they should be |
35 | * proportional to the memory access latency ratios. |
36 | */ |
37 | u8 numa_slit[MAX_NUMNODES * MAX_NUMNODES]; |
38 | |
39 | /* Identify which cnode a physical address resides on */ |
40 | int |
41 | paddr_to_nid(unsigned long paddr) |
42 | { |
43 | int i; |
44 | |
45 | for (i = 0; i < num_node_memblks; i++) |
46 | if (paddr >= node_memblk[i].start_paddr && |
47 | paddr < node_memblk[i].start_paddr + node_memblk[i].size) |
48 | break; |
49 | |
50 | return (i < num_node_memblks) ? node_memblk[i].nid : (num_node_memblks ? -1 : 0); |
51 | } |
52 | |
53 | #if defined(CONFIG_SPARSEMEM) && defined(CONFIG_NUMA) |
54 | /* |
55 | * Because of holes evaluate on section limits. |
56 | * If the section of memory exists, then return the node where the section |
57 | * resides. Otherwise return node 0 as the default. This is used by |
58 | * SPARSEMEM to allocate the SPARSEMEM sectionmap on the NUMA node where |
59 | * the section resides. |
60 | */ |
61 | int __meminit __early_pfn_to_nid(unsigned long pfn) |
62 | { |
63 | int i, section = pfn >> PFN_SECTION_SHIFT, ssec, esec; |
64 | |
65 | for (i = 0; i < num_node_memblks; i++) { |
66 | ssec = node_memblk[i].start_paddr >> PA_SECTION_SHIFT; |
67 | esec = (node_memblk[i].start_paddr + node_memblk[i].size + |
68 | ((1L << PA_SECTION_SHIFT) - 1)) >> PA_SECTION_SHIFT; |
69 | if (section >= ssec && section < esec) |
70 | return node_memblk[i].nid; |
71 | } |
72 | |
73 | return -1; |
74 | } |
75 | |
76 | #ifdef CONFIG_MEMORY_HOTPLUG |
77 | /* |
78 | * SRAT information is stored in node_memblk[], then we can use SRAT |
79 | * information at memory-hot-add if necessary. |
80 | */ |
81 | |
82 | int memory_add_physaddr_to_nid(u64 addr) |
83 | { |
84 | int nid = paddr_to_nid(addr); |
85 | if (nid < 0) |
86 | return 0; |
87 | return nid; |
88 | } |
89 | |
90 | EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); |
91 | #endif |
92 | #endif |
93 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9