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>