1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_MEMORY_TIERS_H |
3 | #define _LINUX_MEMORY_TIERS_H |
4 | |
5 | #include <linux/types.h> |
6 | #include <linux/nodemask.h> |
7 | #include <linux/kref.h> |
8 | #include <linux/mmzone.h> |
9 | #include <linux/notifier.h> |
10 | /* |
11 | * Each tier cover a abstrace distance chunk size of 128 |
12 | */ |
13 | #define MEMTIER_CHUNK_BITS 7 |
14 | #define MEMTIER_CHUNK_SIZE (1 << MEMTIER_CHUNK_BITS) |
15 | /* |
16 | * Smaller abstract distance values imply faster (higher) memory tiers. Offset |
17 | * the DRAM adistance so that we can accommodate devices with a slightly lower |
18 | * adistance value (slightly faster) than default DRAM adistance to be part of |
19 | * the same memory tier. |
20 | */ |
21 | #define MEMTIER_ADISTANCE_DRAM ((4 * MEMTIER_CHUNK_SIZE) + (MEMTIER_CHUNK_SIZE >> 1)) |
22 | |
23 | struct memory_tier; |
24 | struct memory_dev_type { |
25 | /* list of memory types that are part of same tier as this type */ |
26 | struct list_head tier_sibling; |
27 | /* list of memory types that are managed by one driver */ |
28 | struct list_head list; |
29 | /* abstract distance for this specific memory type */ |
30 | int adistance; |
31 | /* Nodes of same abstract distance */ |
32 | nodemask_t nodes; |
33 | struct kref kref; |
34 | }; |
35 | |
36 | struct access_coordinate; |
37 | |
38 | #ifdef CONFIG_NUMA |
39 | extern bool numa_demotion_enabled; |
40 | extern struct memory_dev_type *default_dram_type; |
41 | struct memory_dev_type *alloc_memory_type(int adistance); |
42 | void put_memory_type(struct memory_dev_type *memtype); |
43 | void init_node_memory_type(int node, struct memory_dev_type *default_type); |
44 | void clear_node_memory_type(int node, struct memory_dev_type *memtype); |
45 | int register_mt_adistance_algorithm(struct notifier_block *nb); |
46 | int unregister_mt_adistance_algorithm(struct notifier_block *nb); |
47 | int mt_calc_adistance(int node, int *adist); |
48 | int mt_set_default_dram_perf(int nid, struct access_coordinate *perf, |
49 | const char *source); |
50 | int mt_perf_to_adistance(struct access_coordinate *perf, int *adist); |
51 | #ifdef CONFIG_MIGRATION |
52 | int next_demotion_node(int node); |
53 | void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets); |
54 | bool node_is_toptier(int node); |
55 | #else |
56 | static inline int next_demotion_node(int node) |
57 | { |
58 | return NUMA_NO_NODE; |
59 | } |
60 | |
61 | static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets) |
62 | { |
63 | *targets = NODE_MASK_NONE; |
64 | } |
65 | |
66 | static inline bool node_is_toptier(int node) |
67 | { |
68 | return true; |
69 | } |
70 | #endif |
71 | |
72 | #else |
73 | |
74 | #define numa_demotion_enabled false |
75 | #define default_dram_type NULL |
76 | /* |
77 | * CONFIG_NUMA implementation returns non NULL error. |
78 | */ |
79 | static inline struct memory_dev_type *alloc_memory_type(int adistance) |
80 | { |
81 | return NULL; |
82 | } |
83 | |
84 | static inline void put_memory_type(struct memory_dev_type *memtype) |
85 | { |
86 | |
87 | } |
88 | |
89 | static inline void init_node_memory_type(int node, struct memory_dev_type *default_type) |
90 | { |
91 | |
92 | } |
93 | |
94 | static inline void clear_node_memory_type(int node, struct memory_dev_type *memtype) |
95 | { |
96 | |
97 | } |
98 | |
99 | static inline int next_demotion_node(int node) |
100 | { |
101 | return NUMA_NO_NODE; |
102 | } |
103 | |
104 | static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets) |
105 | { |
106 | *targets = NODE_MASK_NONE; |
107 | } |
108 | |
109 | static inline bool node_is_toptier(int node) |
110 | { |
111 | return true; |
112 | } |
113 | |
114 | static inline int register_mt_adistance_algorithm(struct notifier_block *nb) |
115 | { |
116 | return 0; |
117 | } |
118 | |
119 | static inline int unregister_mt_adistance_algorithm(struct notifier_block *nb) |
120 | { |
121 | return 0; |
122 | } |
123 | |
124 | static inline int mt_calc_adistance(int node, int *adist) |
125 | { |
126 | return NOTIFY_DONE; |
127 | } |
128 | |
129 | static inline int mt_set_default_dram_perf(int nid, struct access_coordinate *perf, |
130 | const char *source) |
131 | { |
132 | return -EIO; |
133 | } |
134 | |
135 | static inline int mt_perf_to_adistance(struct access_coordinate *perf, int *adist) |
136 | { |
137 | return -EIO; |
138 | } |
139 | #endif /* CONFIG_NUMA */ |
140 | #endif /* _LINUX_MEMORY_TIERS_H */ |
141 | |