This is a note to let you know that I've just added the patch titled RDMA/addr: Fix race with netevent_callback()/rdma_addr_cancel() to the 5.4-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: rdma-addr-fix-race-with-netevent_callback-rdma_addr_cancel.patch and it can be found in the queue-5.4 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 2ee9bf346fbfd1dad0933b9eb3a4c2c0979b633e Mon Sep 17 00:00:00 2001 From: Jason Gunthorpe <jgg@xxxxxxxxxx> Date: Wed, 30 Sep 2020 10:20:07 +0300 Subject: RDMA/addr: Fix race with netevent_callback()/rdma_addr_cancel() From: Jason Gunthorpe <jgg@xxxxxxxxxx> commit 2ee9bf346fbfd1dad0933b9eb3a4c2c0979b633e upstream. This three thread race can result in the work being run once the callback becomes NULL: CPU1 CPU2 CPU3 netevent_callback() process_one_req() rdma_addr_cancel() [..] spin_lock_bh() set_timeout() spin_unlock_bh() spin_lock_bh() list_del_init(&req->list); spin_unlock_bh() req->callback = NULL spin_lock_bh() if (!list_empty(&req->list)) // Skipped! // cancel_delayed_work(&req->work); spin_unlock_bh() process_one_req() // again req->callback() // BOOM cancel_delayed_work_sync() The solution is to always cancel the work once it is completed so any in between set_timeout() does not result in it running again. Cc: stable@xxxxxxxxxxxxxxx Fixes: 44e75052bc2a ("RDMA/rdma_cm: Make rdma_addr_cancel into a fence") Link: https://lore.kernel.org/r/20200930072007.1009692-1-leon@xxxxxxxxxx Reported-by: Dan Aloni <dan@xxxxxxxxxxxx> Signed-off-by: Leon Romanovsky <leonro@xxxxxxxxxx> Signed-off-by: Jason Gunthorpe <jgg@xxxxxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/infiniband/core/addr.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) --- a/drivers/infiniband/core/addr.c +++ b/drivers/infiniband/core/addr.c @@ -645,13 +645,12 @@ static void process_one_req(struct work_ req->callback = NULL; spin_lock_bh(&lock); + /* + * Although the work will normally have been canceled by the workqueue, + * it can still be requeued as long as it is on the req_list. + */ + cancel_delayed_work(&req->work); if (!list_empty(&req->list)) { - /* - * Although the work will normally have been canceled by the - * workqueue, it can still be requeued as long as it is on the - * req_list. - */ - cancel_delayed_work(&req->work); list_del_init(&req->list); kfree(req); } Patches currently in stable-queue which might be from jgg@xxxxxxxxxx are queue-5.4/rdma-addr-fix-race-with-netevent_callback-rdma_addr_cancel.patch