On Fri, Feb 14, 2025 at 08:40:02PM +0100, Andrea Righi wrote: > Introduce the new helper nearest_node_nodemask() to find the closest > node in a specified nodemask from a given starting node. > > Returns MAX_NUMNODES if no node is found. > > Suggested-by: Yury Norov [NVIDIA] <yury.norov@xxxxxxxxx> > Signed-off-by: Andrea Righi <arighi@xxxxxxxxxx> Acked-by: Yury Norov [NVIDIA] <yury.norov@xxxxxxxxx> > --- > include/linux/numa.h | 7 +++++++ > mm/mempolicy.c | 31 +++++++++++++++++++++++++++++++ > 2 files changed, 38 insertions(+) > > diff --git a/include/linux/numa.h b/include/linux/numa.h > index 31d8bf8a951a7..e6baaf6051bcf 100644 > --- a/include/linux/numa.h > +++ b/include/linux/numa.h > @@ -31,6 +31,8 @@ void __init alloc_offline_node_data(int nid); > /* Generic implementation available */ > int numa_nearest_node(int node, unsigned int state); > > +int nearest_node_nodemask(int node, nodemask_t *mask); > + > #ifndef memory_add_physaddr_to_nid > int memory_add_physaddr_to_nid(u64 start); > #endif > @@ -47,6 +49,11 @@ static inline int numa_nearest_node(int node, unsigned int state) > return NUMA_NO_NODE; > } > > +static inline int nearest_node_nodemask(int node, nodemask_t *mask) > +{ > + return NUMA_NO_NODE; > +} > + > static inline int memory_add_physaddr_to_nid(u64 start) > { > return 0; > diff --git a/mm/mempolicy.c b/mm/mempolicy.c > index 162407fbf2bc7..488cad280efb3 100644 > --- a/mm/mempolicy.c > +++ b/mm/mempolicy.c > @@ -196,6 +196,37 @@ int numa_nearest_node(int node, unsigned int state) > } > EXPORT_SYMBOL_GPL(numa_nearest_node); > > +/** > + * nearest_node_nodemask - Find the node in @mask at the nearest distance > + * from @node. > + * > + * @node: a valid node ID to start the search from. > + * @mask: a pointer to a nodemask representing the allowed nodes. > + * > + * This function iterates over all nodes in @mask and calculates the > + * distance from the starting @node, then it returns the node ID that is > + * the closest to @node, or MAX_NUMNODES if no node is found. > + * > + * Note that @node must be a valid node ID usable with node_distance(), > + * providing an invalid node ID (e.g., NUMA_NO_NODE) may result in crashes > + * or unexpected behavior. > + */ > +int nearest_node_nodemask(int node, nodemask_t *mask) > +{ > + int dist, n, min_dist = INT_MAX, min_node = MAX_NUMNODES; > + > + for_each_node_mask(n, *mask) { > + dist = node_distance(node, n); > + if (dist < min_dist) { > + min_dist = dist; > + min_node = n; > + } > + } > + > + return min_node; > +} > +EXPORT_SYMBOL_GPL(nearest_node_nodemask); > + > struct mempolicy *get_task_policy(struct task_struct *p) > { > struct mempolicy *pol = p->mempolicy; > -- > 2.48.1