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 ((4L * 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 extern nodemask_t default_dram_nodes; 42 struct memory_dev_type *alloc_memory_type(int adistance); 43 void put_memory_type(struct memory_dev_type *memtype); 44 void init_node_memory_type(int node, struct memory_dev_type *default_type); 45 void clear_node_memory_type(int node, struct memory_dev_type *memtype); 46 int register_mt_adistance_algorithm(struct notifier_block *nb); 47 int unregister_mt_adistance_algorithm(struct notifier_block *nb); 48 int mt_calc_adistance(int node, int *adist); 49 int mt_set_default_dram_perf(int nid, struct access_coordinate *perf, 50 const char *source); 51 int mt_perf_to_adistance(struct access_coordinate *perf, int *adist); 52 struct memory_dev_type *mt_find_alloc_memory_type(int adist, 53 struct list_head *memory_types); 54 void mt_put_memory_types(struct list_head *memory_types); 55 #ifdef CONFIG_MIGRATION 56 int next_demotion_node(int node); 57 void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets); 58 bool node_is_toptier(int node); 59 #else 60 static inline int next_demotion_node(int node) 61 { 62 return NUMA_NO_NODE; 63 } 64 65 static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets) 66 { 67 *targets = NODE_MASK_NONE; 68 } 69 70 static inline bool node_is_toptier(int node) 71 { 72 return true; 73 } 74 #endif 75 76 #else 77 78 #define numa_demotion_enabled false 79 #define default_dram_type NULL 80 #define default_dram_nodes NODE_MASK_NONE 81 /* 82 * CONFIG_NUMA implementation returns non NULL error. 83 */ 84 static inline struct memory_dev_type *alloc_memory_type(int adistance) 85 { 86 return NULL; 87 } 88 89 static inline void put_memory_type(struct memory_dev_type *memtype) 90 { 91 92 } 93 94 static inline void init_node_memory_type(int node, struct memory_dev_type *default_type) 95 { 96 97 } 98 99 static inline void clear_node_memory_type(int node, struct memory_dev_type *memtype) 100 { 101 102 } 103 104 static inline int next_demotion_node(int node) 105 { 106 return NUMA_NO_NODE; 107 } 108 109 static inline void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets) 110 { 111 *targets = NODE_MASK_NONE; 112 } 113 114 static inline bool node_is_toptier(int node) 115 { 116 return true; 117 } 118 119 static inline int register_mt_adistance_algorithm(struct notifier_block *nb) 120 { 121 return 0; 122 } 123 124 static inline int unregister_mt_adistance_algorithm(struct notifier_block *nb) 125 { 126 return 0; 127 } 128 129 static inline int mt_calc_adistance(int node, int *adist) 130 { 131 return NOTIFY_DONE; 132 } 133 134 static inline int mt_set_default_dram_perf(int nid, struct access_coordinate *perf, 135 const char *source) 136 { 137 return -EIO; 138 } 139 140 static inline int mt_perf_to_adistance(struct access_coordinate *perf, int *adist) 141 { 142 return -EIO; 143 } 144 145 static inline struct memory_dev_type *mt_find_alloc_memory_type(int adist, 146 struct list_head *memory_types) 147 { 148 return NULL; 149 } 150 151 static inline void mt_put_memory_types(struct list_head *memory_types) 152 { 153 } 154 #endif /* CONFIG_NUMA */ 155 #endif /* _LINUX_MEMORY_TIERS_H */ 156