On Tue, 2 Apr 2024 00:17:37 +0000 "Ho-Ren (Jack) Chuang" <horenchuang@xxxxxxxxxxxxx> wrote: > Since different memory devices require finding, allocating, and putting > memory types, these common steps are abstracted in this patch, > enhancing the scalability and conciseness of the code. > > Signed-off-by: Ho-Ren (Jack) Chuang <horenchuang@xxxxxxxxxxxxx> > Reviewed-by: "Huang, Ying" <ying.huang@xxxxxxxxx> Hi, I know this is a late entry to the discussion but a few comments inline. (sorry I didn't look earlier!) All opportunities to improve code complexity and readability as a result of your factoring out. Jonathan > --- > drivers/dax/kmem.c | 20 ++------------------ > include/linux/memory-tiers.h | 13 +++++++++++++ > mm/memory-tiers.c | 32 ++++++++++++++++++++++++++++++++ > 3 files changed, 47 insertions(+), 18 deletions(-) > > diff --git a/drivers/dax/kmem.c b/drivers/dax/kmem.c > index 42ee360cf4e3..01399e5b53b2 100644 > --- a/drivers/dax/kmem.c > +++ b/drivers/dax/kmem.c > @@ -55,21 +55,10 @@ static LIST_HEAD(kmem_memory_types); > > static struct memory_dev_type *kmem_find_alloc_memory_type(int adist) > { > - bool found = false; > struct memory_dev_type *mtype; > > mutex_lock(&kmem_memory_type_lock); could use guard(mutex)(&kmem_memory_type_lock); return mt_find_alloc_memory_type(adist, &kmem_memory_types); I'm fine if you ignore this comment though as may be other functions in here that could take advantage of the cleanup.h stuff in a future patch. > - list_for_each_entry(mtype, &kmem_memory_types, list) { > - if (mtype->adistance == adist) { > - found = true; > - break; > - } > - } > - if (!found) { > - mtype = alloc_memory_type(adist); > - if (!IS_ERR(mtype)) > - list_add(&mtype->list, &kmem_memory_types); > - } > + mtype = mt_find_alloc_memory_type(adist, &kmem_memory_types); > mutex_unlock(&kmem_memory_type_lock); > > return mtype; > diff --git a/include/linux/memory-tiers.h b/include/linux/memory-tiers.h > index 69e781900082..a44c03c2ba3a 100644 > --- a/include/linux/memory-tiers.h > +++ b/include/linux/memory-tiers.h > @@ -48,6 +48,9 @@ int mt_calc_adistance(int node, int *adist); > int mt_set_default_dram_perf(int nid, struct access_coordinate *perf, > const char *source); > int mt_perf_to_adistance(struct access_coordinate *perf, int *adist); > +struct memory_dev_type *mt_find_alloc_memory_type(int adist, > + struct list_head *memory_types); That indent looks unusual. Align the start of struct with start of int. > +void mt_put_memory_types(struct list_head *memory_types); > #ifdef CONFIG_MIGRATION > int next_demotion_node(int node); > void node_get_allowed_targets(pg_data_t *pgdat, nodemask_t *targets); > @@ -136,5 +139,15 @@ static inline int mt_perf_to_adistance(struct access_coordinate *perf, int *adis > { > return -EIO; > } > + > +struct memory_dev_type *mt_find_alloc_memory_type(int adist, struct list_head *memory_types) > +{ > + return NULL; > +} > + > +void mt_put_memory_types(struct list_head *memory_types) > +{ > + No blank line needed here. > +} > #endif /* CONFIG_NUMA */ > #endif /* _LINUX_MEMORY_TIERS_H */ > diff --git a/mm/memory-tiers.c b/mm/memory-tiers.c > index 0537664620e5..974af10cfdd8 100644 > --- a/mm/memory-tiers.c > +++ b/mm/memory-tiers.c > @@ -623,6 +623,38 @@ void clear_node_memory_type(int node, struct memory_dev_type *memtype) > } > EXPORT_SYMBOL_GPL(clear_node_memory_type); > > +struct memory_dev_type *mt_find_alloc_memory_type(int adist, struct list_head *memory_types) Breaking this out as a separate function provides opportunity to improve it. Maybe a follow up patch makes sense given it would no longer be a straight forward code move. However in my view it would be simple enough to be obvious even within this patch. > +{ > + bool found = false; > + struct memory_dev_type *mtype; > + > + list_for_each_entry(mtype, memory_types, list) { > + if (mtype->adistance == adist) { > + found = true; Why not return here? return mtype; > + break; > + } > + } > + if (!found) { If returning above, no need for found variable - just do this unconditionally. + I suggest you flip logic for simpler to follow code flow. It's more code but I think a bit easier to read as error handling is out of the main simple flow. mtype = alloc_memory_type(adist); if (IS_ERR(mtype)) return mtype; list_add(&mtype->list, memory_types); return mtype; > + mtype = alloc_memory_type(adist); > + if (!IS_ERR(mtype)) > + list_add(&mtype->list, memory_types); > + } > + > + return mtype; > +} > +EXPORT_SYMBOL_GPL(mt_find_alloc_memory_type); > + > +void mt_put_memory_types(struct list_head *memory_types) > +{ > + struct memory_dev_type *mtype, *mtn; > + > + list_for_each_entry_safe(mtype, mtn, memory_types, list) { > + list_del(&mtype->list); > + put_memory_type(mtype); > + } > +} > +EXPORT_SYMBOL_GPL(mt_put_memory_types); > + > static void dump_hmem_attrs(struct access_coordinate *coord, const char *prefix) > { > pr_info(