抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

SPDK 自带的性能测试应用 spdk_nvme_perf 的源代码 perf.c 的粗浅分析,进一步熟悉 SPDK 用户态驱动的主要工作流程和方式。

简介

perf 是 SPDK 用来测试 NVMe SSD 性能的工具,最新版本的 SPDK 中 perf 源代码在 spdk/app/spdk_nvme_perf/ 路径下。perf 主要用来测试 NVMe SSD 的 IOPS,Bandwidth 和 Latency,它既可以测本地的 target,也可以测远端的 target。

perf 主流程


perf 资源


TODO

  1. 函数调用栈 + 控制流程图 + 数据流程图,按照不同流程图分章节跟进重要函数中去;

  2. 所有用到的重要资源,如 spdk_nvme_ctrlrspdk_nvme_ns 数据结构等,理清他们的关系,类似于 UML 类图;

  3. controller 状态转移图。

函数调用栈说明:

  • 相同缩进表示同一层的函数执行;不同缩进表示存在函数内调用另一个函数。

  • 花括号表示循环体。

  • 函数结尾 ; 表示该函数结束;: 表示进入该函数,接下来存在函数调用。


(一)控制流(初始化)

流程图:

函数调用栈:

spdk_env_opts_init(&opts);
parse_args(...):
    while {
        getopt_long(..., g_perf_cmdline_opts, ...);
        add_trid(...);
        ...
    }
spdk_env_init(&opts);
register_workers():
    SPDK_ENV_FOREACH_CORE(i) {
        worker = calloc(...);
    }
    TAILQ_INIT(&worker->ns_ctx);
    TAILQ_INSERT_TAIL(&g_workers, worker, link);
register_controllers():
    TAILQ_FOREACH(trid_entry, &g_trid_list, tailq) {
        spdk_nvme_probe(&trid_entry->trid, trid_entry, probe_cb, attach_cb, NULL):
            probe_ctx = spdk_nvme_probe_async(...):
                nvme_driver_init();
                probe_ctx = calloc(...);
                nvme_probe_ctx_init(probe_ctx, ...):
                    TAILQ_INIT(&probe_ctx->init_ctrlrs);
                nvme_probe_internal(probe_ctx, false):
                    nvme_rdma.c: nvme_fabric_ctrlr_scan(probe_ctx, ...): (识别 ctrlr 过程)
                        (该函数调用见后文)
            nvme_init_controllers(probe_ctx):
                spdk_nvme_probe_poll_async(probe_ctx):
                    TAILQ_FOREACH_SAFE(ctrlr, &probe_ctx->init_ctrlrs, ...) {
                        nvme_ctrlr_poll_internal(ctrlr, probe_ctx):
                            nvme_ctrlr_process_init(ctrlr);
                            TAILQ_REMOVE(&probe_ctx->init_ctrlrs, ctrlr, ...);
                            perf.c: attach_cb(...):
                                register_ctrlr(ctrlr, trid_entry):
                                    TAILQ_INSERT_TAIL(&g_controllers, ctrlr_entry, ...);
                                    (该函数剩余的函数调用见后文)
                    }
    }

(二)控制流(初始化 - fabric_ctrlr_scan)


(三)控制流(初始化 - register_ns)


(四)控制流(任务执行)


(五)数据流(发送)


(六)数据流(接收)





本站采用 Volantis 主题设计