美文网首页
Sunrpc in Linux Kernel

Sunrpc in Linux Kernel

作者: 帆子_8c3a | 来源:发表于2019-03-13 15:15 被阅读0次

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/

相关文章

网友评论

      本文标题:Sunrpc in Linux Kernel

      本文链接:https://www.haomeiwen.com/subject/jzxtmqtx.html