@@ -100,6 +100,7 @@ static struct bio_nvme_data nvme_glb;
100100static int
101101bio_spdk_env_init (void )
102102{
103+ // 构建spdk opt
103104 struct spdk_env_opts opts ;
104105 bool enable_rpc_srv = false;
105106 int rc ;
@@ -123,6 +124,7 @@ bio_spdk_env_init(void)
123124 // == true
124125 if (bio_nvme_configured (SMD_DEV_TYPE_MAX )) {
125126 // 传递allowed bdev pci 地址给spdk,即将nvme addr 添加到opts 的allowlist 中
127+ // nvme 类型的bdev,创建命令是conf 中的 attach controller
126128 rc = bio_add_allowed_alloc (nvme_glb .bd_nvme_conf , & opts , & roles );
127129 if (rc != 0 ) {
128130 D_ERROR ("Failed to add allowed devices to SPDK env, " DF_RC "\n" ,
@@ -483,6 +485,7 @@ struct common_cp_arg {
483485static void
484486common_prep_arg (struct common_cp_arg * arg )
485487{
488+ // 设置一个 inflight
486489 arg -> cca_inflights = 1 ;
487490 arg -> cca_rc = 0 ;
488491 arg -> cca_bs = NULL ;
@@ -491,6 +494,7 @@ common_prep_arg(struct common_cp_arg *arg)
491494static void
492495common_init_cb (void * arg , int rc )
493496{
497+ // rpc 执行成功或者超时后,inflight 自减
494498 struct common_cp_arg * cp_arg = arg ;
495499
496500 D_ASSERT (cp_arg -> cca_inflights == 1 );
@@ -1732,28 +1736,39 @@ bio_xsctxt_alloc(struct bio_xs_context **pctxt, int tgt_id, bool self_polling)
17321736 common_prep_arg (& cp_arg );
17331737 // 这里用的是全局的nvme conf 文件,每个engine 有自己单独的
17341738 // spdk 中子系统其实就是模块的意思,比如子系统名字为bdev,表示bdev 模块
1739+ // 这里面会调用 spdk_rpc_initialize,会启动rpc 服务监听
17351740 spdk_subsystem_init_from_json_config (nvme_glb .bd_nvme_conf ,
17361741 SPDK_DEFAULT_RPC_ADDR ,
17371742 subsys_init_cb , & cp_arg ,
17381743 true);
1744+ // init from json 会注册 rpc_subsystem_poll,rpc_client_connect_poller,用于接收rpc 请求
1745+ // 这里是为了等待rpc req 被处理完,或者req 超时
17391746 rc = xs_poll_completion (ctxt , & cp_arg .cca_inflights , 0 );
17401747 D_ASSERT (rc == 0 );
17411748
1749+ // 初始化失败了
17421750 if (cp_arg .cca_rc != 0 ) {
17431751 rc = cp_arg .cca_rc ;
17441752 D_ERROR ("failed to init bdevs, rc:%d\n" , rc );
17451753 goto out ;
17461754 }
17471755
17481756 /* Continue poll until no more events */
1749- // todo: 这里是为啥
1757+ // 这个时间点:
1758+ // 1. 不会有其他xs,所有没人给这个 init_thread 通过 spdk_thread_send_msg 发meg
1759+ // 2. 所以只能是处理已经注册过的poller:rpc_subsystem_poll,rpc_client_connect_poller
1760+ // 1-1: spdk_subsystem_init_from_json_config --> spdk_rpc_initialize --> rpc_subsystem_poll --> spdk_rpc_accept ---> spdk_jsonrpc_server_poll: 检查监听的socket,处理连接
1761+ // 2-2: spdk_subsystem_init_from_json_config --> rpc_client_connect_poller --> spdk_jsonrpc_client_poll --> jsonrpc_client_poll / jsonrpc_client_poll_connecting
1762+ // return 1 if work was done. 0 if no work was done.
1763+ // 返回0表示轮询成功,但是没有处理任何事件;返回>0 表示轮询成功,且处理了n 个事件;返回 <0 表示轮询失败
1764+ // 这里是loop 直到所有的事件都被处理完
17501765 while (spdk_thread_poll (ctxt -> bxc_thread , 0 , 0 ) > 0 )
17511766 ;
17521767 // 这个日志会打印,tgt_id 为 0
1753- // todo: 什么样才算初始化完成 ,此时可以通过 spdk_bdev_first 拿到spdk bdev 了吗?
1768+ // 初始化完成 ,此时可以通过 spdk_bdev_first 拿到spdk bdev 了
17541769 D_DEBUG (DB_MGMT , "SPDK bdev initialized, tgt_id:%d" , tgt_id );
17551770
1756- // 将spdk thread 设置到全局数据中,表示在众多(每个xs 有各自的spdk thread)的thread 中,当前是扫描bdev那个
1771+ // 将spdk thread 设置到全局数据中,表示在众多(每个xs 有各自的spdk thread)的thread 中,当前是初始化的那个
17571772 nvme_glb .bd_init_thread = ctxt -> bxc_thread ;
17581773
17591774 // 内部会load_blobstore 最终创建spdk bs,只有target 0 会执行
@@ -1764,7 +1779,10 @@ bio_xsctxt_alloc(struct bio_xs_context **pctxt, int tgt_id, bool self_polling)
17641779 goto out ;
17651780 }
17661781
1767- // bio bdev 初始化完成后,重启spdk rpc server。rpc 默认是禁用的
1782+ // 上面 spdk_subsystem_init_from_json_config 中会通过调用 spdk_rpc_initialize 自动开启rpc 监听
1783+ // 用于处理json 文件中配置的method,其中 nvme_attach_controller 会1. 创建nvme ctrlr 2. 添加ns 到nvme ctrlr 3. 注册spdk nvme bdev
1784+ // 在 init_bio_bdevs 函数执行之前,spdk nvme bdev 注册已经完成(通过nvme_attach_controller 对应的mapping 函数,走的rpc 流程)
1785+ // 当 bio bdev 初始化完成后,重启spdk rpc server,这里是false,所以不用重启
17681786 /* After bio_bdevs are initialized, restart SPDK JSON-RPC server if required. */
17691787 // 默认是false
17701788 if (nvme_glb .bd_enable_rpc_srv ) {
0 commit comments