acpi的_PXM 表示device所在的numa id

如果使能了CONFIG_NUMA
#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;
}
#endif
则会定义dev_to_node和set_dev_node 两个函数,调用dev_to_node就会返回当前dev所在的numa id。
如果是acpi boot的话,则会在acpi_create_platform_device 函数的最后调用那个set_dev_node 来设置当前device所在的numa id
        set_dev_node(&pdev->dev, acpi_get_node(adev->handle));
        dev_dbg(&adev->dev, "created platform device %s\n",
            dev_name(&pdev->dev));
这里是通过acpi_get_node来得到numa id后,在通过set_dev_node将numa id保存在dev->numa_node 中。
int acpi_get_node(acpi_handle handle)
{
    int pxm;
    pxm = acpi_get_pxm(handle);
    return acpi_map_pxm_to_node(pxm);
}
在acpi_get_node 中先通过acpi_get_pxm 得到一个pxm,然后调用acpi_map_pxm_to_node 中从__acpi_map_pxm_to_node这个数组以pxe为index找到numa id

static int acpi_get_pxm(acpi_handle h)
{
    unsigned long long pxm;
    acpi_status status;
    acpi_handle handle;
    acpi_handle phandle = h;
    do {
        handle = phandle;
        status = acpi_evaluate_integer(handle, "_PXM", NULL, &pxm);
        if (ACPI_SUCCESS(status))
            return pxm;
        status = acpi_get_parent(handle, &phandle);
    } while (ACPI_SUCCESS(status));
    return -1;
}
原来pxe是acpi协议的一部分,最终调用acpi_evaluate_integer 从bios runtime service得到pxm
得到pxm后再通过acpi_map_pxm_to_node 将


int acpi_map_pxm_to_node(int pxm)
{
    int node;
    if (pxm < 0 || pxm >= MAX_PXM_DOMAINS || numa_off)
        return NUMA_NO_NODE;
    node = pxm_to_node_map[pxm];
    if (node == NUMA_NO_NODE) {
        if (nodes_weight(nodes_found_map) >= MAX_NUMNODES)
            return NUMA_NO_NODE;
        node = first_unset_node(nodes_found_map);
        __acpi_map_pxm_to_node(pxm, node);
        node_set(node, nodes_found_map);
    }
    return node;
}
可以看到pxm_to_node_map 就是一个数组
static int pxm_to_node_map[MAX_PXM_DOMAINS]
            = { [0 ... MAX_PXM_DOMAINS - 1] = NUMA_NO_NODE };
static int node_to_pxm_map[MAX_NUMNODES]
            = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
unsigned char acpi_srat_revision __initdata;
int acpi_numa __initdata;
int pxm_to_node(int pxm)
{
    if (pxm < 0)
        return NUMA_NO_NODE;
    return pxm_to_node_map[pxm];
}

如果pxm_to_node_map中返回的是NUMA_NO_NODE,则调用first_unset_node 找到nodes_found_map 中第一个为0的node,然后通过__acpi_map_pxm_to_node 来更新pxm_to_node_map和node_to_pxm_map 这两个数组,最后再通过node_set 来更新nodes_found_map。
可以很清楚的看到first_unset_node 是找到maskp->bits中第一个为0的bit,这里的mask 就是nodes_found_map
#define first_unset_node(mask) __first_unset_node(&(mask))
static inline int __first_unset_node(const nodemask_t *maskp)
{
    return min_t(int,MAX_NUMNODES,
            find_first_zero_bit(maskp->bits, MAX_NUMNODES));
}
__acpi_map_pxm_to_node则更新pxm_to_node_map和node_to_pxm_map 这两个数组
static void __acpi_map_pxm_to_node(int pxm, int node)
{
    if (pxm_to_node_map[pxm] == NUMA_NO_NODE || node < pxm_to_node_map[pxm])
        pxm_to_node_map[pxm] = node;
    if (node_to_pxm_map[node] == PXM_INVAL || pxm < node_to_pxm_map[node])
        node_to_pxm_map[node] = pxm;
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值