SPDK线程模型解析

本文深入探讨SPDK线程模型,包括Reactor和Thread的设计与实现,以及在NVMe-oF实例中的应用。SPDK的无锁化设计确保高效性能,通过线程和事件传递实现资源抽象和独立访问。
摘要由CSDN通过智能技术生成

SPDK Thread模型是SPDK诞生以来十分重要的模块,它的设计确保了spdk应用的无锁化编程模型,本篇文章基于spdk最新的release 19.07版本介绍了整体thread模型的设计与实现,并详细分析了NVMe-oF的使用案例。

一. SPDK Thread 模型设计与实现

Reactor – 单个CPU Core抽象,主要包含了:

  • Lcore对应的CPU Core id
  • Threads在该核心下的线程
  • Events这是一个spdk ring,用于事件传递接收

Thread – 线程,但它是spdk抽象出来的线程,主要包含了:

  • io_channels资源的抽象,可以是bdev,也可以是具体的tgt
  • tailq线程队列,用于连接下一个线程
  • name线程的名称
  • Stats用于计时统计闲置和忙时时间的
  • active_pollers轮询使用的poller,非定时
  • timer_pollers定时的poller
  • messages这是一个spdk ring,用于消息传递接收
  • msg_cache事件的缓存

1. Reactor

对象g_reactor_state有五个状态对应了应用中reactors运行运行状态,

enum spdk_reactor_state {
        SPDK_REACTOR_STATE_INVALID = 0,
        SPDK_REACTOR_STATE_INITIALIZED = 1,
        SPDK_REACTOR_STATE_RUNNING = 2,
        SPDK_REACTOR_STATE_EXITING = 3,
        SPDK_REACTOR_STATE_SHUTDOWN = 4,
};

初始情况下是:

SPDK_REACTOR_STATE_INVALID状态,在spdk app(任意一个target,比如nvmf_tgt)启动时,即调用了spdk_app_start方法,会调用spdk_reactors_init,在这个方法中将会初始化所有需要被初始化的reactors(可以在配置文件中指定需要使用的Core,CPU Core 和reactor是一对一的)。并且会将g_reactor_state设置为SPDK_REACTOR_STATE_INITIALIZED。具体代码如下:

Int spdk_reactors_init(void)
{
        // 初始化所有的event mempool
        g_spdk_event_mempool = spdk_mempool_create(…);
        // 为g_reactors分配内存,g_reactors是一个数组,管理了所有的reactors
posix_memalign((void **)&g_reactors, 64,  (last_core + 1) * sizeof(struct spdk_reactor));
// 这里设置了reactor创建线程的方法,之后需要初始化线程的时候将会调用该方法
spdk_thread_lib_init(spdk_reactor_schedule_thread, sizeof(struct spdk_lw_thread));
// 对于每一个启动的reactor,将会初始化它们
// 初始化reactor过程,即为绑定lcore,初始化spdk ring、threads,对rusage无操作
SPDK_ENV_FOREACH_CORE(i) {
reactor = spdk_reactor_get(i);
spdk_reactor_construct(reactor, i);
}
               // 设置好状态返回
g_reactor_state = SPDK_REACTOR_STATE_INITIALIZED;
return 0;
}

在进入SPDK_REACTOR_STATE_INITIALIZED状态且spdk_app_start在创建了自己的线程并绑定到了reactors后,会调用spdk_reactors_start方法并将g_reactor_state设置为SPDK_REACTOR_STATE_RUNNING状态并会创建所有reactor的线程且轮询。

Void spdk_reactors_start(void) {
SPDK_ENV_FOREACH_CORE(i) {
                       if (i != current_core) { // 在非master reactor中
                                      reactor = spdk_reactor_get(i); // 得到相应的reactor
                                      // 设置好线程创建后的一个消息,该消息为轮询函数
                                      rc = spdk_env_thread_launch_pinned(reactor->lcore, _spdk_reactor_run, reactor);                             
                                      // reactor创建好线程并且会自动执行第一个消息
                                     spdk_thread_create(thread_name, tmp_cpuma
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值