memory-tiers.c (32008027289239100d8d2876f50b15d92bde1855) memory-tiers.c (467b171af881282fc627328e6c164f044a6df888)
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/slab.h>
3#include <linux/lockdep.h>
4#include <linux/sysfs.h>
5#include <linux/kobject.h>
6#include <linux/memory.h>
7#include <linux/memory-tiers.h>
8

--- 23 unchanged lines hidden (view full) ---

32 int map_count;
33};
34
35static DEFINE_MUTEX(memory_tier_lock);
36static LIST_HEAD(memory_tiers);
37static struct node_memory_type_map node_memory_types[MAX_NUMNODES];
38static struct memory_dev_type *default_dram_type;
39#ifdef CONFIG_MIGRATION
1// SPDX-License-Identifier: GPL-2.0
2#include <linux/slab.h>
3#include <linux/lockdep.h>
4#include <linux/sysfs.h>
5#include <linux/kobject.h>
6#include <linux/memory.h>
7#include <linux/memory-tiers.h>
8

--- 23 unchanged lines hidden (view full) ---

32 int map_count;
33};
34
35static DEFINE_MUTEX(memory_tier_lock);
36static LIST_HEAD(memory_tiers);
37static struct node_memory_type_map node_memory_types[MAX_NUMNODES];
38static struct memory_dev_type *default_dram_type;
39#ifdef CONFIG_MIGRATION
40static int top_tier_adistance;
40/*
41 * node_demotion[] examples:
42 *
43 * Example 1:
44 *
45 * Node 0 & 1 are CPU + DRAM nodes, node 2 & 3 are PMEM nodes.
46 *
47 * node distances:

--- 109 unchanged lines hidden (view full) ---

157 * RCU read locks when accessing the details. No
158 * parallel updates are possible here.
159 */
160 return rcu_dereference_check(pgdat->memtier,
161 lockdep_is_held(&memory_tier_lock));
162}
163
164#ifdef CONFIG_MIGRATION
41/*
42 * node_demotion[] examples:
43 *
44 * Example 1:
45 *
46 * Node 0 & 1 are CPU + DRAM nodes, node 2 & 3 are PMEM nodes.
47 *
48 * node distances:

--- 109 unchanged lines hidden (view full) ---

158 * RCU read locks when accessing the details. No
159 * parallel updates are possible here.
160 */
161 return rcu_dereference_check(pgdat->memtier,
162 lockdep_is_held(&memory_tier_lock));
163}
164
165#ifdef CONFIG_MIGRATION
166bool node_is_toptier(int node)
167{
168 bool toptier;
169 pg_data_t *pgdat;
170 struct memory_tier *memtier;
171
172 pgdat = NODE_DATA(node);
173 if (!pgdat)
174 return false;
175
176 rcu_read_lock();
177 memtier = rcu_dereference(pgdat->memtier);
178 if (!memtier) {
179 toptier = true;
180 goto out;
181 }
182 if (memtier->adistance_start <= top_tier_adistance)
183 toptier = true;
184 else
185 toptier = false;
186out:
187 rcu_read_unlock();
188 return toptier;
189}
190
165void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets)
166{
167 struct memory_tier *memtier;
168
169 /*
170 * pg_data_t.memtier updates includes a synchronize_rcu()
171 * which ensures that we either find NULL or a valid memtier
172 * in NODE_DATA. protect the access via rcu_read_lock();

--- 142 unchanged lines hidden (view full) ---

315 best_distance = distance;
316 node_set(target, nd->preferred);
317 } else {
318 break;
319 }
320 } while (1);
321 }
322 /*
191void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets)
192{
193 struct memory_tier *memtier;
194
195 /*
196 * pg_data_t.memtier updates includes a synchronize_rcu()
197 * which ensures that we either find NULL or a valid memtier
198 * in NODE_DATA. protect the access via rcu_read_lock();

--- 142 unchanged lines hidden (view full) ---

341 best_distance = distance;
342 node_set(target, nd->preferred);
343 } else {
344 break;
345 }
346 } while (1);
347 }
348 /*
349 * Promotion is allowed from a memory tier to higher
350 * memory tier only if the memory tier doesn't include
351 * compute. We want to skip promotion from a memory tier,
352 * if any node that is part of the memory tier have CPUs.
353 * Once we detect such a memory tier, we consider that tier
354 * as top tiper from which promotion is not allowed.
355 */
356 list_for_each_entry_reverse(memtier, &memory_tiers, list) {
357 tier_nodes = get_memtier_nodemask(memtier);
358 nodes_and(tier_nodes, node_states[N_CPU], tier_nodes);
359 if (!nodes_empty(tier_nodes)) {
360 /*
361 * abstract distance below the max value of this memtier
362 * is considered toptier.
363 */
364 top_tier_adistance = memtier->adistance_start +
365 MEMTIER_CHUNK_SIZE - 1;
366 break;
367 }
368 }
369 /*
323 * Now build the lower_tier mask for each node collecting node mask from
324 * all memory tier below it. This allows us to fallback demotion page
325 * allocation to a set of nodes that is closer the above selected
326 * perferred node.
327 */
328 lower_tier = node_states[N_MEMORY];
329 list_for_each_entry(memtier, &memory_tiers, list) {
330 /*

--- 290 unchanged lines hidden ---
370 * Now build the lower_tier mask for each node collecting node mask from
371 * all memory tier below it. This allows us to fallback demotion page
372 * allocation to a set of nodes that is closer the above selected
373 * perferred node.
374 */
375 lower_tier = node_states[N_MEMORY];
376 list_for_each_entry(memtier, &memory_tiers, list) {
377 /*

--- 290 unchanged lines hidden ---