Skip to content

Commit 823430c

Browse files
Ho-Ren (Jack) Chuangakpm00
authored andcommitted
memory tier: consolidate the initialization of memory tiers
The current memory tier initialization process is distributed across two different functions, memory_tier_init() and memory_tier_late_init(). This design is hard to maintain. Thus, this patch is proposed to reduce the possible code paths by consolidating different initialization patches into one. The earlier discussion with Jonathan and Ying is listed here: https://lore.kernel.org/lkml/[email protected]/ If we want to put these two initializations together, they must be placed together in the later function. Because only at that time, the HMAT information will be ready, adist between nodes can be calculated, and memory tiering can be established based on the adist. So we position the initialization at memory_tier_init() to the memory_tier_late_init() call. Moreover, it's natural to keep memory_tier initialization in drivers at device_initcall() level. If we simply move the set_node_memory_tier() from memory_tier_init() to late_initcall(), it will result in HMAT not registering the mt_adistance_algorithm callback function, because set_node_memory_tier() is not performed during the memory tiering initialization phase, leading to a lack of correct default_dram information. Therefore, we introduced a nodemask to pass the information of the default DRAM nodes. The reason for not choosing to reuse default_dram_type->nodes is that it is not clean enough. So in the end, we use a __initdata variable, which is a variable that is released once initialization is complete, including both CPU and memory nodes for HMAT to iterate through. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Ho-Ren (Jack) Chuang <[email protected]> Suggested-by: Jonathan Cameron <[email protected]> Reviewed-by: "Huang, Ying" <[email protected]> Reviewed-by: Jonathan Cameron <[email protected]> Cc: Alistair Popple <[email protected]> Cc: Aneesh Kumar K.V <[email protected]> Cc: Dan Williams <[email protected]> Cc: Dave Jiang <[email protected]> Cc: Gregory Price <[email protected]> Cc: Len Brown <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Rafael J. Wysocki <[email protected]> Cc: Ravi Jonnalagadda <[email protected]> Cc: SeongJae Park <[email protected]> Cc: Tejun Heo <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent a8585ac commit 823430c

File tree

3 files changed

+24
-37
lines changed

3 files changed

+24
-37
lines changed

drivers/acpi/numa/hmat.c

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -940,10 +940,7 @@ static int hmat_set_default_dram_perf(void)
940940
struct memory_target *target;
941941
struct access_coordinate *attrs;
942942

943-
if (!default_dram_type)
944-
return -EIO;
945-
946-
for_each_node_mask(nid, default_dram_type->nodes) {
943+
for_each_node_mask(nid, default_dram_nodes) {
947944
pxm = node_to_pxm(nid);
948945
target = find_mem_target(pxm);
949946
if (!target)

include/linux/memory-tiers.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ struct access_coordinate;
3838
#ifdef CONFIG_NUMA
3939
extern bool numa_demotion_enabled;
4040
extern struct memory_dev_type *default_dram_type;
41+
extern nodemask_t default_dram_nodes;
4142
struct memory_dev_type *alloc_memory_type(int adistance);
4243
void put_memory_type(struct memory_dev_type *memtype);
4344
void init_node_memory_type(int node, struct memory_dev_type *default_type);
@@ -76,6 +77,7 @@ static inline bool node_is_toptier(int node)
7677

7778
#define numa_demotion_enabled false
7879
#define default_dram_type NULL
80+
#define default_dram_nodes NODE_MASK_NONE
7981
/*
8082
* CONFIG_NUMA implementation returns non NULL error.
8183
*/

mm/memory-tiers.c

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ static LIST_HEAD(memory_tiers);
4343
static LIST_HEAD(default_memory_types);
4444
static struct node_memory_type_map node_memory_types[MAX_NUMNODES];
4545
struct memory_dev_type *default_dram_type;
46+
nodemask_t default_dram_nodes __initdata = NODE_MASK_NONE;
4647

4748
static const struct bus_type memory_tier_subsys = {
4849
.name = "memory_tiering",
@@ -671,28 +672,35 @@ EXPORT_SYMBOL_GPL(mt_put_memory_types);
671672

672673
/*
673674
* This is invoked via `late_initcall()` to initialize memory tiers for
674-
* CPU-less memory nodes after driver initialization, which is
675-
* expected to provide `adistance` algorithms.
675+
* memory nodes, both with and without CPUs. After the initialization of
676+
* firmware and devices, adistance algorithms are expected to be provided.
676677
*/
677678
static int __init memory_tier_late_init(void)
678679
{
679680
int nid;
681+
struct memory_tier *memtier;
680682

683+
get_online_mems();
681684
guard(mutex)(&memory_tier_lock);
685+
686+
/* Assign each uninitialized N_MEMORY node to a memory tier. */
682687
for_each_node_state(nid, N_MEMORY) {
683688
/*
684-
* Some device drivers may have initialized memory tiers
685-
* between `memory_tier_init()` and `memory_tier_late_init()`,
686-
* potentially bringing online memory nodes and
687-
* configuring memory tiers. Exclude them here.
689+
* Some device drivers may have initialized
690+
* memory tiers, potentially bringing memory nodes
691+
* online and configuring memory tiers.
692+
* Exclude them here.
688693
*/
689694
if (node_memory_types[nid].memtype)
690695
continue;
691696

692-
set_node_memory_tier(nid);
697+
memtier = set_node_memory_tier(nid);
698+
if (IS_ERR(memtier))
699+
continue;
693700
}
694701

695702
establish_demotion_targets();
703+
put_online_mems();
696704

697705
return 0;
698706
}
@@ -875,8 +883,7 @@ static int __meminit memtier_hotplug_callback(struct notifier_block *self,
875883

876884
static int __init memory_tier_init(void)
877885
{
878-
int ret, node;
879-
struct memory_tier *memtier;
886+
int ret;
880887

881888
ret = subsys_virtual_register(&memory_tier_subsys, NULL);
882889
if (ret)
@@ -887,7 +894,8 @@ static int __init memory_tier_init(void)
887894
GFP_KERNEL);
888895
WARN_ON(!node_demotion);
889896
#endif
890-
mutex_lock(&memory_tier_lock);
897+
898+
guard(mutex)(&memory_tier_lock);
891899
/*
892900
* For now we can have 4 faster memory tiers with smaller adistance
893901
* than default DRAM tier.
@@ -897,29 +905,9 @@ static int __init memory_tier_init(void)
897905
if (IS_ERR(default_dram_type))
898906
panic("%s() failed to allocate default DRAM tier\n", __func__);
899907

900-
/*
901-
* Look at all the existing N_MEMORY nodes and add them to
902-
* default memory tier or to a tier if we already have memory
903-
* types assigned.
904-
*/
905-
for_each_node_state(node, N_MEMORY) {
906-
if (!node_state(node, N_CPU))
907-
/*
908-
* Defer memory tier initialization on
909-
* CPUless numa nodes. These will be initialized
910-
* after firmware and devices are initialized.
911-
*/
912-
continue;
913-
914-
memtier = set_node_memory_tier(node);
915-
if (IS_ERR(memtier))
916-
/*
917-
* Continue with memtiers we are able to setup
918-
*/
919-
break;
920-
}
921-
establish_demotion_targets();
922-
mutex_unlock(&memory_tier_lock);
908+
/* Record nodes with memory and CPU to set default DRAM performance. */
909+
nodes_and(default_dram_nodes, node_states[N_MEMORY],
910+
node_states[N_CPU]);
923911

924912
hotplug_memory_notifier(memtier_hotplug_callback, MEMTIER_HOTPLUG_PRI);
925913
return 0;

0 commit comments

Comments
 (0)