numa init 2

我们分别看一下acpi_numa_init 中的这几个函数
int __init acpi_numa_init(void)
{

    /* SRAT: Static Resource Affinity Table */
    if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
        acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY,
                     acpi_parse_x2apic_affinity, 0);
        acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
                     acpi_parse_processor_affinity, 0);
        acpi_table_parse_srat(ACPI_SRAT_TYPE_GICC_AFFINITY,
                      acpi_parse_gicc_affinity, 0);
        cnt = acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
                        acpi_parse_memory_affinity,
                        NR_NODE_MEMBLKS);
    }


}
首先srat 表分为下面几个type
enum acpi_srat_type {
    ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
    ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
    ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
    ACPI_SRAT_TYPE_GICC_AFFINITY = 3,
    ACPI_SRAT_TYPE_RESERVED = 4    /* 4 and greater are reserved */
};
1:acpi_table_parse_srat(ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY, acpi_parse_x2apic_affinity, 0);
查找ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,

static int __init
acpi_parse_x2apic_affinity(struct acpi_subtable_header *header,
               const unsigned long end)
{
    struct acpi_srat_x2apic_cpu_affinity *processor_affinity;

    processor_affinity = (struct acpi_srat_x2apic_cpu_affinity *)header;
    if (!processor_affinity)
        return -EINVAL;

    acpi_table_print_srat_entry(header);

    /* let architecture-dependent part to do it */
    acpi_numa_x2apic_affinity_init(processor_affinity);

    return 0;
}
其中acpi_table_print_srat_entry 主要是打印log,可以忽略。实际做事的函数acpi_numa_x2apic_affinity_init也是打印一行log而已.
void __init __weak
acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa)
{
    pr_warn("Found unsupported x2apic [0x%08x] SRAT entry\n", pa->apic_id);
}
2:    acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, acpi_parse_processor_affinity, 0);

static int __init
acpi_parse_processor_affinity(struct acpi_subtable_header *header,
                  const unsigned long end)
{
    struct acpi_srat_cpu_affinity *processor_affinity;
    /* let architecture-dependent part to do it */
    acpi_numa_processor_affinity_init(processor_affinity);

    return 0;
}

void __init
acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
{
    int pxm;

    if (!(pa->flags & ACPI_SRAT_CPU_ENABLED))
        return;

    if (srat_num_cpus >= ARRAY_SIZE(node_cpuid)) {
        printk_once(KERN_WARNING
                "node_cpuid[%ld] is too small, may not be able to use all cpus\n",
                ARRAY_SIZE(node_cpuid));
        return;
    }
    pxm = get_processor_proximity_domain(pa);

    /* record this node in proximity bitmap */
    pxm_bit_set(pxm);

    node_cpuid[srat_num_cpus].phys_id =
        (pa->apic_id << 8) | (pa->local_sapic_eid);
    /* nid should be overridden as logical node id later */
    node_cpuid[srat_num_cpus].nid = pxm;
    cpumask_set_cpu(srat_num_cpus, &early_cpu_possible_map);
    srat_num_cpus++;
}
这个函数会设定node和cpu的affinity,首先得到phys_id 和nid,然后调用cpumask_set_cpu 来设定cpu mask.
3:    acpi_table_parse_srat(ACPI_SRAT_TYPE_GICC_AFFINITY, acpi_parse_gicc_affinity, 0);
static int __init
acpi_parse_gicc_affinity(struct acpi_subtable_header *header,
             const unsigned long end)
{
    struct acpi_srat_gicc_affinity *processor_affinity;

    processor_affinity = (struct acpi_srat_gicc_affinity *)header;
    if (!processor_affinity)
        return -EINVAL;

    acpi_table_print_srat_entry(header);

    /* let architecture-dependent part to do it */
    acpi_numa_gicc_affinity_init(processor_affinity);

    return 0;
}


/* Callback for Proximity Domain -> ACPI processor UID mapping */
void __init acpi_numa_gicc_affinity_init(struct acpi_srat_gicc_affinity *pa)
{
    int pxm, node;
    u64 mpidr;

    pxm = pa->proximity_domain;
    node = acpi_map_pxm_to_node(pxm);


    early_node_cpu_hwid[cpus_in_srat].node_id = node;
    early_node_cpu_hwid[cpus_in_srat].cpu_hwid =  mpidr;
    node_set(node, numa_nodes_parsed);
    acpi_numa = 1;
    cpus_in_srat++;
    pr_info("SRAT: PXM %d -> MPIDR 0x%Lx -> Node %d cpu %d\n",
        pxm, mpidr, node, cpus_in_srat);
}
这个函数从apci表得到node_id 和 cpu_hwid。最后调用node_set将node设定到numa_nodes_parsed中
4:static int __init
acpi_parse_memory_affinity(struct acpi_subtable_header * header,
               const unsigned long end)
{
    struct acpi_srat_mem_affinity *memory_affinity;

    memory_affinity = (struct acpi_srat_mem_affinity *)header;
        /* let architecture-dependent part to do it */
    if (!acpi_numa_memory_affinity_init(memory_affinity))
        parsed_numa_memblks++;
    return 0;
}
int __init acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
{
    u64 start, end;
    int node, pxm;

    start = ma->base_address;
    end = start + ma->length;
    pxm = ma->proximity_domain;

    node = acpi_map_pxm_to_node(pxm);


    pr_info("SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
        node, pxm,
        (unsigned long long) start, (unsigned long long) end - 1);

    if (numa_add_memblk(node, start, (end - start)) < 0) {
        bad_srat();
        return -EINVAL;
    }

    return 0;
}
主要是调用numa_add_memblk 来为node添加memory,其输入参数是这个node 管理memory的起始地址和size.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值