Skip to content

[DM/feature] Simple NUMA (Non-Uniform Memory Access) #9000

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion components/drivers/core/SConscript
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ if GetDepend(['RT_USING_DEV_BUS']) or GetDepend(['RT_USING_DM']):
src = src + ['bus.c']

if GetDepend(['RT_USING_DM']):
src = src + ['dm.c', 'driver.c', 'platform.c']
src = src + ['dm.c', 'driver.c', 'numa.c', 'platform.c']

if GetDepend(['RT_USING_DFS']):
src += ['mnt.c'];
Expand Down
171 changes: 171 additions & 0 deletions components/drivers/core/numa.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-09-24 GuEe-GUI the first version
*/

#include <rtthread.h>
#include <rtdevice.h>

#define DBG_TAG "rtdm.numa"
#define DBG_LVL DBG_INFO
#include <rtdbg.h>

#include <drivers/pic.h>

struct numa_memory
{
rt_list_t list;

int nid;
rt_uint64_t start;
rt_uint64_t end;

union
{
void *ofw_node;
};
};

static rt_bool_t numa_enabled = RT_FALSE;
static int cpu_numa_map[RT_CPUS_NR] rt_section(".bss.noclean.numa");
static rt_list_t numa_memory_nodes rt_section(".bss.noclean.numa");

int rt_numa_cpu_id(int cpuid)
{
if (!numa_enabled)
{
return -RT_ENOSYS;
}

return cpuid < RT_ARRAY_SIZE(cpu_numa_map) ? cpu_numa_map[cpuid] : -RT_EINVAL;
}

int rt_numa_device_id(struct rt_device *dev)
{
rt_uint32_t nid = (rt_uint32_t)-RT_ENOSYS;

if (!numa_enabled)
{
return nid;
}

return rt_dm_dev_prop_read_u32(dev, "numa-node-id", &nid) ? : (int)nid;
}

rt_err_t rt_numa_memory_affinity(rt_uint64_t phy_addr, rt_bitmap_t *out_affinity)
{
struct numa_memory *nm;

if (!out_affinity)
{
return -RT_EINVAL;
}

if (!numa_enabled)
{
/* Default to CPU#0 */
RT_IRQ_AFFINITY_SET(out_affinity, 0);

return RT_EOK;
}

rt_memset(out_affinity, 0, sizeof(*out_affinity) * RT_BITMAP_LEN(RT_CPUS_NR));

rt_list_for_each_entry(nm, &numa_memory_nodes, list)
{
if (phy_addr >= nm->start && phy_addr < nm->end)
{
for (int i = 0; i < RT_ARRAY_SIZE(cpu_numa_map); ++i)
{
if (cpu_numa_map[i] == nm->nid)
{
RT_IRQ_AFFINITY_SET(out_affinity, i);
}
}

return RT_EOK;
}
}

return -RT_EEMPTY;
}

#ifdef RT_USING_OFW
static int numa_ofw_init(void)
{
int i = 0;
rt_uint32_t nid;
const char *numa_conf;
struct rt_ofw_node *np = RT_NULL;

numa_conf = rt_ofw_bootargs_select("numa=", 0);

if (!numa_conf || rt_strcmp(numa_conf, "on"))
{
return (int)RT_EOK;
}

numa_enabled = RT_TRUE;

for (int i = 0; i < RT_ARRAY_SIZE(cpu_numa_map); ++i)
{
cpu_numa_map[i] = -RT_ENOSYS;
}

rt_list_init(&numa_memory_nodes);

rt_ofw_foreach_cpu_node(np)
{
rt_ofw_prop_read_u32(np, "numa-node-id", (rt_uint32_t *)&cpu_numa_map[i]);

if (++i >= RT_CPUS_NR)
{
break;
}
}

rt_ofw_foreach_node_by_type(np, "memory")
{
if (!rt_ofw_prop_read_u32(np, "numa-node-id", &nid))
{
int mem_nr = rt_ofw_get_address_count(np);

for (i = 0; i < mem_nr; ++i)
{
rt_uint64_t addr, size;
struct numa_memory *nm;

if (rt_ofw_get_address(np, i, &addr, &size))
{
continue;
}

nm = rt_malloc(sizeof(*nm));

if (!nm)
{
LOG_E("No memory to record NUMA[%d] memory[%p, %p] info",
nid, addr, addr + size);

return (int)-RT_ENOMEM;
}

nm->start = addr;
nm->end = addr + size;
nm->ofw_node = np;

rt_list_init(&nm->list);
rt_list_insert_before(&numa_memory_nodes, &nm->list);
}
}
}

return 0;
}
INIT_CORE_EXPORT(numa_ofw_init);
#endif /* RT_USING_OFW */
25 changes: 25 additions & 0 deletions components/drivers/include/drivers/core/numa.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-09-24 GuEe-GUI the first version
*/

#ifndef __RT_DM_NUMA_H__
#define __RT_DM_NUMA_H__

#include <rthw.h>
#include <rtthread.h>

#include <bitmap.h>

/* NUMA: Non-Uniform Memory Access */

int rt_numa_cpu_id(int cpuid);
int rt_numa_device_id(struct rt_device *dev);
rt_err_t rt_numa_memory_affinity(rt_uint64_t phy_addr, rt_bitmap_t *out_affinity);

#endif /* __RT_DM_NUMA_H__ */
1 change: 1 addition & 0 deletions components/drivers/include/rtdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ extern "C" {

#ifdef RT_USING_DM
#include "drivers/core/dm.h"
#include "drivers/core/numa.h"
#include "drivers/platform.h"

#ifdef RT_USING_OFW
Expand Down
Loading