sunrpc __rpc_execute()出现ERESTARTSYS的问题

点击这里查看配套的教学视频

点击跳转到nfs课程所有目录

1 问题描述

点击这里查看日志

有些情况下还会有hung task的日志

2 补丁

分析过程参考openeuler issue

5483b904bf33 SUNRPC: Should wake up the privileged task firstly.
fcb170a9d825 SUNRPC: Fix the batch tasks count wraparound.

3 代码分析

根据打印的日志,挂载不上是因为__rpc_execute()中的捕获到信号:

__rpc_execute
  dprintk("RPC: %5u sync task going to sleep
  out_of_line_wait_on_bit
    __wait_on_bit
      rpc_wait_bit_killable // (*action)(
        if (signal_pending_state
        return -ERESTARTSYS // 512
  dprintk("RPC: %5u got signal
  rpc_exit(task, -ERESTARTSYS

打印出很多rpc任务是因为写/proc/sys/sunrpc/rpc_debug文件:

proc_dodebug
  rpc_show_tasks
    list_for_each_entry(clnt, &sn->all_clients,
    list_for_each_entry(task, &clnt->cl_tasks, // 存在任务才会打印
    rpc_show_header
    rpc_show_task

ForeChannel Slot table相关的流程:

nfs4_alloc_session
  nfs4_init_slot_table(..., "ForeChannel Slot table")
    rpc_init_priority_wait_queue(&tbl->slot_tbl_waitq, ...)
      __rpc_init_priority_wait_queue
        rpc_assign_waitqueue_name
          q->name = name;

nfs4_setup_sequence
  if (nfs4_slot_tbl_draining(tbl) // 如果正在清空slot,则执行goto out_sleep
  nfs4_alloc_slot // 如果找不到空闲的slot,也执行goto out_sleep
  out_sleep:
  rpc_sleep_on_priority(&tbl->slot_tbl_waitq,
  rpc_sleep_on(&tbl->slot_tbl_waitq,

我们还可以在虚拟机中尝试把server端服务停掉,然后写文件,修改/proc/sys/sunrpc/rpc_debug文件的值时, 打印的是类似91 4080 0 8eecf24b e2badc1c 3000 66c9f56f nfsv4 GETATTR a:call_timeout q:delayq:

// 初始化delayq
init_sunrpc
  rpc_init_mempool
    rpc_init_wait_queue(&delay_queue, "delayq")

rpc_delay
  rpc_sleep_on(&delay_queue,
    __rpc_sleep_on_priority
      __rpc_add_wait_queue