1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | /* |
3 | * include/linux/node.h - generic node definition |
4 | * |
5 | * This is mainly for topological representation. We define the |
6 | * basic 'struct node' here, which can be embedded in per-arch |
7 | * definitions of processors. |
8 | * |
9 | * Basic handling of the devices is done in drivers/base/node.c |
10 | * and system devices are handled in drivers/base/sys.c. |
11 | * |
12 | * Nodes are exported via driverfs in the class/node/devices/ |
13 | * directory. |
14 | */ |
15 | #ifndef _LINUX_NODE_H_ |
16 | #define _LINUX_NODE_H_ |
17 | |
18 | #include <linux/device.h> |
19 | #include <linux/cpumask.h> |
20 | #include <linux/list.h> |
21 | |
22 | /** |
23 | * struct node_hmem_attrs - heterogeneous memory performance attributes |
24 | * |
25 | * @read_bandwidth: Read bandwidth in MB/s |
26 | * @write_bandwidth: Write bandwidth in MB/s |
27 | * @read_latency: Read latency in nanoseconds |
28 | * @write_latency: Write latency in nanoseconds |
29 | */ |
30 | struct node_hmem_attrs { |
31 | unsigned int read_bandwidth; |
32 | unsigned int write_bandwidth; |
33 | unsigned int read_latency; |
34 | unsigned int write_latency; |
35 | }; |
36 | |
37 | enum cache_indexing { |
38 | NODE_CACHE_DIRECT_MAP, |
39 | NODE_CACHE_INDEXED, |
40 | NODE_CACHE_OTHER, |
41 | }; |
42 | |
43 | enum cache_write_policy { |
44 | NODE_CACHE_WRITE_BACK, |
45 | NODE_CACHE_WRITE_THROUGH, |
46 | NODE_CACHE_WRITE_OTHER, |
47 | }; |
48 | |
49 | /** |
50 | * struct node_cache_attrs - system memory caching attributes |
51 | * |
52 | * @indexing: The ways memory blocks may be placed in cache |
53 | * @write_policy: Write back or write through policy |
54 | * @size: Total size of cache in bytes |
55 | * @line_size: Number of bytes fetched on a cache miss |
56 | * @level: The cache hierarchy level |
57 | */ |
58 | struct node_cache_attrs { |
59 | enum cache_indexing indexing; |
60 | enum cache_write_policy write_policy; |
61 | u64 size; |
62 | u16 line_size; |
63 | u8 level; |
64 | }; |
65 | |
66 | #ifdef CONFIG_HMEM_REPORTING |
67 | void node_add_cache(unsigned int nid, struct node_cache_attrs *cache_attrs); |
68 | void node_set_perf_attrs(unsigned int nid, struct node_hmem_attrs *hmem_attrs, |
69 | unsigned access); |
70 | #else |
71 | static inline void node_add_cache(unsigned int nid, |
72 | struct node_cache_attrs *cache_attrs) |
73 | { |
74 | } |
75 | |
76 | static inline void node_set_perf_attrs(unsigned int nid, |
77 | struct node_hmem_attrs *hmem_attrs, |
78 | unsigned access) |
79 | { |
80 | } |
81 | #endif |
82 | |
83 | struct node { |
84 | struct device dev; |
85 | struct list_head access_list; |
86 | #ifdef CONFIG_HMEM_REPORTING |
87 | struct list_head cache_attrs; |
88 | struct device *cache_dev; |
89 | #endif |
90 | }; |
91 | |
92 | struct memory_block; |
93 | extern struct node *node_devices[]; |
94 | |
95 | #if defined(CONFIG_MEMORY_HOTPLUG) && defined(CONFIG_NUMA) |
96 | void register_memory_blocks_under_node(int nid, unsigned long start_pfn, |
97 | unsigned long end_pfn, |
98 | enum meminit_context context); |
99 | #else |
100 | static inline void register_memory_blocks_under_node(int nid, unsigned long start_pfn, |
101 | unsigned long end_pfn, |
102 | enum meminit_context context) |
103 | { |
104 | } |
105 | #endif |
106 | |
107 | extern void unregister_node(struct node *node); |
108 | #ifdef CONFIG_NUMA |
109 | extern void node_dev_init(void); |
110 | /* Core of the node registration - only memory hotplug should use this */ |
111 | extern int __register_one_node(int nid); |
112 | |
113 | /* Registers an online node */ |
114 | static inline int register_one_node(int nid) |
115 | { |
116 | int error = 0; |
117 | |
118 | if (node_online(nid)) { |
119 | struct pglist_data *pgdat = NODE_DATA(nid); |
120 | unsigned long start_pfn = pgdat->node_start_pfn; |
121 | unsigned long end_pfn = start_pfn + pgdat->node_spanned_pages; |
122 | |
123 | error = __register_one_node(nid); |
124 | if (error) |
125 | return error; |
126 | register_memory_blocks_under_node(nid, start_pfn, end_pfn, |
127 | MEMINIT_EARLY); |
128 | } |
129 | |
130 | return error; |
131 | } |
132 | |
133 | extern void unregister_one_node(int nid); |
134 | extern int register_cpu_under_node(unsigned int cpu, unsigned int nid); |
135 | extern int unregister_cpu_under_node(unsigned int cpu, unsigned int nid); |
136 | extern void unregister_memory_block_under_nodes(struct memory_block *mem_blk); |
137 | |
138 | extern int register_memory_node_under_compute_node(unsigned int mem_nid, |
139 | unsigned int cpu_nid, |
140 | unsigned access); |
141 | #else |
142 | static inline void node_dev_init(void) |
143 | { |
144 | } |
145 | static inline int __register_one_node(int nid) |
146 | { |
147 | return 0; |
148 | } |
149 | static inline int register_one_node(int nid) |
150 | { |
151 | return 0; |
152 | } |
153 | static inline int unregister_one_node(int nid) |
154 | { |
155 | return 0; |
156 | } |
157 | static inline int register_cpu_under_node(unsigned int cpu, unsigned int nid) |
158 | { |
159 | return 0; |
160 | } |
161 | static inline int unregister_cpu_under_node(unsigned int cpu, unsigned int nid) |
162 | { |
163 | return 0; |
164 | } |
165 | static inline void unregister_memory_block_under_nodes(struct memory_block *mem_blk) |
166 | { |
167 | } |
168 | #endif |
169 | |
170 | #define to_node(device) container_of(device, struct node, dev) |
171 | |
172 | #endif /* _LINUX_NODE_H_ */ |
173 | |