linux kernel 状态机,Sunrpc in Linux Kernel

RPC代码位于net/sunrpc/

几个概念

以下信息可以在/sys/kernel/debug/sunrpc中查看

xprt (transport)

struct rpc_xprt描述,代表一个连接(可以是TCP,UDP和RDMA)。由xprt_create_transport创建。

rpc client

struct rpc_clnt描述,代表一个client handle。由rpc_create创建,它会创建transport,并发送ping,判断是否对方支持这个RPC

rpc message

struct rpc_message描述,代表一个rpc message,在创建task时候需要描述rpc message,里面包括传输的参数,返回的参数地址,发生/接收时候用到编码/解码函数等。

rpc task

struct rpc_task描述,代表一个task,内部是一个有限状态机。

RPC 除调度之外的其它接口

rpc_create //返回rpc_clnt

xprt_create_transport //返回rpc_xprt,代表一个TCP连接

rpc_create_xprt //根据rpc_xprt,返回一个rpc_clnt

RPC task数据结构

每个Task(struct rpc_task)就是一个有限状态机,状态机运行完毕表示这个task运行完毕。

RPC Task 调度函数

rpc_execute //运行状态机

rpc_run_task //用rpc_task_setup描述task,对rpc_execute的封装

rpc_call_sync //用rpc_message描述task,对rpc_run_task的封装

rpc_call_async //用rpc_message描述task,对rpc_run_task的封装

rpc_call_start //将task->tk_action设置为call_start

rpc_execute()中,如果task需要prepare,状态机从rpc_prepare_task()开始运行,否则从call_start开始。

NFS Client构造RPC request

NFS Client是sunrpc重要客户,NFS的RPC请求本质上都是构造struct rpc_task,然后调用rpc_run_task完成的。

调用rpc_call_sync()

=>rpc_call_sync() => rpc_run_task() => rpc_execute()

参见nfs4_proc_exchange_id的实现

调用rpc_call_async()

=>rpc_call_async() => rpc_run_task() => rpc_execute()

参见nfs4_proc_async_renew的实现

直接调用rpc_run_task()

参见nfs41_proc_reclaim_complete的实现。

需要注意的是,rpc_task状态机还提供了一些callback,允许在运行之前和之后会被调用。例如:

static const struct rpc_call_ops nfs4_reclaim_complete_call_ops = {

.rpc_call_prepare = nfs4_reclaim_complete_prepare,

.rpc_call_done = nfs4_reclaim_complete_done,

.rpc_release = nfs4_free_reclaim_complete_data,

};

RPC Task 状态机 状态转移

__rpc_execute是RPC的处理函数,本质上是一个有限状态机FSM。如果是同步RPC,由rpc_execute调用。如果是异步RPC,由rpc_execute插入到work queue中调用。

__rpc_execute(struct rpc_task *task)

{

for(;;)

{

task->tk_callback(); //如call_start,call_reserve等。在这里修改tk_callback

}

}

rpc_call_start() => call_start => call_reserve => call_refresh => ... => call_connect => 等等

call_start //0. Initial state

call_reserve //1. Reserve an RPC call slot

call_refresh //2. Bind and/or refresh the credentials

rpc_xdr_encode //3. Encode arguments of an RPC call

call_bind //4. Get the server port number if not yet set

call_transmit //5. Transmit the RPC request, and wait for reply

call_status //6. Sort out the RPC call status

call_decode //7. Decode the RPC reply

work queue

sun rpc里边会使用三个workqueue,分别是rpciod_workqueue,xprtiod_workqueue,nfsiod_workqueue。

rpciod_workqueue:调用__rpc_execute运行rpc task状态机。同步RPC调用运行在调用者的运行上下文,异步RPC在这个work queue执行__rpc_execute。

xprtiod_workqueue:处理网络收发(在Linux 4.4中还没有这个)

nfsiod_workqueue:rpc task使用结束后,需要调用rpc_free_task进行回收。回收可以同步,也可以异步。异步回收时在这个work queue中。这是nfs的RPC请求时提供的。

统计参数

/proc/net/rpc/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值