From patchwork Wed Nov 29 20:25:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13473421 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="FWKtnNDq" Received: from mail-oo1-xc31.google.com (mail-oo1-xc31.google.com [IPv6:2607:f8b0:4864:20::c31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 566AD10EF for ; Wed, 29 Nov 2023 12:26:26 -0800 (PST) Received: by mail-oo1-xc31.google.com with SMTP id 006d021491bc7-58dc380a6cdso159919eaf.0 for ; Wed, 29 Nov 2023 12:26:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701289585; x=1701894385; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QktSggJLQcetld8uakFuhfIq2ygrmNPQ2pKu14TqlYs=; b=FWKtnNDqDkJtXGBGP1OE3MKrRmOly/PFfxTknSCEEYMYGF1aeSiGA6+IFSkdZKHaf1 X4UQCIAJWXUfRUDczZYodVRmPI1itV1Ivet5TEdNE559MXynPiqTG+4KZnEZbiO0sKKF 10TteaJZqToAW+vf88h7WVbyKSlALIGxLGRLwxGxpJdhFa+zBiUokvouNo/sl24zu7kU UAk8eaRb+PsEQtnpKOrfGQF9RmkONFsiOcBiQV4t/G992NZvTbpubGTQQ5ikhzaH8VBV JbjePAwuuMMFPePJph1NVxHRYP08NTf8CKkMpZmsXHFNzQo8TURKiY7Pp/1rxsB/ikKR iMUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701289585; x=1701894385; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QktSggJLQcetld8uakFuhfIq2ygrmNPQ2pKu14TqlYs=; b=djKZtI5Jy+6OhxRDigbSw9TGU6H3lodMJJGKPkd0jz636+puHgOlSOEplwIypCBSYD YqZ1RncDos3qwUlGPRuRUAPkWpVSdbmQXoOShbI5LkakHjuah0fYV7yAro6Kx8r0XP2A Imoxe1FCNIJ/I528dCgVp47VFyBiHI325X5zNhoxapcCqo3nkFWHh/hoH9tn0UUaEgAc AhXSRY+3eRjOAd4SMcZmUbHCGI/qDHZs2HdJNNdy8G3EtHj26JBQVqn+LaZt9XYVbLm2 sKHoiPIqkuQlLLsxl+iBV9OK4VDa+rn67LRxD8mG0TMvwTY53CkxiXQk2ATE77z+VVVQ Bw3g== X-Gm-Message-State: AOJu0YwXuIXsgQxHNCTmFIPcmz6f+0StGQA//Exa1SQRpusbpXzf+Tch lwZgraIO8KRwseJiAX+gey4= X-Google-Smtp-Source: AGHT+IGnH/PhyKjsio00PDnuQYfDtNMiEKjb3ngT9AkMsNR7Ht3ioq6eby+YbUKftN8sSZMBiqriJQ== X-Received: by 2002:a05:6820:16a8:b0:58d:be21:9e94 with SMTP id bc40-20020a05682016a800b0058dbe219e94mr4998347oob.6.1701289585636; Wed, 29 Nov 2023 12:26:25 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-6755-34f8-2ed3-56ec.res6.spectrum.com. [2603:8081:1405:679b:6755:34f8:2ed3:56ec]) by smtp.gmail.com with ESMTPSA id 126-20020a4a0684000000b0058ab906ae38sm2473867ooj.2.2023.11.29.12.26.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 12:26:24 -0800 (PST) From: Bob Pearson To: jgg@nvidia.com, yanjun.zhu@linux.dev, linux-rdma@vger.kernel.org Cc: Bob Pearson Subject: [PATCH for-next v3 1/7] RDMA/rxe: Cleanup rxe_ah/av_chk_attr Date: Wed, 29 Nov 2023 14:25:53 -0600 Message-Id: <20231129202558.31682-2-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231129202558.31682-1-rpearsonhpe@gmail.com> References: <20231129202558.31682-1-rpearsonhpe@gmail.com> Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Replace rxe_ah_chk_attr() and rxe_av_chk_attr() by a single routine rxe_chk_ah_attr(). Signed-off-by: Bob Pearson --- drivers/infiniband/sw/rxe/rxe_av.c | 43 ++++----------------------- drivers/infiniband/sw/rxe/rxe_loc.h | 3 +- drivers/infiniband/sw/rxe/rxe_qp.c | 4 +-- drivers/infiniband/sw/rxe/rxe_verbs.c | 5 ++-- 4 files changed, 12 insertions(+), 43 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_av.c b/drivers/infiniband/sw/rxe/rxe_av.c index 889d7adbd455..4ac17b8def28 100644 --- a/drivers/infiniband/sw/rxe/rxe_av.c +++ b/drivers/infiniband/sw/rxe/rxe_av.c @@ -14,45 +14,24 @@ void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av) memcpy(av->dmac, attr->roce.dmac, ETH_ALEN); } -static int chk_attr(void *obj, struct rdma_ah_attr *attr, bool obj_is_ah) +int rxe_chk_ah_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr) { const struct ib_global_route *grh = rdma_ah_read_grh(attr); - struct rxe_port *port; - struct rxe_dev *rxe; - struct rxe_qp *qp; - struct rxe_ah *ah; + struct rxe_port *port = &rxe->port; int type; - if (obj_is_ah) { - ah = obj; - rxe = to_rdev(ah->ibah.device); - } else { - qp = obj; - rxe = to_rdev(qp->ibqp.device); - } - - port = &rxe->port; - if (rdma_ah_get_ah_flags(attr) & IB_AH_GRH) { if (grh->sgid_index > port->attr.gid_tbl_len) { - if (obj_is_ah) - rxe_dbg_ah(ah, "invalid sgid index = %d\n", - grh->sgid_index); - else - rxe_dbg_qp(qp, "invalid sgid index = %d\n", - grh->sgid_index); + rxe_dbg_dev(rxe, "invalid sgid index = %d\n", + grh->sgid_index); return -EINVAL; } type = rdma_gid_attr_network_type(grh->sgid_attr); if (type < RDMA_NETWORK_IPV4 || type > RDMA_NETWORK_IPV6) { - if (obj_is_ah) - rxe_dbg_ah(ah, "invalid network type for rdma_rxe = %d\n", - type); - else - rxe_dbg_qp(qp, "invalid network type for rdma_rxe = %d\n", - type); + rxe_dbg_dev(rxe, "invalid network type for rdma_rxe = %d\n", + type); return -EINVAL; } } @@ -60,16 +39,6 @@ static int chk_attr(void *obj, struct rdma_ah_attr *attr, bool obj_is_ah) return 0; } -int rxe_av_chk_attr(struct rxe_qp *qp, struct rdma_ah_attr *attr) -{ - return chk_attr(qp, attr, false); -} - -int rxe_ah_chk_attr(struct rxe_ah *ah, struct rdma_ah_attr *attr) -{ - return chk_attr(ah, attr, true); -} - void rxe_av_from_attr(u8 port_num, struct rxe_av *av, struct rdma_ah_attr *attr) { diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 4d2a8ef52c85..3d2504a0ae56 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -9,8 +9,7 @@ /* rxe_av.c */ void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av); -int rxe_av_chk_attr(struct rxe_qp *qp, struct rdma_ah_attr *attr); -int rxe_ah_chk_attr(struct rxe_ah *ah, struct rdma_ah_attr *attr); +int rxe_chk_ah_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr); void rxe_av_from_attr(u8 port_num, struct rxe_av *av, struct rdma_ah_attr *attr); void rxe_av_to_attr(struct rxe_av *av, struct rdma_ah_attr *attr); diff --git a/drivers/infiniband/sw/rxe/rxe_qp.c b/drivers/infiniband/sw/rxe/rxe_qp.c index 28e379c108bc..c28005db032d 100644 --- a/drivers/infiniband/sw/rxe/rxe_qp.c +++ b/drivers/infiniband/sw/rxe/rxe_qp.c @@ -456,11 +456,11 @@ int rxe_qp_chk_attr(struct rxe_dev *rxe, struct rxe_qp *qp, goto err1; } - if (mask & IB_QP_AV && rxe_av_chk_attr(qp, &attr->ah_attr)) + if (mask & IB_QP_AV && rxe_chk_ah_attr(rxe, &attr->ah_attr)) goto err1; if (mask & IB_QP_ALT_PATH) { - if (rxe_av_chk_attr(qp, &attr->alt_ah_attr)) + if (rxe_chk_ah_attr(rxe, &attr->alt_ah_attr)) goto err1; if (!rdma_is_port_valid(&rxe->ib_dev, attr->alt_port_num)) { rxe_dbg_qp(qp, "invalid alt port %d\n", attr->alt_port_num); diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.c b/drivers/infiniband/sw/rxe/rxe_verbs.c index 48f86839d36a..6706d540f1f6 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.c +++ b/drivers/infiniband/sw/rxe/rxe_verbs.c @@ -286,7 +286,7 @@ static int rxe_create_ah(struct ib_ah *ibah, /* create index > 0 */ ah->ah_num = ah->elem.index; - err = rxe_ah_chk_attr(ah, init_attr->ah_attr); + err = rxe_chk_ah_attr(rxe, init_attr->ah_attr); if (err) { rxe_dbg_ah(ah, "bad attr"); goto err_cleanup; @@ -322,10 +322,11 @@ static int rxe_create_ah(struct ib_ah *ibah, static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) { + struct rxe_dev *rxe = to_rdev(ibah->device); struct rxe_ah *ah = to_rah(ibah); int err; - err = rxe_ah_chk_attr(ah, attr); + err = rxe_chk_ah_attr(rxe, attr); if (err) { rxe_dbg_ah(ah, "bad attr"); goto err_out; From patchwork Wed Nov 29 20:25:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13473422 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jqVfGl1g" Received: from mail-oo1-xc2c.google.com (mail-oo1-xc2c.google.com [IPv6:2607:f8b0:4864:20::c2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8004410CB for ; Wed, 29 Nov 2023 12:26:27 -0800 (PST) Received: by mail-oo1-xc2c.google.com with SMTP id 006d021491bc7-58d521f12ebso135795eaf.2 for ; Wed, 29 Nov 2023 12:26:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701289587; x=1701894387; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XAo9Voy4RzHWA16EdVudg5saPOZLVlTIEuxiR5JPPMk=; b=jqVfGl1gBU8Qf31hppbyeJkdPj8ujPTBVDaD2CFl2bXF112FggWxFAl54dXOaIX944 dkSbKCoW/kHkIitbhhdrWaEkQBvplNbYt1LTrDUTOrWHKr9R4t5gaN87/tmUMbPkXm/o yKxD/zjcZC1E7A+FAiLZtpnQRg5zxlnmlfRGywAWI/aO5fbye9/oRJDpJVhgjVEG0uYs vdRabAlRUnWFMW1pTyBDCcnAJw9f66pa3WI+BxaSjFaavc20UqCOjHuFtOz/AouhkJcu HkCw3zxzjXpWaKkb4nkXJf3/69InFrmxPhQfcXUvhCvnd/vo2a2UtjyW3+l246O/TfyE O5oQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701289587; x=1701894387; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XAo9Voy4RzHWA16EdVudg5saPOZLVlTIEuxiR5JPPMk=; b=Q69rMBQzfXxj05PvCqoW9z6JC4plp936Nkdi91xOqBPNRjMAIEYI9+5TvC8VFGzQ8p QHsT89nIFJ5yMTLRdtMXVpMB6gPEuPWif6tBjTqyiFtbc6eyhm6OX7g5aNGmrN2CgkUt hvJhA8uN6kJPkcmW8IZXrnswXK0X33oCvf7rvH+w62zce4rHSseLliJmcrjoqSfasfQt dHfdkbg+jjGIvup8fck/JafuZ0yquHlNT6NrJrDX97QZHoS0NU1bHJlbxYt2HdkyANZj 4IGsxOIHzMU4fPktrk/B6iletzbdEWYTbqJ1sBOWJ7MxaXEGFZhGcxUTVbFQHkgTlEXH 1BIQ== X-Gm-Message-State: AOJu0YxMJPapVdKYFB5vLIh6pIxqLtZzc5Gb89FIradVVqjEoiM6ayRT TJv1Vze9vAtLFnxXPTugZiI= X-Google-Smtp-Source: AGHT+IHqvYy8ziwtVI103lHQngpSHAmftbyUE1/KTJu79CXJnCk5uubNzJAKW+ZpSWk1MGuSB4+jIw== X-Received: by 2002:a05:6820:2204:b0:581:ea96:f800 with SMTP id cj4-20020a056820220400b00581ea96f800mr20877140oob.6.1701289586661; Wed, 29 Nov 2023 12:26:26 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-6755-34f8-2ed3-56ec.res6.spectrum.com. [2603:8081:1405:679b:6755:34f8:2ed3:56ec]) by smtp.gmail.com with ESMTPSA id 126-20020a4a0684000000b0058ab906ae38sm2473867ooj.2.2023.11.29.12.26.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 12:26:25 -0800 (PST) From: Bob Pearson To: jgg@nvidia.com, yanjun.zhu@linux.dev, linux-rdma@vger.kernel.org Cc: Bob Pearson Subject: [PATCH for-next v3 2/7] RDMA/rxe: Fix sending of mcast packets Date: Wed, 29 Nov 2023 14:25:54 -0600 Message-Id: <20231129202558.31682-3-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231129202558.31682-1-rpearsonhpe@gmail.com> References: <20231129202558.31682-1-rpearsonhpe@gmail.com> Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently the rdma_rxe driver does not send mcast packets correctly. It uses the wrong qp number for the packets. Add a mask bit to indicate that a multicast packet has been locally sent and use to set the correct qpn for multicast packets and identify mcast packets when sending. Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Bob Pearson --- drivers/infiniband/sw/rxe/rxe_av.c | 7 +++++++ drivers/infiniband/sw/rxe/rxe_loc.h | 1 + drivers/infiniband/sw/rxe/rxe_net.c | 4 +++- drivers/infiniband/sw/rxe/rxe_opcode.h | 2 +- drivers/infiniband/sw/rxe/rxe_recv.c | 4 ++++ drivers/infiniband/sw/rxe/rxe_req.c | 11 +++++++++-- 6 files changed, 25 insertions(+), 4 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_av.c b/drivers/infiniband/sw/rxe/rxe_av.c index 4ac17b8def28..022173eb5d75 100644 --- a/drivers/infiniband/sw/rxe/rxe_av.c +++ b/drivers/infiniband/sw/rxe/rxe_av.c @@ -7,6 +7,13 @@ #include "rxe.h" #include "rxe_loc.h" +bool rxe_is_mcast_av(struct rxe_av *av) +{ + struct in6_addr *daddr = (struct in6_addr *)av->grh.dgid.raw; + + return rdma_is_multicast_addr(daddr); +} + void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av) { rxe_av_from_attr(rdma_ah_get_port_num(attr), av, attr); diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 3d2504a0ae56..62b2b25903fc 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -8,6 +8,7 @@ #define RXE_LOC_H /* rxe_av.c */ +bool rxe_is_mcast_av(struct rxe_av *av); void rxe_init_av(struct rdma_ah_attr *attr, struct rxe_av *av); int rxe_chk_ah_attr(struct rxe_dev *rxe, struct rdma_ah_attr *attr); void rxe_av_from_attr(u8 port_num, struct rxe_av *av, diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index cd59666158b1..58c3f3759bf0 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -431,7 +431,9 @@ int rxe_xmit_packet(struct rxe_qp *qp, struct rxe_pkt_info *pkt, rxe_icrc_generate(skb, pkt); - if (pkt->mask & RXE_LOOPBACK_MASK) + if (pkt->mask & RXE_MCAST_MASK) + err = rxe_send(skb, pkt); + else if (pkt->mask & RXE_LOOPBACK_MASK) err = rxe_loopback(skb, pkt); else err = rxe_send(skb, pkt); diff --git a/drivers/infiniband/sw/rxe/rxe_opcode.h b/drivers/infiniband/sw/rxe/rxe_opcode.h index 5686b691d6b8..c4cf672ea26d 100644 --- a/drivers/infiniband/sw/rxe/rxe_opcode.h +++ b/drivers/infiniband/sw/rxe/rxe_opcode.h @@ -85,7 +85,7 @@ enum rxe_hdr_mask { RXE_END_MASK = BIT(NUM_HDR_TYPES + 11), RXE_LOOPBACK_MASK = BIT(NUM_HDR_TYPES + 12), - + RXE_MCAST_MASK = BIT(NUM_HDR_TYPES + 13), RXE_ATOMIC_WRITE_MASK = BIT(NUM_HDR_TYPES + 14), RXE_READ_OR_ATOMIC_MASK = (RXE_READ_MASK | RXE_ATOMIC_MASK), diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c index 5861e4244049..7153de0799fc 100644 --- a/drivers/infiniband/sw/rxe/rxe_recv.c +++ b/drivers/infiniband/sw/rxe/rxe_recv.c @@ -217,6 +217,10 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) list_for_each_entry(mca, &mcg->qp_list, qp_list) { qp = mca->qp; + /* don't reply packet to sender if locally sent */ + if (pkt->mask & RXE_MCAST_MASK && qp_num(qp) == deth_sqp(pkt)) + continue; + /* validate qp for incoming packet */ err = check_type_state(rxe, pkt, qp); if (err) diff --git a/drivers/infiniband/sw/rxe/rxe_req.c b/drivers/infiniband/sw/rxe/rxe_req.c index d8c41fd626a9..599bec88cb54 100644 --- a/drivers/infiniband/sw/rxe/rxe_req.c +++ b/drivers/infiniband/sw/rxe/rxe_req.c @@ -442,8 +442,12 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp, (pkt->mask & (RXE_WRITE_MASK | RXE_IMMDT_MASK)) == (RXE_WRITE_MASK | RXE_IMMDT_MASK)); - qp_num = (pkt->mask & RXE_DETH_MASK) ? ibwr->wr.ud.remote_qpn : - qp->attr.dest_qp_num; + if (pkt->mask & RXE_MCAST_MASK) + qp_num = IB_MULTICAST_QPN; + else if (pkt->mask & RXE_DETH_MASK) + qp_num = ibwr->wr.ud.remote_qpn; + else + qp_num = qp->attr.dest_qp_num; ack_req = ((pkt->mask & RXE_END_MASK) || (qp->req.noack_pkts++ > RXE_MAX_PKT_PER_ACK)); @@ -809,6 +813,9 @@ int rxe_requester(struct rxe_qp *qp) goto err; } + if (rxe_is_mcast_av(av)) + pkt.mask |= RXE_MCAST_MASK; + skb = init_req_packet(qp, av, wqe, opcode, payload, &pkt); if (unlikely(!skb)) { rxe_dbg_qp(qp, "Failed allocating skb\n"); From patchwork Wed Nov 29 20:25:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13473424 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="W3hlblOT" Received: from mail-oo1-xc2d.google.com (mail-oo1-xc2d.google.com [IPv6:2607:f8b0:4864:20::c2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 99B2D10E0 for ; Wed, 29 Nov 2023 12:26:28 -0800 (PST) Received: by mail-oo1-xc2d.google.com with SMTP id 006d021491bc7-58d4968c362so143533eaf.0 for ; Wed, 29 Nov 2023 12:26:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701289588; x=1701894388; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ddedcRRBLiVSLexUYYT8YVATiw9+52DOaOKUt89pFfs=; b=W3hlblOT/l+jWNMNOvuQxIzysSw3qD0L/hs1QV5F8DtM6s9P3JZJRvSmBBqWvQMzpS yrBleIAKO3ueT4XBkDU3t/OAPORSSz3abX8L6nHT2gx0iHmKYadzCUEHHwMjlzxdXfvI eLmN80q8Y26e555uluMof04SES/oUFGGIVq0WnydtqMiY2WpVscIAWJ3xic/VSsr8obm PFjMrE5qOmHDGBJQvCfqh15/P5fPPnE6pSDd7pQ1egu7K03Ki4LVWJrCNGCw1fwu6IWy F3dmG6XVJtaCRK5vcZvPcLHH4syvoL/6R+7SqUrGCYq4DjJflAKnyv0tOaqxS8SsJphx aANQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701289588; x=1701894388; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ddedcRRBLiVSLexUYYT8YVATiw9+52DOaOKUt89pFfs=; b=YNuGmGO/CELaBxpcZossCNLm82AHwpJC4gpNvyFCPcbTk8WBXpVTw84PEJvXmcLf2G 5zgpsPYYm5hlnbjHQosqEtzb29TSEDbu5fhK9JX57Yhf2b4gHdrpNrZH/6IHi3kGy2su ksTQrsAirLrXGyl3waCEEV8Qz/TpXyW7a4ozp4W1lzDHHp4dCvmVtGin7ZbWdXg/Cnog rqJF8XNgas5wZz6ekTh36O3wYgaTa7M0t7ElY0BtTlKbKpu1FHlUg/WHDNZ/7CY9MDAL jNcCkUzNHSiaLSexpN/wqdXIO9wQ3t/pcMu/SL3Yece4GCkrWcbtKpugsvlKiuZZlraZ bN6Q== X-Gm-Message-State: AOJu0Yzr3W7i4/1s+g44txqQlruVWhL+EZMXn6QwTkRtjajsX/9KeZ2P Str6Z9QFBq9JdF3J9Rjg6Z8= X-Google-Smtp-Source: AGHT+IHyGBy+8BZxOhgZn9F7G546DWaz+rzN4c50R1H8AwVJDRVj19mQOryviTrvsiC9ckTJ1n+LQw== X-Received: by 2002:a05:6820:294:b0:58d:c250:cb1d with SMTP id q20-20020a056820029400b0058dc250cb1dmr4053416ood.2.1701289587870; Wed, 29 Nov 2023 12:26:27 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-6755-34f8-2ed3-56ec.res6.spectrum.com. [2603:8081:1405:679b:6755:34f8:2ed3:56ec]) by smtp.gmail.com with ESMTPSA id 126-20020a4a0684000000b0058ab906ae38sm2473867ooj.2.2023.11.29.12.26.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 12:26:27 -0800 (PST) From: Bob Pearson To: jgg@nvidia.com, yanjun.zhu@linux.dev, linux-rdma@vger.kernel.org Cc: Bob Pearson Subject: [PATCH for-next v3 3/7] RDMA/rxe: Register IP mcast address Date: Wed, 29 Nov 2023 14:25:55 -0600 Message-Id: <20231129202558.31682-4-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231129202558.31682-1-rpearsonhpe@gmail.com> References: <20231129202558.31682-1-rpearsonhpe@gmail.com> Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently the rdma_rxe driver does not receive mcast packets at all. Add code to rxe_mcast_add() and rxe_mcast_del() to register/deregister the IP mcast address. This is required for mcast traffic to reach the rxe driver when coming from an external source. Fixes: 8700e3e7c485 ("Soft RoCE driver") Signed-off-by: Bob Pearson --- drivers/infiniband/sw/rxe/rxe_mcast.c | 112 +++++++++++++++++++++----- drivers/infiniband/sw/rxe/rxe_net.c | 2 +- drivers/infiniband/sw/rxe/rxe_net.h | 1 + drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + 4 files changed, 95 insertions(+), 21 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index 86cc2e18a7fd..a6575381878d 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -19,38 +19,109 @@ * mcast packets in the rxe receive path. */ +#include + #include "rxe.h" -/** - * rxe_mcast_add - add multicast address to rxe device - * @rxe: rxe device object - * @mgid: multicast address as a gid - * - * Returns 0 on success else an error - */ -static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid) +static int rxe_mcast_add6(struct rxe_dev *rxe, union ib_gid *mgid) { + struct in6_addr *addr6 = (struct in6_addr *)mgid; unsigned char ll_addr[ETH_ALEN]; + int err; + + rtnl_lock(); + err = ipv6_sock_mc_join(recv_sockets.sk6->sk, rxe->ndev->ifindex, + addr6); + rtnl_unlock(); + if (err && err != -EADDRINUSE) + goto err_out; ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr); + err = dev_mc_add(rxe->ndev, ll_addr); + if (err) + goto err_drop; + + return 0; - return dev_mc_add(rxe->ndev, ll_addr); +err_drop: + rtnl_lock(); + ipv6_sock_mc_drop(recv_sockets.sk6->sk, rxe->ndev->ifindex, addr6); + rtnl_unlock(); +err_out: + return err; } -/** - * rxe_mcast_del - delete multicast address from rxe device - * @rxe: rxe device object - * @mgid: multicast address as a gid - * - * Returns 0 on success else an error - */ -static int rxe_mcast_del(struct rxe_dev *rxe, union ib_gid *mgid) +static int rxe_mcast_add(struct rxe_mcg *mcg) { + struct rxe_dev *rxe = mcg->rxe; + union ib_gid *mgid = &mcg->mgid; unsigned char ll_addr[ETH_ALEN]; + struct ip_mreqn imr = {}; + int err; + + if (mcg->is_ipv6) + return rxe_mcast_add6(rxe, mgid); + + imr.imr_multiaddr = *(struct in_addr *)(mgid->raw + 12); + imr.imr_ifindex = rxe->ndev->ifindex; + rtnl_lock(); + err = ip_mc_join_group(recv_sockets.sk4->sk, &imr); + rtnl_unlock(); + if (err && err != -EADDRINUSE) + goto err_out; + + ip_eth_mc_map(imr.imr_multiaddr.s_addr, ll_addr); + err = dev_mc_add(rxe->ndev, ll_addr); + if (err) + goto err_leave; + + return 0; + +err_leave: + rtnl_lock(); + ip_mc_leave_group(recv_sockets.sk4->sk, &imr); + rtnl_unlock(); +err_out: + return err; +} + +static int rxe_mcast_del6(struct rxe_dev *rxe, union ib_gid *mgid) +{ + unsigned char ll_addr[ETH_ALEN]; + int err, err2; ipv6_eth_mc_map((struct in6_addr *)mgid->raw, ll_addr); + err = dev_mc_del(rxe->ndev, ll_addr); + + rtnl_lock(); + err2 = ipv6_sock_mc_drop(recv_sockets.sk6->sk, + rxe->ndev->ifindex, (struct in6_addr *)mgid); + rtnl_unlock(); + + return err ?: err2; +} + +static int rxe_mcast_del(struct rxe_mcg *mcg) +{ + struct rxe_dev *rxe = mcg->rxe; + union ib_gid *mgid = &mcg->mgid; + unsigned char ll_addr[ETH_ALEN]; + struct ip_mreqn imr = {}; + int err, err2; + + if (mcg->is_ipv6) + return rxe_mcast_del6(rxe, mgid); + + imr.imr_multiaddr = *(struct in_addr *)(mgid->raw + 12); + imr.imr_ifindex = rxe->ndev->ifindex; + ip_eth_mc_map(imr.imr_multiaddr.s_addr, ll_addr); + err = dev_mc_del(rxe->ndev, ll_addr); + + rtnl_lock(); + err2 = ip_mc_leave_group(recv_sockets.sk4->sk, &imr); + rtnl_unlock(); - return dev_mc_del(rxe->ndev, ll_addr); + return err ?: err2; } /** @@ -164,6 +235,7 @@ static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid, { kref_init(&mcg->ref_cnt); memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid)); + mcg->is_ipv6 = !ipv6_addr_v4mapped((struct in6_addr *)mgid); INIT_LIST_HEAD(&mcg->qp_list); mcg->rxe = rxe; @@ -225,7 +297,7 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) spin_unlock_bh(&rxe->mcg_lock); /* add mcast address outside of lock */ - err = rxe_mcast_add(rxe, mgid); + err = rxe_mcast_add(mcg); if (!err) return mcg; @@ -273,7 +345,7 @@ static void __rxe_destroy_mcg(struct rxe_mcg *mcg) static void rxe_destroy_mcg(struct rxe_mcg *mcg) { /* delete mcast address outside of lock */ - rxe_mcast_del(mcg->rxe, &mcg->mgid); + rxe_mcast_del(mcg); spin_lock_bh(&mcg->rxe->mcg_lock); __rxe_destroy_mcg(mcg); diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c index 58c3f3759bf0..b481f8da2002 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.c +++ b/drivers/infiniband/sw/rxe/rxe_net.c @@ -18,7 +18,7 @@ #include "rxe_net.h" #include "rxe_loc.h" -static struct rxe_recv_sockets recv_sockets; +struct rxe_recv_sockets recv_sockets; static struct dst_entry *rxe_find_route4(struct rxe_qp *qp, struct net_device *ndev, diff --git a/drivers/infiniband/sw/rxe/rxe_net.h b/drivers/infiniband/sw/rxe/rxe_net.h index 45d80d00f86b..89cee7d5340f 100644 --- a/drivers/infiniband/sw/rxe/rxe_net.h +++ b/drivers/infiniband/sw/rxe/rxe_net.h @@ -15,6 +15,7 @@ struct rxe_recv_sockets { struct socket *sk4; struct socket *sk6; }; +extern struct rxe_recv_sockets recv_sockets; int rxe_net_add(const char *ibdev_name, struct net_device *ndev); diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index ccb9d19ffe8a..7be9e6232dd9 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -352,6 +352,7 @@ struct rxe_mcg { atomic_t qp_num; u32 qkey; u16 pkey; + bool is_ipv6; }; struct rxe_mca { From patchwork Wed Nov 29 20:25:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13473423 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="SE7gvphe" Received: from mail-oo1-xc34.google.com (mail-oo1-xc34.google.com [IPv6:2607:f8b0:4864:20::c34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A845D71 for ; Wed, 29 Nov 2023 12:26:29 -0800 (PST) Received: by mail-oo1-xc34.google.com with SMTP id 006d021491bc7-58ceab7daddso126103eaf.3 for ; Wed, 29 Nov 2023 12:26:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701289589; x=1701894389; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=nB46h1qQvGrP3T4J5+qBSgGcpfSh92PG6l8mrznpKt4=; b=SE7gvpheZlp8k2eGRIPAGNc+iEtnJ2ZdhwKcq8KPOe8mzeddAnbMOx7IfWYAtfIJW3 KD1e6uHm7cvOzSjiFreiFbH4ZajWIhSlxtiJ4DuboT4RTVyhYgYkVsJVEWYXccBw23c4 R3mzpeUIJB9v/BOoHIlbWEOKqJqHw1PM3YCTtnJfgEtDTTLpzLz7jZyd4CFlDPPr279r Pa6UILnBmzLMznSrMwcrqrQp99A5BTJPcidlAqP/0ICDQDs2vi4yBejOsgIIxk8eTs3a xHWgYHnv4NT4a6LUDIASxL/8i0wXd8RnXokcgY2FsDooo5wD6UBY5RXeSn+tPFefvT9m LHHw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701289589; x=1701894389; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=nB46h1qQvGrP3T4J5+qBSgGcpfSh92PG6l8mrznpKt4=; b=u/nD02KznSDZj1aYBZYCtcXAxjcClplWWFHAVh+L0G5qqx089Oy5GE7JsuudWIMZSS Iy4wd8LY85nGiWDan3lSLyjSW7gsgwvjXwkNKwq0A7RzsQZ2img9Bj1w+qaKLXdEeeQf 0qD8bKRArgoyvvFxnh8te5MwGWR/CFfVM7z4ZyKKBuq4lgzFqbf7agq56HPiCWhtTeK1 iKePap+eOCaXda/g5V7rbnhvxDlZ22uanIg1zBCS4xaFL8poV4SqU/vc7jIXC9eHrls1 mHHsT+K9Ec9fjsoKNIcOgpGIuXDlf05i3Ttan21rdKUL/r8bdMgTnnTaTVa7nlZA9H6t eXWQ== X-Gm-Message-State: AOJu0YxWGlzOwZl/7MHWRTkW8JyEBvXYGVDuhvUwn/8Fo5SRUtWmzROg uU7p7/fK5MxM0SUHPnTv2ayyuvLfYCU= X-Google-Smtp-Source: AGHT+IGMVZpNCi3JoNc8jJAXVtIS/2o/ORB8K7VzuZ1iaK5CHnOeRDDMOgZHipGCXApxERtd4+V9iQ== X-Received: by 2002:a05:6820:62a:b0:58d:8b93:eca with SMTP id e42-20020a056820062a00b0058d8b930ecamr10513603oow.6.1701289588916; Wed, 29 Nov 2023 12:26:28 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-6755-34f8-2ed3-56ec.res6.spectrum.com. [2603:8081:1405:679b:6755:34f8:2ed3:56ec]) by smtp.gmail.com with ESMTPSA id 126-20020a4a0684000000b0058ab906ae38sm2473867ooj.2.2023.11.29.12.26.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 12:26:28 -0800 (PST) From: Bob Pearson To: jgg@nvidia.com, yanjun.zhu@linux.dev, linux-rdma@vger.kernel.org Cc: Bob Pearson Subject: [PATCH for-next v3 4/7] RDMA/rxe: Let rxe_lookup_mcg use rcu_read_lock Date: Wed, 29 Nov 2023 14:25:56 -0600 Message-Id: <20231129202558.31682-5-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231129202558.31682-1-rpearsonhpe@gmail.com> References: <20231129202558.31682-1-rpearsonhpe@gmail.com> Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Change locking of read side operations of the mcast group red-black tree to use rcu read locking. This will allow changing the mcast lock in the next patch to be a mutex without breaking rxe_recv.c which runs in an atomic state. It is also a better implementation than the current use of a spin-lock per rdma device since receiving mcast packets will be much more common than registering/deregistering mcast groups. Signed-off-by: Bob Pearson --- drivers/infiniband/sw/rxe/rxe_mcast.c | 59 +++++++++------------------ drivers/infiniband/sw/rxe/rxe_verbs.h | 1 + 2 files changed, 21 insertions(+), 39 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index a6575381878d..5e10a3b8aa58 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -144,13 +144,18 @@ static void __rxe_insert_mcg(struct rxe_mcg *mcg) tmp = rb_entry(node, struct rxe_mcg, node); cmp = memcmp(&tmp->mgid, &mcg->mgid, sizeof(mcg->mgid)); - if (cmp > 0) + if (cmp > 0) { link = &(*link)->rb_left; - else + } else if (cmp < 0) { link = &(*link)->rb_right; + } else { + /* we must delete the old mcg before adding one */ + WARN_ON_ONCE(1); + return; + } } - rb_link_node(&mcg->node, node, link); + rb_link_node_rcu(&mcg->node, node, link); rb_insert_color(&mcg->node, tree); } @@ -165,15 +170,11 @@ static void __rxe_remove_mcg(struct rxe_mcg *mcg) rb_erase(&mcg->node, &mcg->rxe->mcg_tree); } -/** - * __rxe_lookup_mcg - lookup mcg in rxe->mcg_tree while holding lock - * @rxe: rxe device object - * @mgid: multicast IP address - * - * Context: caller must hold rxe->mcg_lock - * Returns: mcg on success and takes a ref to mcg else NULL +/* + * Lookup mgid in the multicast group red-black tree and try to + * get a ref on it. Return mcg on success else NULL. */ -static struct rxe_mcg *__rxe_lookup_mcg(struct rxe_dev *rxe, +struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid) { struct rb_root *tree = &rxe->mcg_tree; @@ -181,7 +182,8 @@ static struct rxe_mcg *__rxe_lookup_mcg(struct rxe_dev *rxe, struct rb_node *node; int cmp; - node = tree->rb_node; + rcu_read_lock(); + node = rcu_dereference_raw(tree->rb_node); while (node) { mcg = rb_entry(node, struct rxe_mcg, node); @@ -189,35 +191,14 @@ static struct rxe_mcg *__rxe_lookup_mcg(struct rxe_dev *rxe, cmp = memcmp(&mcg->mgid, mgid, sizeof(*mgid)); if (cmp > 0) - node = node->rb_left; + node = rcu_dereference_raw(node->rb_left); else if (cmp < 0) - node = node->rb_right; + node = rcu_dereference_raw(node->rb_right); else break; } - - if (node) { - kref_get(&mcg->ref_cnt); - return mcg; - } - - return NULL; -} - -/** - * rxe_lookup_mcg - lookup up mcg in red-back tree - * @rxe: rxe device object - * @mgid: multicast IP address - * - * Returns: mcg if found else NULL - */ -struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid) -{ - struct rxe_mcg *mcg; - - spin_lock_bh(&rxe->mcg_lock); - mcg = __rxe_lookup_mcg(rxe, mgid); - spin_unlock_bh(&rxe->mcg_lock); + mcg = (node && kref_get_unless_zero(&mcg->ref_cnt)) ? mcg : NULL; + rcu_read_unlock(); return mcg; } @@ -285,7 +266,7 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) spin_lock_bh(&rxe->mcg_lock); /* re-check to see if someone else just added it */ - tmp = __rxe_lookup_mcg(rxe, mgid); + tmp = rxe_lookup_mcg(rxe, mgid); if (tmp) { spin_unlock_bh(&rxe->mcg_lock); atomic_dec(&rxe->mcg_num); @@ -315,7 +296,7 @@ void rxe_cleanup_mcg(struct kref *kref) { struct rxe_mcg *mcg = container_of(kref, typeof(*mcg), ref_cnt); - kfree(mcg); + kfree_rcu(mcg, rcu); } /** diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index 7be9e6232dd9..8058e5039322 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -345,6 +345,7 @@ struct rxe_mw { struct rxe_mcg { struct rb_node node; + struct rcu_head rcu; struct kref ref_cnt; struct rxe_dev *rxe; struct list_head qp_list; From patchwork Wed Nov 29 20:25:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13473425 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="U494IGx9" Received: from mail-oo1-xc29.google.com (mail-oo1-xc29.google.com [IPv6:2607:f8b0:4864:20::c29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A96F910D0 for ; Wed, 29 Nov 2023 12:26:30 -0800 (PST) Received: by mail-oo1-xc29.google.com with SMTP id 006d021491bc7-587b1231dbeso128945eaf.3 for ; Wed, 29 Nov 2023 12:26:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701289590; x=1701894390; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=rxyeXLPqgXWiDVDWc71JY4fBWRilV18dlQ2eBGhdrCg=; b=U494IGx9CrhyLZaAP6mWlv5aBrlXfLVENvFN+XVXpzrTWUfL8poRjGb95VKS9YYN0B siYvKqlT1Mx7LFt3osyNomUS2SOB/OsVeqXKf/rPW+D+y6K1jJY64p7KQpbS8wToCjHL ja0uCPC39LSvaxSfu2qEW0UFcsHqhwN1a2O+17psnlKiFCO4r1YSpqlSjCNZdEPZBjz6 xLsLeKCmX3gVLxBT08clkGofPtuJCwMY2nC+B9n7W2Nj5MLx2RpGJ4iho7Ena31GKiJZ BPqJvTo/mDHbFxPS8Kvr5TRR6b7MruGonyT/XlBK6D52Q4HewS6wK2VFfbWAwC5P+2d7 zHuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701289590; x=1701894390; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rxyeXLPqgXWiDVDWc71JY4fBWRilV18dlQ2eBGhdrCg=; b=WaXTuLJRyusSvN7vL4z9EvAgMPOVDjzpm0uyepJ2EeblJrlqtGZvgeru2YObzpAd96 fy2re+QipSpXjonpAZVpyFUApaI50dbkVnnUWKkJYX+ODldNdQbTDCqGldSc1wF4v3Aj TWNot2wRyyJ5WXTEnEBLMdeoLPCz6XCVmx6Xp8fnq8a8OMLJH41ooFilUtfor5+7Vweu E4ZqDmvgLoqmslgyoNpXbBK+oXtw5x9Na0BaLhJirlQ56LbZzE1H8hh0X47vsfj+MiPo /4W0OHqTQffEJ3iBGcn+9tpFVqCWcloSCuVa48W1E3s8Ued8kPJJzS3+8IAX+Cs4iBpU vHRw== X-Gm-Message-State: AOJu0Yx+wE1W6aq7PNjRjw2GnjavNt8a3j0sULWVh3IFkAy3BAs1KHgr ziidjnDT5uCZxpfG9IL1BgnTmmHx9oI= X-Google-Smtp-Source: AGHT+IF7xilsgylBocpaJSLZl8L8r3ZBjU/DU/pXTVDejYezpOKOZ0ahdIGMVFKeTGhLv8Yu9O4ypQ== X-Received: by 2002:a05:6820:2202:b0:58a:212e:c6d3 with SMTP id cj2-20020a056820220200b0058a212ec6d3mr24946349oob.5.1701289589902; Wed, 29 Nov 2023 12:26:29 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-6755-34f8-2ed3-56ec.res6.spectrum.com. [2603:8081:1405:679b:6755:34f8:2ed3:56ec]) by smtp.gmail.com with ESMTPSA id 126-20020a4a0684000000b0058ab906ae38sm2473867ooj.2.2023.11.29.12.26.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 12:26:29 -0800 (PST) From: Bob Pearson To: jgg@nvidia.com, yanjun.zhu@linux.dev, linux-rdma@vger.kernel.org Cc: Bob Pearson Subject: [PATCH for-next v3 5/7] RDMA/rxe: Split multicast lock Date: Wed, 29 Nov 2023 14:25:57 -0600 Message-Id: <20231129202558.31682-6-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231129202558.31682-1-rpearsonhpe@gmail.com> References: <20231129202558.31682-1-rpearsonhpe@gmail.com> Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Split rxe->mcg_lock into two locks. One to protect mcg->qp_list and one to protect rxe->mcg_tree (red-black tree) write side operations and provide serialization between rxe_attach_mcast and rxe_detach_mcast. Make the qp_list lock a spin_lock_irqsave lock and move to the mcg struct. It protects the qp_list from simultaneous access from rxe_mcast.c and rxe_recv.c when processing incoming multi- cast packets. In theory some ethernet driver could bypass NAPI so an irq lock is better than a bh lock. Make the mcg_tree lock a mutex since the attach/detach APIs are not called in atomic context. This allows some significant cleanup since we can call kzalloc while holding the mutex so some recheck code can be eliminated. Signed-off-by: Bob Pearson --- drivers/infiniband/sw/rxe/rxe.c | 2 +- drivers/infiniband/sw/rxe/rxe_mcast.c | 254 ++++++++++---------------- drivers/infiniband/sw/rxe/rxe_recv.c | 5 +- drivers/infiniband/sw/rxe/rxe_verbs.h | 3 +- 4 files changed, 105 insertions(+), 159 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 54c723a6edda..147cb16e937d 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c @@ -142,7 +142,7 @@ static void rxe_init(struct rxe_dev *rxe) INIT_LIST_HEAD(&rxe->pending_mmaps); /* init multicast support */ - spin_lock_init(&rxe->mcg_lock); + mutex_init(&rxe->mcg_mutex); rxe->mcg_tree = RB_ROOT; mutex_init(&rxe->usdev_lock); diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index 5e10a3b8aa58..937bfb99cf9c 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -128,7 +128,7 @@ static int rxe_mcast_del(struct rxe_mcg *mcg) * __rxe_insert_mcg - insert an mcg into red-black tree (rxe->mcg_tree) * @mcg: mcg object with an embedded red-black tree node * - * Context: caller must hold a reference to mcg and rxe->mcg_lock and + * Context: caller must hold a reference to mcg and rxe->mcg_mutex and * is responsible to avoid adding the same mcg twice to the tree. */ static void __rxe_insert_mcg(struct rxe_mcg *mcg) @@ -163,7 +163,7 @@ static void __rxe_insert_mcg(struct rxe_mcg *mcg) * __rxe_remove_mcg - remove an mcg from red-black tree holding lock * @mcg: mcast group object with an embedded red-black tree node * - * Context: caller must hold a reference to mcg and rxe->mcg_lock + * Context: caller must hold a reference to mcg and rxe->mcg_mutex */ static void __rxe_remove_mcg(struct rxe_mcg *mcg) { @@ -203,34 +203,6 @@ struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, return mcg; } -/** - * __rxe_init_mcg - initialize a new mcg - * @rxe: rxe device - * @mgid: multicast address as a gid - * @mcg: new mcg object - * - * Context: caller should hold rxe->mcg lock - */ -static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid, - struct rxe_mcg *mcg) -{ - kref_init(&mcg->ref_cnt); - memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid)); - mcg->is_ipv6 = !ipv6_addr_v4mapped((struct in6_addr *)mgid); - INIT_LIST_HEAD(&mcg->qp_list); - mcg->rxe = rxe; - - /* caller holds a ref on mcg but that will be - * dropped when mcg goes out of scope. We need to take a ref - * on the pointer that will be saved in the red-black tree - * by __rxe_insert_mcg and used to lookup mcg from mgid later. - * Inserting mcg makes it visible to outside so this should - * be done last after the object is ready. - */ - kref_get(&mcg->ref_cnt); - __rxe_insert_mcg(mcg); -} - /** * rxe_get_mcg - lookup or allocate a mcg * @rxe: rxe device object @@ -240,51 +212,48 @@ static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid, */ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) { - struct rxe_mcg *mcg, *tmp; + struct rxe_mcg *mcg; int err; - if (rxe->attr.max_mcast_grp == 0) - return ERR_PTR(-EINVAL); - - /* check to see if mcg already exists */ + mutex_lock(&rxe->mcg_mutex); mcg = rxe_lookup_mcg(rxe, mgid); if (mcg) - return mcg; + goto out; /* nothing to do */ - /* check to see if we have reached limit */ if (atomic_inc_return(&rxe->mcg_num) > rxe->attr.max_mcast_grp) { err = -ENOMEM; goto err_dec; } - /* speculative alloc of new mcg */ mcg = kzalloc(sizeof(*mcg), GFP_KERNEL); if (!mcg) { err = -ENOMEM; goto err_dec; } - spin_lock_bh(&rxe->mcg_lock); - /* re-check to see if someone else just added it */ - tmp = rxe_lookup_mcg(rxe, mgid); - if (tmp) { - spin_unlock_bh(&rxe->mcg_lock); - atomic_dec(&rxe->mcg_num); - kfree(mcg); - return tmp; - } - - __rxe_init_mcg(rxe, mgid, mcg); - spin_unlock_bh(&rxe->mcg_lock); + memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid)); + mcg->is_ipv6 = !ipv6_addr_v4mapped((struct in6_addr *)mgid); + mcg->rxe = rxe; + kref_init(&mcg->ref_cnt); + INIT_LIST_HEAD(&mcg->qp_list); + spin_lock_init(&mcg->lock); + kref_get(&mcg->ref_cnt); + __rxe_insert_mcg(mcg); - /* add mcast address outside of lock */ err = rxe_mcast_add(mcg); - if (!err) - return mcg; + if (err) + goto err_free; + +out: + mutex_unlock(&rxe->mcg_mutex); + return mcg; +err_free: + __rxe_remove_mcg(mcg); kfree(mcg); err_dec: atomic_dec(&rxe->mcg_num); + mutex_unlock(&rxe->mcg_mutex); return ERR_PTR(err); } @@ -300,10 +269,10 @@ void rxe_cleanup_mcg(struct kref *kref) } /** - * __rxe_destroy_mcg - destroy mcg object holding rxe->mcg_lock + * __rxe_destroy_mcg - destroy mcg object holding rxe->mcg_mutex * @mcg: the mcg object * - * Context: caller is holding rxe->mcg_lock + * Context: caller is holding rxe->mcg_mutex * no qp's are attached to mcg */ static void __rxe_destroy_mcg(struct rxe_mcg *mcg) @@ -328,151 +297,123 @@ static void rxe_destroy_mcg(struct rxe_mcg *mcg) /* delete mcast address outside of lock */ rxe_mcast_del(mcg); - spin_lock_bh(&mcg->rxe->mcg_lock); + mutex_lock(&mcg->rxe->mcg_mutex); __rxe_destroy_mcg(mcg); - spin_unlock_bh(&mcg->rxe->mcg_lock); + mutex_unlock(&mcg->rxe->mcg_mutex); } /** - * __rxe_init_mca - initialize a new mca holding lock + * rxe_attach_mcg - attach qp to mcg if not already attached * @qp: qp object * @mcg: mcg object - * @mca: empty space for new mca - * - * Context: caller must hold references on qp and mcg, rxe->mcg_lock - * and pass memory for new mca * * Returns: 0 on success else an error */ -static int __rxe_init_mca(struct rxe_qp *qp, struct rxe_mcg *mcg, - struct rxe_mca *mca) +static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) { - struct rxe_dev *rxe = to_rdev(qp->ibqp.device); - int n; + struct rxe_dev *rxe = mcg->rxe; + struct rxe_mca *mca; + unsigned long flags; + int err; - n = atomic_inc_return(&rxe->mcg_attach); - if (n > rxe->attr.max_total_mcast_qp_attach) { - atomic_dec(&rxe->mcg_attach); - return -ENOMEM; + mutex_lock(&rxe->mcg_mutex); + spin_lock_irqsave(&mcg->lock, flags); + list_for_each_entry(mca, &mcg->qp_list, qp_list) { + if (mca->qp == qp) { + spin_unlock_irqrestore(&mcg->lock, flags); + goto out; /* nothing to do */ + } } + spin_unlock_irqrestore(&mcg->lock, flags); - n = atomic_inc_return(&mcg->qp_num); - if (n > rxe->attr.max_mcast_qp_attach) { - atomic_dec(&mcg->qp_num); - atomic_dec(&rxe->mcg_attach); - return -ENOMEM; + if (atomic_inc_return(&rxe->mcg_attach) > + rxe->attr.max_total_mcast_qp_attach) { + err = -EINVAL; + goto err_dec_attach; } - atomic_inc(&qp->mcg_num); + if (atomic_inc_return(&mcg->qp_num) > + rxe->attr.max_mcast_qp_attach) { + err = -EINVAL; + goto err_dec_qp_num; + } + + mca = kzalloc(sizeof(*mca), GFP_KERNEL); + if (!mca) { + err = -ENOMEM; + goto err_dec_qp_num; + } + atomic_inc(&qp->mcg_num); rxe_get(qp); mca->qp = qp; + spin_lock_irqsave(&mcg->lock, flags); list_add_tail(&mca->qp_list, &mcg->qp_list); - + spin_unlock_irqrestore(&mcg->lock, flags); +out: + mutex_unlock(&rxe->mcg_mutex); return 0; + +err_dec_qp_num: + atomic_dec(&mcg->qp_num); +err_dec_attach: + atomic_dec(&rxe->mcg_attach); + mutex_unlock(&rxe->mcg_mutex); + return err; } /** - * rxe_attach_mcg - attach qp to mcg if not already attached - * @qp: qp object + * rxe_detach_mcg - detach qp from mcg * @mcg: mcg object + * @qp: qp object * - * Context: caller must hold reference on qp and mcg. - * Returns: 0 on success else an error + * Returns: 0 on success else an error if qp is not attached. */ -static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) +static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) { struct rxe_dev *rxe = mcg->rxe; - struct rxe_mca *mca, *tmp; - int err; + struct rxe_mca *mca; + unsigned long flags; + int err = 0; - /* check to see if the qp is already a member of the group */ - spin_lock_bh(&rxe->mcg_lock); + mutex_lock(&rxe->mcg_mutex); + spin_lock_irqsave(&mcg->lock, flags); list_for_each_entry(mca, &mcg->qp_list, qp_list) { if (mca->qp == qp) { - spin_unlock_bh(&rxe->mcg_lock); - return 0; + spin_unlock_irqrestore(&mcg->lock, flags); + goto found; } } - spin_unlock_bh(&rxe->mcg_lock); + spin_unlock_irqrestore(&mcg->lock, flags); - /* speculative alloc new mca without using GFP_ATOMIC */ - mca = kzalloc(sizeof(*mca), GFP_KERNEL); - if (!mca) - return -ENOMEM; - - spin_lock_bh(&rxe->mcg_lock); - /* re-check to see if someone else just attached qp */ - list_for_each_entry(tmp, &mcg->qp_list, qp_list) { - if (tmp->qp == qp) { - kfree(mca); - err = 0; - goto out; - } - } - - err = __rxe_init_mca(qp, mcg, mca); - if (err) - kfree(mca); -out: - spin_unlock_bh(&rxe->mcg_lock); - return err; -} + /* we didn't find the qp on the list */ + err = -EINVAL; + goto err_out; -/** - * __rxe_cleanup_mca - cleanup mca object holding lock - * @mca: mca object - * @mcg: mcg object - * - * Context: caller must hold a reference to mcg and rxe->mcg_lock - */ -static void __rxe_cleanup_mca(struct rxe_mca *mca, struct rxe_mcg *mcg) -{ +found: + spin_lock_irqsave(&mcg->lock, flags); list_del(&mca->qp_list); + spin_unlock_irqrestore(&mcg->lock, flags); atomic_dec(&mcg->qp_num); atomic_dec(&mcg->rxe->mcg_attach); atomic_dec(&mca->qp->mcg_num); rxe_put(mca->qp); - kfree(mca); -} - -/** - * rxe_detach_mcg - detach qp from mcg - * @mcg: mcg object - * @qp: qp object - * - * Returns: 0 on success else an error if qp is not attached. - */ -static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) -{ - struct rxe_dev *rxe = mcg->rxe; - struct rxe_mca *mca, *tmp; - spin_lock_bh(&rxe->mcg_lock); - list_for_each_entry_safe(mca, tmp, &mcg->qp_list, qp_list) { - if (mca->qp == qp) { - __rxe_cleanup_mca(mca, mcg); - - /* if the number of qp's attached to the - * mcast group falls to zero go ahead and - * tear it down. This will not free the - * object since we are still holding a ref - * from the caller - */ - if (atomic_read(&mcg->qp_num) <= 0) - __rxe_destroy_mcg(mcg); - - spin_unlock_bh(&rxe->mcg_lock); - return 0; - } - } + /* if the number of qp's attached to the + * mcast group falls to zero go ahead and + * tear it down. This will not free the + * object since we are still holding a ref + * from the caller + */ + if (atomic_read(&mcg->qp_num) <= 0) + __rxe_destroy_mcg(mcg); - /* we didn't find the qp on the list */ - spin_unlock_bh(&rxe->mcg_lock); - return -EINVAL; +err_out: + mutex_unlock(&rxe->mcg_mutex); + return err; } /** @@ -490,6 +431,9 @@ int rxe_attach_mcast(struct ib_qp *ibqp, union ib_gid *mgid, u16 mlid) struct rxe_qp *qp = to_rqp(ibqp); struct rxe_mcg *mcg; + if (rxe->attr.max_mcast_grp == 0) + return -EINVAL; + /* takes a ref on mcg if successful */ mcg = rxe_get_mcg(rxe, mgid); if (IS_ERR(mcg)) diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c index 7153de0799fc..6cf0da958864 100644 --- a/drivers/infiniband/sw/rxe/rxe_recv.c +++ b/drivers/infiniband/sw/rxe/rxe_recv.c @@ -194,6 +194,7 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) struct rxe_mca *mca; struct rxe_qp *qp; union ib_gid dgid; + unsigned long flags; int err; if (skb->protocol == htons(ETH_P_IP)) @@ -207,7 +208,7 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) if (!mcg) goto drop; /* mcast group not registered */ - spin_lock_bh(&rxe->mcg_lock); + spin_lock_irqsave(&mcg->lock, flags); /* this is unreliable datagram service so we let * failures to deliver a multicast packet to a @@ -259,7 +260,7 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) } } - spin_unlock_bh(&rxe->mcg_lock); + spin_unlock_irqrestore(&mcg->lock, flags); kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h index 8058e5039322..f21963dcb2c8 100644 --- a/drivers/infiniband/sw/rxe/rxe_verbs.h +++ b/drivers/infiniband/sw/rxe/rxe_verbs.h @@ -351,6 +351,7 @@ struct rxe_mcg { struct list_head qp_list; union ib_gid mgid; atomic_t qp_num; + spinlock_t lock; /* protect qp_list */ u32 qkey; u16 pkey; bool is_ipv6; @@ -390,7 +391,7 @@ struct rxe_dev { struct rxe_pool mw_pool; /* multicast support */ - spinlock_t mcg_lock; + struct mutex mcg_mutex; struct rb_root mcg_tree; atomic_t mcg_num; atomic_t mcg_attach; From patchwork Wed Nov 29 20:25:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13473426 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dAMyWT5n" Received: from mail-oo1-xc30.google.com (mail-oo1-xc30.google.com [IPv6:2607:f8b0:4864:20::c30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A9E8E10D9 for ; Wed, 29 Nov 2023 12:26:31 -0800 (PST) Received: by mail-oo1-xc30.google.com with SMTP id 006d021491bc7-58d52e0065fso95864eaf.0 for ; Wed, 29 Nov 2023 12:26:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701289591; x=1701894391; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8Ot999bwSu+30wyuMjnVZ1J2tnwOfT2zetDIWC25BSk=; b=dAMyWT5nBAE0ziVZ1MtJk8gqSDK0QvmX9LW3ZB+JwcSWVjfwh23uvOgedSwWjpZD2i Z3dyFyi1NkstfqkPJdQ8d1JJry0QN4jgLJK0tMLEI9cijfYW0M7BfeeHFIYdS3dELb+v HwLsf+zQy/y/MPhS6305UyCU7v+TpGD+y9N84cjBiGfL02KZI3INAWXqWaS8CYOlkCRj VThZMnCiZ8mcVNf+6PDsvakJURhZLhWM8F/uBQ8IBbmTnRx7gMLVVitoEyHVbpzq44qp M9S1ChXozodlcmN/Ebj2J9I4p+EAyqxQ1n56Wz6tvcTO19HDny563Pv83YTCMnipw0SY EEpA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701289591; x=1701894391; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8Ot999bwSu+30wyuMjnVZ1J2tnwOfT2zetDIWC25BSk=; b=kGM0u46Jyi/sZiVVFylDTNhyMsvNK5ePP9CdAy3yiafQ7IjwCBEBIxycQhMwU3FgmO TgwMkn3/1XlHCVzebwCAEsH+KtRDWcS5Fb/ZyV56hqniRHlxCQROl4RtAkdr0lllE34n 1xuaXHyuJOgNrRnqed+5qdafyBLQ6+t3wfqkpJgg8uqFoznWYnhRj+E326/mVRAtaYtz 1zXndGF3ZGw7ViZ9hWqnRZNLJoEaiRBPt3DguN/B0v8K0zFUvAanlDdQGnWDWDDpZqZK pPs7fEaVWnpH+pUIuPMITbfbm7aUYyKIjF3eiPgeS7i2gOdGcnYaEu1RKtp27jvaPDlA Xseg== X-Gm-Message-State: AOJu0Yznrxu7Dg08Uu1VOHRzQhwjLjuVhvwBNDn0k+H1+iPV4zFkBry3 3XMFyQUmZpM+tVth1iQhx2g= X-Google-Smtp-Source: AGHT+IG/JdPKW3VVq5OBdHMrB+DMGqQbLWUzXqWhJPOmylnxBRreFq4X7VYch70zqrlkmCrsxFVzTw== X-Received: by 2002:a05:6820:16a5:b0:58d:8f17:6606 with SMTP id bc37-20020a05682016a500b0058d8f176606mr5751518oob.4.1701289590977; Wed, 29 Nov 2023 12:26:30 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-6755-34f8-2ed3-56ec.res6.spectrum.com. [2603:8081:1405:679b:6755:34f8:2ed3:56ec]) by smtp.gmail.com with ESMTPSA id 126-20020a4a0684000000b0058ab906ae38sm2473867ooj.2.2023.11.29.12.26.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 12:26:30 -0800 (PST) From: Bob Pearson To: jgg@nvidia.com, yanjun.zhu@linux.dev, linux-rdma@vger.kernel.org Cc: Bob Pearson Subject: [PATCH for-next v3 6/7] RDMA/rxe: Cleanup mcg lifetime Date: Wed, 29 Nov 2023 14:25:58 -0600 Message-Id: <20231129202558.31682-7-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231129202558.31682-1-rpearsonhpe@gmail.com> References: <20231129202558.31682-1-rpearsonhpe@gmail.com> Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Currently the rdma_rxe driver has two different and not really compatible ways of managing the lifetime of an mcast group, by ref counting the mcg struct and counting the number of attached qp's. They are each doing part of the job of cleaning up an mcg when the last qp is detached and are racy in the process. This patch removes using the use of the number of qp's. Fix up mcg reference counting so the ref count will drop to zero correctly and move code from rxe_destroy_mcg to rxe_cleanup_mcg since rxe_destroy is no longer needed. This set of fixes scrambles the code in rxe_mast.c and as a result a lot of cleanup has been done as well. Fixes: 6090a0c4c7c6 ("RDMA/rxe: Cleanup rxe_mcast.c") Signed-off-by: Bob Pearson --- drivers/infiniband/sw/rxe/rxe_loc.h | 2 +- drivers/infiniband/sw/rxe/rxe_mcast.c | 170 +++++++------------------- drivers/infiniband/sw/rxe/rxe_recv.c | 2 +- 3 files changed, 46 insertions(+), 128 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h index 62b2b25903fc..0509ccdaa2f2 100644 --- a/drivers/infiniband/sw/rxe/rxe_loc.h +++ b/drivers/infiniband/sw/rxe/rxe_loc.h @@ -37,7 +37,7 @@ void rxe_cq_cleanup(struct rxe_pool_elem *elem); struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid); int rxe_attach_mcast(struct ib_qp *ibqp, union ib_gid *mgid, u16 mlid); int rxe_detach_mcast(struct ib_qp *ibqp, union ib_gid *mgid, u16 mlid); -void rxe_cleanup_mcg(struct kref *kref); +int rxe_put_mcg(struct rxe_mcg *mcg); /* rxe_mmap.c */ struct rxe_mmap_info { diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index 937bfb99cf9c..57efb29702fe 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -124,13 +124,31 @@ static int rxe_mcast_del(struct rxe_mcg *mcg) return err ?: err2; } -/** - * __rxe_insert_mcg - insert an mcg into red-black tree (rxe->mcg_tree) - * @mcg: mcg object with an embedded red-black tree node - * - * Context: caller must hold a reference to mcg and rxe->mcg_mutex and - * is responsible to avoid adding the same mcg twice to the tree. - */ +static void __rxe_remove_mcg(struct rxe_mcg *mcg) +{ + rb_erase(&mcg->node, &mcg->rxe->mcg_tree); +} + +static void rxe_cleanup_mcg(struct kref *kref) +{ + struct rxe_mcg *mcg = container_of(kref, typeof(*mcg), ref_cnt); + + __rxe_remove_mcg(mcg); + rxe_mcast_del(mcg); + atomic_dec(&mcg->rxe->mcg_num); + kfree_rcu(mcg, rcu); +} + +static int rxe_get_mcg(struct rxe_mcg *mcg) +{ + return kref_get_unless_zero(&mcg->ref_cnt); +} + +int rxe_put_mcg(struct rxe_mcg *mcg) +{ + return kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); +} + static void __rxe_insert_mcg(struct rxe_mcg *mcg) { struct rb_root *tree = &mcg->rxe->mcg_tree; @@ -159,23 +177,11 @@ static void __rxe_insert_mcg(struct rxe_mcg *mcg) rb_insert_color(&mcg->node, tree); } -/** - * __rxe_remove_mcg - remove an mcg from red-black tree holding lock - * @mcg: mcast group object with an embedded red-black tree node - * - * Context: caller must hold a reference to mcg and rxe->mcg_mutex - */ -static void __rxe_remove_mcg(struct rxe_mcg *mcg) -{ - rb_erase(&mcg->node, &mcg->rxe->mcg_tree); -} - /* * Lookup mgid in the multicast group red-black tree and try to * get a ref on it. Return mcg on success else NULL. */ -struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, - union ib_gid *mgid) +struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid) { struct rb_root *tree = &rxe->mcg_tree; struct rxe_mcg *mcg; @@ -197,20 +203,14 @@ struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, else break; } - mcg = (node && kref_get_unless_zero(&mcg->ref_cnt)) ? mcg : NULL; + mcg = (node && rxe_get_mcg(mcg)) ? mcg : NULL; rcu_read_unlock(); return mcg; } -/** - * rxe_get_mcg - lookup or allocate a mcg - * @rxe: rxe device object - * @mgid: multicast IP address as a gid - * - * Returns: mcg on success else ERR_PTR(error) - */ -static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) +/* find an existing mcg or allocate a new one */ +static struct rxe_mcg *rxe_alloc_mcg(struct rxe_dev *rxe, union ib_gid *mgid) { struct rxe_mcg *mcg; int err; @@ -221,7 +221,7 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) goto out; /* nothing to do */ if (atomic_inc_return(&rxe->mcg_num) > rxe->attr.max_mcast_grp) { - err = -ENOMEM; + err = -EINVAL; goto err_dec; } @@ -237,19 +237,17 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) kref_init(&mcg->ref_cnt); INIT_LIST_HEAD(&mcg->qp_list); spin_lock_init(&mcg->lock); - kref_get(&mcg->ref_cnt); - __rxe_insert_mcg(mcg); err = rxe_mcast_add(mcg); if (err) goto err_free; + __rxe_insert_mcg(mcg); out: mutex_unlock(&rxe->mcg_mutex); return mcg; err_free: - __rxe_remove_mcg(mcg); kfree(mcg); err_dec: atomic_dec(&rxe->mcg_num); @@ -257,64 +255,12 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid) return ERR_PTR(err); } -/** - * rxe_cleanup_mcg - cleanup mcg for kref_put - * @kref: struct kref embnedded in mcg - */ -void rxe_cleanup_mcg(struct kref *kref) -{ - struct rxe_mcg *mcg = container_of(kref, typeof(*mcg), ref_cnt); - - kfree_rcu(mcg, rcu); -} - -/** - * __rxe_destroy_mcg - destroy mcg object holding rxe->mcg_mutex - * @mcg: the mcg object - * - * Context: caller is holding rxe->mcg_mutex - * no qp's are attached to mcg - */ -static void __rxe_destroy_mcg(struct rxe_mcg *mcg) -{ - struct rxe_dev *rxe = mcg->rxe; - - /* remove mcg from red-black tree then drop ref */ - __rxe_remove_mcg(mcg); - kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); - - atomic_dec(&rxe->mcg_num); -} - -/** - * rxe_destroy_mcg - destroy mcg object - * @mcg: the mcg object - * - * Context: no qp's are attached to mcg - */ -static void rxe_destroy_mcg(struct rxe_mcg *mcg) -{ - /* delete mcast address outside of lock */ - rxe_mcast_del(mcg); - - mutex_lock(&mcg->rxe->mcg_mutex); - __rxe_destroy_mcg(mcg); - mutex_unlock(&mcg->rxe->mcg_mutex); -} - -/** - * rxe_attach_mcg - attach qp to mcg if not already attached - * @qp: qp object - * @mcg: mcg object - * - * Returns: 0 on success else an error - */ -static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) +static int rxe_attach_mcg(struct rxe_qp *qp, struct rxe_mcg *mcg) { struct rxe_dev *rxe = mcg->rxe; struct rxe_mca *mca; unsigned long flags; - int err; + int err = 0; mutex_lock(&rxe->mcg_mutex); spin_lock_irqsave(&mcg->lock, flags); @@ -348,29 +294,24 @@ static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) rxe_get(qp); mca->qp = qp; + rxe_get_mcg(mcg); + spin_lock_irqsave(&mcg->lock, flags); list_add_tail(&mca->qp_list, &mcg->qp_list); spin_unlock_irqrestore(&mcg->lock, flags); -out: - mutex_unlock(&rxe->mcg_mutex); - return 0; + goto out; err_dec_qp_num: atomic_dec(&mcg->qp_num); err_dec_attach: atomic_dec(&rxe->mcg_attach); +out: + rxe_put_mcg(mcg); mutex_unlock(&rxe->mcg_mutex); return err; } -/** - * rxe_detach_mcg - detach qp from mcg - * @mcg: mcg object - * @qp: qp object - * - * Returns: 0 on success else an error if qp is not attached. - */ -static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) +static int rxe_detach_mcg(struct rxe_qp *qp, struct rxe_mcg *mcg) { struct rxe_dev *rxe = mcg->rxe; struct rxe_mca *mca; @@ -387,7 +328,6 @@ static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) } spin_unlock_irqrestore(&mcg->lock, flags); - /* we didn't find the qp on the list */ err = -EINVAL; goto err_out; @@ -395,23 +335,15 @@ static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) spin_lock_irqsave(&mcg->lock, flags); list_del(&mca->qp_list); spin_unlock_irqrestore(&mcg->lock, flags); + rxe_put_mcg(mcg); atomic_dec(&mcg->qp_num); atomic_dec(&mcg->rxe->mcg_attach); atomic_dec(&mca->qp->mcg_num); rxe_put(mca->qp); kfree(mca); - - /* if the number of qp's attached to the - * mcast group falls to zero go ahead and - * tear it down. This will not free the - * object since we are still holding a ref - * from the caller - */ - if (atomic_read(&mcg->qp_num) <= 0) - __rxe_destroy_mcg(mcg); - err_out: + rxe_put_mcg(mcg); mutex_unlock(&rxe->mcg_mutex); return err; } @@ -426,7 +358,6 @@ static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp) */ int rxe_attach_mcast(struct ib_qp *ibqp, union ib_gid *mgid, u16 mlid) { - int err; struct rxe_dev *rxe = to_rdev(ibqp->device); struct rxe_qp *qp = to_rqp(ibqp); struct rxe_mcg *mcg; @@ -434,20 +365,11 @@ int rxe_attach_mcast(struct ib_qp *ibqp, union ib_gid *mgid, u16 mlid) if (rxe->attr.max_mcast_grp == 0) return -EINVAL; - /* takes a ref on mcg if successful */ - mcg = rxe_get_mcg(rxe, mgid); + mcg = rxe_alloc_mcg(rxe, mgid); if (IS_ERR(mcg)) return PTR_ERR(mcg); - err = rxe_attach_mcg(mcg, qp); - - /* if we failed to attach the first qp to mcg tear it down */ - if (atomic_read(&mcg->qp_num) == 0) - rxe_destroy_mcg(mcg); - - kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); - - return err; + return rxe_attach_mcg(qp, mcg); } /** @@ -463,14 +385,10 @@ int rxe_detach_mcast(struct ib_qp *ibqp, union ib_gid *mgid, u16 mlid) struct rxe_dev *rxe = to_rdev(ibqp->device); struct rxe_qp *qp = to_rqp(ibqp); struct rxe_mcg *mcg; - int err; mcg = rxe_lookup_mcg(rxe, mgid); if (!mcg) return -EINVAL; - err = rxe_detach_mcg(mcg, qp); - kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); - - return err; + return rxe_detach_mcg(qp, mcg); } diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c index 6cf0da958864..e3ec3dfc57f4 100644 --- a/drivers/infiniband/sw/rxe/rxe_recv.c +++ b/drivers/infiniband/sw/rxe/rxe_recv.c @@ -262,7 +262,7 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb) spin_unlock_irqrestore(&mcg->lock, flags); - kref_put(&mcg->ref_cnt, rxe_cleanup_mcg); + rxe_put_mcg(mcg); if (likely(!skb)) return; From patchwork Wed Nov 29 20:25:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13473427 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eyUy2RxQ" Received: from mail-oo1-xc34.google.com (mail-oo1-xc34.google.com [IPv6:2607:f8b0:4864:20::c34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B903910C2 for ; Wed, 29 Nov 2023 12:26:32 -0800 (PST) Received: by mail-oo1-xc34.google.com with SMTP id 006d021491bc7-58dd3528497so139251eaf.3 for ; Wed, 29 Nov 2023 12:26:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701289592; x=1701894392; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8xW8YlJNeX4Wpian/ZFUqeO11K05OcmJkUPNwn2Dt/c=; b=eyUy2RxQ+u+EtCpl0CMmsJHDsA8pgSnmzPFDOyfHgo0/7xE8Vy7nBKVD5pFD8lMvhD 8HdsxYH6yTcrE6ZhphamUIh7TiTGrqRv3e71t5Z/odbZf6fTIBE/q4p44EeKNTnBLwXn YQMo7RlNjJY5Mvq88VqZp83h+1F7fkIUt6cbsZtaopmgQ2XD1iO0d3ra9oPILPX+MDYX 1MrNPnQhRJRS/j6jK9l4VKWh4G4n12iyk7Zw8ElNInDeNGUHxCxBTOH/Izupt1gcyx0h fbcssIhemP3q66DrvLq2XLPsfqprVXQOAeWzx7JUeL5YFkg7r85DIx6iKIjupMdqDEdn 9XZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701289592; x=1701894392; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8xW8YlJNeX4Wpian/ZFUqeO11K05OcmJkUPNwn2Dt/c=; b=c4CwUsh9H8KZyInrLW4vYlxD2aYZuCuOdlAhJhjCuQ/9rP6zEyIXxKBfGgg8iNgEkf uFit79qYx1nybZmr3GGoZ0RF4Gf9zRRfKTslGSTEbWFzBJ9sKJRXWv4HWjhl3GkxfuQ/ PoJGy5JKjdnViMqMvdBDnfdbtNmgjRwCmTIKC5Cea/u1hAWnJ1c/1YrechbfD7FswLEj b54+oJVLHpPNeLydoJh5fMDC7xoptaN5s4+DwtZroWFfYtfc+Nytj2CyjcGc5s9z2uft L4jv/c+cKxJH28ayIQPYEM3XKqRbNdYMUL+yUV9hYWUlutiERny8zFUPTCRM6RmYUm4W LhGQ== X-Gm-Message-State: AOJu0YysmW8iSLnoxAMH83JsybBaEWufdGOG3FrZODmnygAjBWroqQLU LIJlRYsgOeOUz1n9S5eheGp5TnIugDI= X-Google-Smtp-Source: AGHT+IHPN3GfAiGMQTOaEfaGDw3kcFqkDlHBAyBqnrFPKLKsWKcgCk7Oz/nyuc0/AlVbubV1rVhhVQ== X-Received: by 2002:a05:6820:1c92:b0:58d:e48a:6e63 with SMTP id ct18-20020a0568201c9200b0058de48a6e63mr336226oob.2.1701289592029; Wed, 29 Nov 2023 12:26:32 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-6755-34f8-2ed3-56ec.res6.spectrum.com. [2603:8081:1405:679b:6755:34f8:2ed3:56ec]) by smtp.gmail.com with ESMTPSA id 126-20020a4a0684000000b0058ab906ae38sm2473867ooj.2.2023.11.29.12.26.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 29 Nov 2023 12:26:31 -0800 (PST) From: Bob Pearson To: jgg@nvidia.com, yanjun.zhu@linux.dev, linux-rdma@vger.kernel.org Cc: Bob Pearson Subject: [PATCH for-next v3 7/7] RDMA/rxe: Add module parameters for mcast limits Date: Wed, 29 Nov 2023 14:25:59 -0600 Message-Id: <20231129202558.31682-8-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231129202558.31682-1-rpearsonhpe@gmail.com> References: <20231129202558.31682-1-rpearsonhpe@gmail.com> Precedence: bulk X-Mailing-List: linux-rdma@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Add module parameters for max_mcast_grp, max_mcast_qp_attach, and tot_mcast_qp_attach to allow setting these parameters to small values when the driver is loaded to support testing these limits. Signed-off-by: Bob Pearson --- drivers/infiniband/sw/rxe/Makefile | 3 ++- drivers/infiniband/sw/rxe/rxe.c | 6 +++--- drivers/infiniband/sw/rxe/rxe_param.c | 23 +++++++++++++++++++++++ drivers/infiniband/sw/rxe/rxe_param.h | 4 ++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 drivers/infiniband/sw/rxe/rxe_param.c diff --git a/drivers/infiniband/sw/rxe/Makefile b/drivers/infiniband/sw/rxe/Makefile index 5395a581f4bb..b183924ea01d 100644 --- a/drivers/infiniband/sw/rxe/Makefile +++ b/drivers/infiniband/sw/rxe/Makefile @@ -22,4 +22,5 @@ rdma_rxe-y := \ rxe_mcast.o \ rxe_task.o \ rxe_net.o \ - rxe_hw_counters.o + rxe_hw_counters.o \ + rxe_param.o diff --git a/drivers/infiniband/sw/rxe/rxe.c b/drivers/infiniband/sw/rxe/rxe.c index 147cb16e937d..599fbfdeb426 100644 --- a/drivers/infiniband/sw/rxe/rxe.c +++ b/drivers/infiniband/sw/rxe/rxe.c @@ -59,9 +59,9 @@ static void rxe_init_device_param(struct rxe_dev *rxe) rxe->attr.max_res_rd_atom = RXE_MAX_RES_RD_ATOM; rxe->attr.max_qp_init_rd_atom = RXE_MAX_QP_INIT_RD_ATOM; rxe->attr.atomic_cap = IB_ATOMIC_HCA; - rxe->attr.max_mcast_grp = RXE_MAX_MCAST_GRP; - rxe->attr.max_mcast_qp_attach = RXE_MAX_MCAST_QP_ATTACH; - rxe->attr.max_total_mcast_qp_attach = RXE_MAX_TOT_MCAST_QP_ATTACH; + rxe->attr.max_mcast_grp = rxe_max_mcast_grp; + rxe->attr.max_mcast_qp_attach = rxe_max_mcast_qp_attach; + rxe->attr.max_total_mcast_qp_attach = rxe_max_tot_mcast_qp_attach; rxe->attr.max_ah = RXE_MAX_AH; rxe->attr.max_srq = RXE_MAX_SRQ; rxe->attr.max_srq_wr = RXE_MAX_SRQ_WR; diff --git a/drivers/infiniband/sw/rxe/rxe_param.c b/drivers/infiniband/sw/rxe/rxe_param.c new file mode 100644 index 000000000000..27873e7de753 --- /dev/null +++ b/drivers/infiniband/sw/rxe/rxe_param.c @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB +/* + * Copyright (c) 2023 Hewlett Packard Enterprise, Inc. All rights reserved. + */ + +#include "rxe.h" + +int rxe_max_mcast_grp = RXE_MAX_MCAST_GRP; +module_param_named(max_mcast_grp, rxe_max_mcast_grp, int, 0444); +MODULE_PARM_DESC(max_mcast_grp, + "Maximum number of multicast groups per device"); + +int rxe_max_mcast_qp_attach = RXE_MAX_MCAST_QP_ATTACH; +module_param_named(max_mcast_qp_attach, rxe_max_mcast_qp_attach, + int, 0444); +MODULE_PARM_DESC(max_mcast_qp_attach, + "Maximum number of QPs attached to a multicast group"); + +int rxe_max_tot_mcast_qp_attach = RXE_MAX_TOT_MCAST_QP_ATTACH; +module_param_named(max_tot_mcast_qp_attach, rxe_max_tot_mcast_qp_attach, + int, 0444); +MODULE_PARM_DESC(max_tot_mcast_qp_attach, + "Maximum total number of QPs attached to multicast groups per device"); diff --git a/drivers/infiniband/sw/rxe/rxe_param.h b/drivers/infiniband/sw/rxe/rxe_param.h index d2f57ead78ad..d6fe50f5f483 100644 --- a/drivers/infiniband/sw/rxe/rxe_param.h +++ b/drivers/infiniband/sw/rxe/rxe_param.h @@ -125,6 +125,10 @@ enum rxe_device_param { RXE_VENDOR_ID = 0XFFFFFF, }; +extern int rxe_max_mcast_grp; +extern int rxe_max_mcast_qp_attach; +extern int rxe_max_tot_mcast_qp_attach; + /* default/initial rxe port parameters */ enum rxe_port_param { RXE_PORT_GID_TBL_LEN = 1024,