Re: [PATCH] SUNRPC: Prevent looping due to rpc_signal_task() races

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, 2025-02-01 at 15:00 -0500, trondmy@xxxxxxxxxx wrote:
> From: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> 
> If rpc_signal_task() is called while a task is in an rpc_call_done()
> callback function, and the latter calls rpc_restart_call(), the task can
> end up looping due to the RPC_TASK_SIGNALLED flag being set without the
> tk_rpc_status being set.
> Removing the redundant mechanism for signalling the task fixes the
> looping behaviour.
> 
> Reported-by: Li Lingfeng <lilingfeng3@xxxxxxxxxx>
> Fixes: 39494194f93b ("SUNRPC: Fix races with rpc_killall_tasks()")
> Signed-off-by: Trond Myklebust <trond.myklebust@xxxxxxxxxxxxxxx>
> ---
>  include/linux/sunrpc/sched.h  | 3 +--
>  include/trace/events/sunrpc.h | 3 +--
>  net/sunrpc/sched.c            | 2 --
>  3 files changed, 2 insertions(+), 6 deletions(-)
> 
> diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
> index fec1e8a1570c..eac57914dcf3 100644
> --- a/include/linux/sunrpc/sched.h
> +++ b/include/linux/sunrpc/sched.h
> @@ -158,7 +158,6 @@ enum {
>  	RPC_TASK_NEED_XMIT,
>  	RPC_TASK_NEED_RECV,
>  	RPC_TASK_MSG_PIN_WAIT,
> -	RPC_TASK_SIGNALLED,
>  };
>  
>  #define rpc_test_and_set_running(t) \
> @@ -171,7 +170,7 @@ enum {
>  
>  #define RPC_IS_ACTIVATED(t)	test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate)
>  
> -#define RPC_SIGNALLED(t)	test_bit(RPC_TASK_SIGNALLED, &(t)->tk_runstate)
> +#define RPC_SIGNALLED(t)	(READ_ONCE(task->tk_rpc_status) == -ERESTARTSYS)
>  
>  /*
>   * Task priorities.
> diff --git a/include/trace/events/sunrpc.h b/include/trace/events/sunrpc.h
> index b13dc275ef4a..851841336ee6 100644
> --- a/include/trace/events/sunrpc.h
> +++ b/include/trace/events/sunrpc.h
> @@ -360,8 +360,7 @@ TRACE_EVENT(rpc_request,
>  		{ (1UL << RPC_TASK_ACTIVE), "ACTIVE" },			\
>  		{ (1UL << RPC_TASK_NEED_XMIT), "NEED_XMIT" },		\
>  		{ (1UL << RPC_TASK_NEED_RECV), "NEED_RECV" },		\
> -		{ (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" },	\
> -		{ (1UL << RPC_TASK_SIGNALLED), "SIGNALLED" })
> +		{ (1UL << RPC_TASK_MSG_PIN_WAIT), "MSG_PIN_WAIT" })
>  
>  DECLARE_EVENT_CLASS(rpc_task_running,
>  
> diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c
> index cef623ea1506..9b45fbdc90ca 100644
> --- a/net/sunrpc/sched.c
> +++ b/net/sunrpc/sched.c
> @@ -864,8 +864,6 @@ void rpc_signal_task(struct rpc_task *task)
>  	if (!rpc_task_set_rpc_status(task, -ERESTARTSYS))
>  		return;
>  	trace_rpc_task_signalled(task, task->tk_action);
> -	set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate);
> -	smp_mb__after_atomic();
>  	queue = READ_ONCE(task->tk_waitqueue);
>  	if (queue)
>  		rpc_wake_up_queued_task(queue, task);

Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>





[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux