如下所示device结构体有一个numa_node 表示当前device所在的numa节点。
struct device {
struct device *parent;
struct device_private *p;
struct kobject kobj;
const char *init_name; /* initial name of the device */
const struct device_type *type;
#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
#endif
}
因此一般通过dma_zalloc_coherent等函数申请memory的时候也就会在这个numa节点上申请内存,但是有时候当前节点没有足够的内存,就可以制定和device不同的节点来申请内存.
如下例所示:通过dma_zalloc_coherent 申请的memory就和当前device 不再同一个numa节点上
static void *mlx5_dma_zalloc_coherent_node(struct mlx5_core_dev *dev,
size_t size, dma_addr_t *dma_handle,
int node)
{
struct mlx5_priv *priv = &dev->priv;
int original_node;
void *cpu_handle;
mutex_lock(&priv->alloc_mutex);
//通过dev_to_node的到当前的numa节点并保存到original_node
original_node = dev_to_node(&dev->pdev->dev);
//设置要申请numa节点
set_dev_node(&dev->pdev->dev, node);
cpu_handle = dma_zalloc_coherent(&dev->pdev->dev, size,
dma_handle, GFP_KERNEL);
//restore原本的numa节点
set_dev_node(&dev->pdev->dev, original_node);
mutex_unlock(&priv->alloc_mutex);
return cpu_handle;
}
其中dev_to_node和set_dev_node的源码如下,可见就是操作
#ifdef CONFIG_NUMA
static inline int dev_to_node(struct device *dev)
{
return dev->numa_node;
}
static inline void set_dev_node(struct device *dev, int node)
{
dev->numa_node = node;
}
#else
static inline int dev_to_node(struct device *dev)
{
return -1;
}
static inline void set_dev_node(struct device *dev, int node)
{
}
#endif
申请和device不再同一个numa节点的memory
最新推荐文章于 2024-09-14 16:20:16 发布