RDMA/rxe: Fix seg fault in rxe_comp_queue_pkt
authorBob Pearson <rpearsonhpe@gmail.com>
Fri, 29 Mar 2024 14:55:04 +0000 (09:55 -0500)
committerJason Gunthorpe <jgg@nvidia.com>
Mon, 22 Apr 2024 19:54:32 +0000 (16:54 -0300)
In rxe_comp_queue_pkt() an incoming response packet skb is enqueued to the
resp_pkts queue and then a decision is made whether to run the completer
task inline or schedule it. Finally the skb is dereferenced to bump a 'hw'
performance counter. This is wrong because if the completer task is
already running in a separate thread it may have already processed the skb
and freed it which can cause a seg fault.  This has been observed
infrequently in testing at high scale.

This patch fixes this by changing the order of enqueuing the packet until
after the counter is accessed.

Link: https://lore.kernel.org/r/20240329145513.35381-4-rpearsonhpe@gmail.com
Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
Fixes: 0b1e5b99a48b ("IB/rxe: Add port protocol stats")
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/sw/rxe/rxe_comp.c

index b78b8c0856abdec8555678d72b919688ec4ddca4..c997b7cbf2a9e82e8c251f726d051d6aed9ddf1f 100644 (file)
@@ -131,12 +131,12 @@ void rxe_comp_queue_pkt(struct rxe_qp *qp, struct sk_buff *skb)
 {
        int must_sched;
 
-       skb_queue_tail(&qp->resp_pkts, skb);
-
-       must_sched = skb_queue_len(&qp->resp_pkts) > 1;
+       must_sched = skb_queue_len(&qp->resp_pkts) > 0;
        if (must_sched != 0)
                rxe_counter_inc(SKB_TO_PKT(skb)->rxe, RXE_CNT_COMPLETER_SCHED);
 
+       skb_queue_tail(&qp->resp_pkts, skb);
+
        if (must_sched)
                rxe_sched_task(&qp->comp.task);
        else