From patchwork Tue Dec 5 00:23:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13479216 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="UErw5z0T" Received: from mail-oi1-x22b.google.com (mail-oi1-x22b.google.com [IPv6:2607:f8b0:4864:20::22b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F24DB0 for ; Mon, 4 Dec 2023 16:24:16 -0800 (PST) Received: by mail-oi1-x22b.google.com with SMTP id 5614622812f47-3b844357f7cso2809836b6e.1 for ; Mon, 04 Dec 2023 16:24:16 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701735855; x=1702340655; 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=UErw5z0T0aZ4tOdWoU/ua9QBycOSmeUCijT2L0NkRJWIFu/6rZvyN+zokKKzVlF60h P4SGc6JJNW8JloVLOCQxGD+cQqOcHppUvOA2IXf8kDYvJ9FXpB6VDsg69S41pNkSuBUs L5yJ8hsZPo8fiOt1MU7uj9G6mmqnafKJo0BUBcYpB6vx70ROOHFc2cz/4T7dN9OGJj1i +53DE/YGzc9zuqrTq9SZJ7macYOWlYRtCASMftBJ5P1uAPfWNUBhNWihZ+ImlRiu84tT A9CzHnAg0F1c6AcFNqZY25tetaM+qkabYnBb7Ci7RbHZmwpykD5JPHt+soCIO1OizJRN eN3w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701735855; x=1702340655; 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=coykprlQ/KBhlrZDL7xt0GLXQ+Vgo949yijUyzyvEru6GHBO/13teTHK2nMI5lNRKX zbE7tqtr3Iy0XeTSoS/gnk0fAJ5UbcgUAAqWMEcFUCSftwNhBAb0bV25/pI1unANfngs rGRLMiWUOTaDD0mJIOnhtBb/JTKgrvSYMCnmiVNosDdMLEjIRfAFA9Le4mPqxi6j1j8x y/Tbg/JrP2Yf4WkufS3AJfXiT1Y+r2g0l3fXp/C4l9bmB1sUXXk18EmDU7Dt66u/U4dv YQdrXtaRfJN81NwRw902hwXbCy2zg3k45jl/aRCAjvohHgablEyzJ8slfnT5CqK9kWIK Fe9A== X-Gm-Message-State: AOJu0YzBLoBXCMdaWFr50t67bxnDoj6RYHxVvHyGnuctPYmjYPsnCNqv 9fltzYhxQ/VrH3GTktslda8= X-Google-Smtp-Source: AGHT+IFbGoBnxVwJlflAQCGHCAnRdF58ujxT3MuF/tzBK8hUjHAEspceJayEYpyddRsZF1UmtPXGlg== X-Received: by 2002:aca:1b08:0:b0:3b6:b073:20d7 with SMTP id b8-20020aca1b08000000b003b6b07320d7mr4757160oib.17.1701735855382; Mon, 04 Dec 2023 16:24:15 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-e463-fe8f-1aa8-6edb.res6.spectrum.com. [2603:8081:1405:679b:e463:fe8f:1aa8:6edb]) by smtp.gmail.com with ESMTPSA id bi25-20020a056808189900b003b2e4754cc2sm2007066oib.26.2023.12.04.16.24.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 16:24:14 -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 v5 1/7] RDMA/rxe: Cleanup rxe_ah/av_chk_attr Date: Mon, 4 Dec 2023 18:23:18 -0600 Message-Id: <20231205002322.10143-2-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231205002322.10143-1-rpearsonhpe@gmail.com> References: <20231205002322.10143-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 Tue Dec 5 00:23:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13479217 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="idofMd5q" Received: from mail-oi1-x230.google.com (mail-oi1-x230.google.com [IPv6:2607:f8b0:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3992B0 for ; Mon, 4 Dec 2023 16:24:19 -0800 (PST) Received: by mail-oi1-x230.google.com with SMTP id 5614622812f47-3b88f2a37deso2981423b6e.0 for ; Mon, 04 Dec 2023 16:24:19 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701735859; x=1702340659; 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=idofMd5qJjdatpiTn32waov+vZBiP9zTmBHP3pRT+DitmlwF+2AYpd+JQWaCfgh9Fx MHq5pj5UmdKmH8BQZZJgVG+ZUsXwTgxy0/puk2v/io2WB39xkt1LXDUgppcPCpUgNY0X BNzHIwiLP5TTQ8hgAiUKWEiuB8pDA+zAznHc0k/QWX0Kj8Yoi3Im48mS0AQaa2+lOmF5 2Rd6bQF7eUzV16OSqQSVbSz8e1tEnQcXshQG31/LNAx0CybNXAc4kCbxkf+5eeu1HXnC xMTiqu6p0FvTtK3fejsd77/SH16NY3eaWrdj1U9iBZIfhphGpxaruWngUAyVhfBAs+Zl Wnog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701735859; x=1702340659; 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=TVSFO/Qivo+7sbAgJ/RnGSXrOyBexFlq2nhXfvF1xAk2Ms/O7Ub7DyeQWZ4c7YNwt1 MgGV6YFffqR53rZy+mXg+q+5T2gNIjKIGoZDo2mfrNLaRIY9YPT3fmJAxxpHuD8JY0SM Ksi3cOrPRSrSLlTs2oyZsGdmQ6ZEEcKUeQxMe0+m6XfYojcArKQKdT7OjuuPi19vsQyY LH1+QFOcZEoX65uOtCfiULew19cmnudb/Mf881GTNeTLjDl1cl1mSNyeZS4lmJDd9hUB cXdme61fFPtVwRM5VGsKPsKpRrK0+Ck7Rcz2vz55TYkUZJp1zRFhoH5DXuwDSuiTQa3a 1dfw== X-Gm-Message-State: AOJu0Yziww4t49nWoAvfwqGgAVooiRW3Jl/n4Ic83od6VQmmMk4hWMXV WTsGOW5rvlxcGn1EtXHCM/UGhT1oLcg= X-Google-Smtp-Source: AGHT+IGJxmzXOezfV7jrF//jxSlH95eexjwnP0qKtRmDFvllNeEK3Mtb9l39IFYQ4VKPSgtMfDh3DQ== X-Received: by 2002:a05:6808:1286:b0:3b8:b063:5059 with SMTP id a6-20020a056808128600b003b8b0635059mr5511159oiw.90.1701735859334; Mon, 04 Dec 2023 16:24:19 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-e463-fe8f-1aa8-6edb.res6.spectrum.com. [2603:8081:1405:679b:e463:fe8f:1aa8:6edb]) by smtp.gmail.com with ESMTPSA id bi25-20020a056808189900b003b2e4754cc2sm2007066oib.26.2023.12.04.16.24.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 16:24:18 -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 v5 2/7] RDMA/rxe: Fix sending of mcast packets Date: Mon, 4 Dec 2023 18:23:19 -0600 Message-Id: <20231205002322.10143-3-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231205002322.10143-1-rpearsonhpe@gmail.com> References: <20231205002322.10143-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 Tue Dec 5 00:26:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13479218 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Gsk3ZZEw" Received: from mail-oa1-x35.google.com (mail-oa1-x35.google.com [IPv6:2001:4860:4864:20::35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 136A9AC for ; Mon, 4 Dec 2023 16:26:25 -0800 (PST) Received: by mail-oa1-x35.google.com with SMTP id 586e51a60fabf-1faf152a1dbso2827166fac.0 for ; Mon, 04 Dec 2023 16:26:25 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701735984; x=1702340784; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=VyY4gAFnlXRgWPxP9SMwMMju7nkj3UkGC1u3lDyzCZM=; b=Gsk3ZZEw87vjA677ZkxTHY0dJg1H5WgGCKHBcCOG7QED2gilD/t/0MkfyA87pEYdvW wY6+4ByUlw6/adjlHPYpMzTq5ITy7eUdLUq5odeoK4DIuczOB6z8xMtLSuam36c1w4gf r6/KrHjNXS8hYPOE4GjATORaoA6kIhsrZZvi25Ms5lFQgSozSAVgYgdE67643NazOujl Os2Zr0xlqEDnT5bCHBoK9KkBaCE//jMFIfxOIV8wGpA+nWcPHESH08Q7J9WGcvTmsBbK PS2O1q+q9hkxEUFoeTmplZx0DTRzOODSOYllq7WfLyarhgnBOLawYnpya+0UdJZhpbpA NwFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701735984; x=1702340784; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=VyY4gAFnlXRgWPxP9SMwMMju7nkj3UkGC1u3lDyzCZM=; b=QKzDOFJj488mHkHUc1f3OH4E+98a6Tp4Xrced4TZN3+27jsxnGV7KNnB2WWnH+G+cP qt7Wn+1Ub4ro8LK40ju/SswVf1f2qzfvThBclebYYrhpLY177dF/sE60tykBn0zpfoEx V+vJuugj7HH7B9si78PEBLgWIwO0Gni/8BwkfLYZgfxTkRsA5r5HAZN8Vkcto15jlEgR FHsdAS9NWOYaciqEAk/SYUNXadEh565+Bdd9KDWca00P60qJsKkgiGeODclJpZg7iCaV kSrSh+wAsAaUJMMEnlqmXcx0ZutGIa2FA+ZJODpcs0HfTAciIWq1PtYNnt+1IV5OTIOK gJhg== X-Gm-Message-State: AOJu0Yw+mf75t8vFvZ2JJd52KkOLR8+hk9NN+Hy2vebYFgrrzo+LqeMT efpB5klKo6SkJFEstanEiHE= X-Google-Smtp-Source: AGHT+IE93HZSVo63t0aN+7n3ld/EEJzR/l4T0BurpalCp5d/MV/kXDj9aUwMvj8rHFjcBE3ya0+EVQ== X-Received: by 2002:a05:6870:d621:b0:1fb:75b:2fb7 with SMTP id a33-20020a056870d62100b001fb075b2fb7mr5933156oaq.78.1701735984111; Mon, 04 Dec 2023 16:26:24 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-e463-fe8f-1aa8-6edb.res6.spectrum.com. [2603:8081:1405:679b:e463:fe8f:1aa8:6edb]) by smtp.gmail.com with ESMTPSA id se6-20020a05687122c600b001faf09f0899sm2524844oab.24.2023.12.04.16.26.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 16:26:23 -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 v5 3/7] RDMA/rxe: Register IP mcast address Date: Mon, 4 Dec 2023 18:26:10 -0600 Message-Id: <20231205002613.10219-1-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 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 | 119 +++++++++++++++++++++----- 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, 102 insertions(+), 21 deletions(-) diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c index 86cc2e18a7fd..54735d07cee5 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -19,38 +19,116 @@ * 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; + struct sock *sk = recv_sockets.sk6->sk; unsigned char ll_addr[ETH_ALEN]; + int err; + + spin_lock_bh(&sk->sk_lock.slock); + rtnl_lock(); + err = ipv6_sock_mc_join(sk, rxe->ndev->ifindex, addr6); + rtnl_unlock(); + spin_unlock_bh(&sk->sk_lock.slock); + 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: + spin_lock_bh(&sk->sk_lock.slock); + rtnl_lock(); + ipv6_sock_mc_drop(sk, rxe->ndev->ifindex, addr6); + rtnl_unlock(); + spin_unlock_bh(&sk->sk_lock.slock); +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) +{ + struct sock *sk = recv_sockets.sk6->sk; + 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); + + spin_lock_bh(&sk->sk_lock.slock); + rtnl_lock(); + err2 = ipv6_sock_mc_drop(sk, rxe->ndev->ifindex, + (struct in6_addr *)mgid); + rtnl_unlock(); + spin_unlock_bh(&sk->sk_lock.slock); + + 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 +242,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 +304,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 +352,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 Tue Dec 5 00:26:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13479219 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="dhmZGWiz" Received: from mail-ot1-x331.google.com (mail-ot1-x331.google.com [IPv6:2607:f8b0:4864:20::331]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3E964FF for ; Mon, 4 Dec 2023 16:26:37 -0800 (PST) Received: by mail-ot1-x331.google.com with SMTP id 46e09a7af769-6d986a75337so1214979a34.1 for ; Mon, 04 Dec 2023 16:26:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701735996; x=1702340796; 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=uj0PU7uEjCTBczW0/yievyQR0AIrXN2P5Hcurk7TtSE=; b=dhmZGWizEpgZhq+Htdpurc7DZT1LRh9lX/uiTkMm1V7ZL4JWc+Pvr7wDRvHc5nM8d5 HDpRsd5YICdGG5oJ5gNZVSiJgGotVpylfP1JHRr9FOj/fLI7FbnllkHpThu6biQLcwmW cYnOE29JeW1QDv8XO6vsm7maABGWJFHf61Rh9Id+O3+NSAf73t9ya48EQgSMoVeY7LI8 +sPUGTb+JEZJMRavDnhWTXwkntC0GQEtJ8fTSTpc+iScFMHWQkeO+nroN2i+JrcTzf/w ACxyaC5zHDJHC3qft4wdjXVySAUJ9xGdI53QdWrm7z8ika4vkHr7UFkEHWUkz1U8GCHG NkZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701735996; x=1702340796; 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=uj0PU7uEjCTBczW0/yievyQR0AIrXN2P5Hcurk7TtSE=; b=uRTjZCJO43osno4iKlwKPV9A0rA8T8CeXrU9G2oH+KoHuTwgw9S3azFv+/TQNAGxIa GA2sQNfCVDemy0iMQxEOrpFYSDWr1UZ5vZG6mIdNlZOjToi6MqoM6oRh24J/6WggH2/1 AHChpNwyubvBFQkYtOGgUnh36F867Eyno61lS6gvbnCKTc9l5ZGP6Wo37KUxbq/xIOlc NsNkwtUrEO+doVkOUMKqN6gIJ2zW5f8C7vV6cUSiy3H+iuuPjbQI7uid/bt4p/zP9efv jvXHKQXUZJv30LJ80Z3738yKM8uWINm7Z2C2xxc6X5QQi3a0eo22R1qk83jRjrs7lwMa 7EFg== X-Gm-Message-State: AOJu0YxiUWQZMFzQLVpj/6XwsqrP9cfpco2NikADynv+1kM5meB8DITK ZHvqU/Cd2gqBZCn/JCQujPU= X-Google-Smtp-Source: AGHT+IEmrDLD3lDXg9MkyEqLEb7IMMTElHH2N53S8C4REFmlmN7GlnsONMC/mQWGSu5Cj1DZx9UbPQ== X-Received: by 2002:a05:6871:6a9:b0:1fa:e7f8:efd5 with SMTP id l41-20020a05687106a900b001fae7f8efd5mr5695080oao.34.1701735996392; Mon, 04 Dec 2023 16:26:36 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-e463-fe8f-1aa8-6edb.res6.spectrum.com. [2603:8081:1405:679b:e463:fe8f:1aa8:6edb]) by smtp.gmail.com with ESMTPSA id se6-20020a05687122c600b001faf09f0899sm2524844oab.24.2023.12.04.16.26.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 16:26:35 -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 v5 4/7] RDMA/rxe: Let rxe_lookup_mcg use rcu_read_lock Date: Mon, 4 Dec 2023 18:26:11 -0600 Message-Id: <20231205002613.10219-2-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231205002613.10219-1-rpearsonhpe@gmail.com> References: <20231205002613.10219-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 54735d07cee5..44948f9cb02b 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -151,13 +151,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); } @@ -172,15 +177,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; @@ -188,7 +189,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); @@ -196,35 +198,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; } @@ -292,7 +273,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); @@ -322,7 +303,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 Tue Dec 5 00:26:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13479220 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CWUPPr3p" Received: from mail-ot1-x329.google.com (mail-ot1-x329.google.com [IPv6:2607:f8b0:4864:20::329]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 24E5CA0 for ; Mon, 4 Dec 2023 16:26:38 -0800 (PST) Received: by mail-ot1-x329.google.com with SMTP id 46e09a7af769-6d7fa93afe9so2653840a34.2 for ; Mon, 04 Dec 2023 16:26:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701735997; x=1702340797; 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=qk+yeA3qxabXsfoTrQlGMJr8FjaKfyQf8fDS3iLQbOQ=; b=CWUPPr3pT8Ct5vlFlw/qZDKpCLr6R33LfXVenvMJDg1j614PnQ1JU1xX5kry0TWmMf Ml8/2NTFkdMhoo4w56Qg1ufsDoB61P0EBPCsbf5OjtbzA55IMKQL/MKVCivd/aQJO0yp /LYaZ5LFq+Jr6ATGjgNwkX1Qs7UqYZ3N7hK0x03F+/ksBR8IVHmzqrd6XujE2TRTY5RY Z5xZ/MRNnungxYBJi6rCHIsTpwurY+nudoFkWbxsM+CLqRpjT52Ju/T39GW0qDxCgXwV njiCiMhyk9xSqmnKsvujUiA0NEqrqkfU4v6KqjaAv8TIexHozHi/BJdTaX153tfQ8+Kf UGeA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701735997; x=1702340797; 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=qk+yeA3qxabXsfoTrQlGMJr8FjaKfyQf8fDS3iLQbOQ=; b=rBx2dOudf6sbYN9h1S3TELUfb4oo/iry9olC5jd/pO8cyEQFv0sr2lHF2Mscezyjsi OfjrmFkR62mdLhX1JTlwOXDdNF7uqouPphjNMlw+2qU/C11kKBx7PqLmD3AT1l/lVfyR TgAnWfAzZPqrCEZKcAomnmBoD/i1ux5th2ZJfXwz///WCcVHKwozGquofeyhvzsw3L82 RVtGp8wMBFsNc98dPfaphTrOZsiPftL45bVRKsA7N5OR2nteBlHH7wCGo6bIAQBnlwxd lDmRgm0W7Rp0hprUsbqtT5N7mIP8InYl9QbHs6P8JZ8u8v2Eyx6idGxf6LDebrxjlA5v siwg== X-Gm-Message-State: AOJu0Yz/HPmCrZ9blTPe1YIotBl+MmgiVFJL0k+oaBGus3cW9iC8Eii5 WneJKPuGMnUcMCfpcPJ41TU= X-Google-Smtp-Source: AGHT+IHEANRqVhqWfNAttj4Ul0X+DfrRGukTUZNso3aTd/L3Q8ibQQetcNv15srM1+IlCS9OYxiBkQ== X-Received: by 2002:a05:6870:e415:b0:1fb:75a:c42b with SMTP id n21-20020a056870e41500b001fb075ac42bmr5253249oag.84.1701735997396; Mon, 04 Dec 2023 16:26:37 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-e463-fe8f-1aa8-6edb.res6.spectrum.com. [2603:8081:1405:679b:e463:fe8f:1aa8:6edb]) by smtp.gmail.com with ESMTPSA id se6-20020a05687122c600b001faf09f0899sm2524844oab.24.2023.12.04.16.26.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 16:26:36 -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 v5 5/7] RDMA/rxe: Split multicast lock Date: Mon, 4 Dec 2023 18:26:12 -0600 Message-Id: <20231205002613.10219-3-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231205002613.10219-1-rpearsonhpe@gmail.com> References: <20231205002613.10219-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 44948f9cb02b..ac8da0bc8428 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -135,7 +135,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) @@ -170,7 +170,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) { @@ -210,34 +210,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 @@ -247,51 +219,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); } @@ -307,10 +276,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) @@ -335,151 +304,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; } /** @@ -497,6 +438,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 Tue Dec 5 00:26:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13479221 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="EIeIxLuH" Received: from mail-oa1-x2a.google.com (mail-oa1-x2a.google.com [IPv6:2001:4860:4864:20::2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3CED8AC for ; Mon, 4 Dec 2023 16:26:39 -0800 (PST) Received: by mail-oa1-x2a.google.com with SMTP id 586e51a60fabf-1faf152a1dbso2827233fac.0 for ; Mon, 04 Dec 2023 16:26:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701735998; x=1702340798; 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=IvxHjSrzMnuGgT7hgLHumBNegp7XoJoR3wahzbsn2B0=; b=EIeIxLuH3MxCsQfdP8Kie8rZtsF0ImpH7JGafgV1I3HtK+AYLbCF0T1jrmZ0DzvRuK z+w49evMgchDb3FisdLSW3oqJcHsjQ5MZr5DMdUrv8RhCpQu3keQjCR4Mn6BMjMf6ftA gca03IHpqf7Mbrmb2QsXCPStZ5bKPiFc1QZzOf7mkFh/5IrMmA+f6LUITKD1y1zMyBDN rKMij37120JlO+u9m2tVHOb4u9/ph0xx5jjeWiYrqQeokeGcBQEfRcho3tv/0YM06Uuu 0m6Rs++Nzg4V83upzBOKtXmQkWmdKgGUW+tf2wwHtyhJK5yEZUeD7q+z4c6uGVkkDT1k jLxQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701735998; x=1702340798; 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=IvxHjSrzMnuGgT7hgLHumBNegp7XoJoR3wahzbsn2B0=; b=RB8IarTCARpijJC7cI1QIWo1FerWntnS7bBny7ceQnmxDP8z0QESSM2EcycauVNUSW HjxPBrkXx0ALqSYiYtJG+0Bvh86gwzTmjN1CcaseR3r2nObUfywAh9L8N/MDTQn69w3h QWO4yARzmPnUwEVtsHB3JFJppCDSrhxBLmX2mR7VWi7HAQLyNl2IQp9fTfGv/s+fDKHu kSbMzP83x1c6hlxFHIsnC6oSVgJmq/WFeMaWN1Krd+M2vQgErfL/muSVU4tBfUTUyLRo HPps4COuZzduVmchz56EeLdf9NKHA5WXydqeAR1N3yQ1kunTdXC+lArbifqPs4gbENFn fbJw== X-Gm-Message-State: AOJu0YzsiJ54c0BASSssKY8qKfjghxeKAU3y6bbKUa2nExOptWhjT4k0 PzrtdbWayzheIFUAqdNY31E= X-Google-Smtp-Source: AGHT+IEN7bnNpiH4Gf/e0MD2Pv26lHhKJUFu2MwOm6w3ApGEzdqEiVzvu6bDuWJgjOvo0j3vudFQ8g== X-Received: by 2002:a05:6870:4c17:b0:1fb:20ca:95df with SMTP id pk23-20020a0568704c1700b001fb20ca95dfmr4618673oab.39.1701735998482; Mon, 04 Dec 2023 16:26:38 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-e463-fe8f-1aa8-6edb.res6.spectrum.com. [2603:8081:1405:679b:e463:fe8f:1aa8:6edb]) by smtp.gmail.com with ESMTPSA id se6-20020a05687122c600b001faf09f0899sm2524844oab.24.2023.12.04.16.26.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 16:26:37 -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 v5 6/7] RDMA/rxe: Cleanup mcg lifetime Date: Mon, 4 Dec 2023 18:26:13 -0600 Message-Id: <20231205002613.10219-4-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231205002613.10219-1-rpearsonhpe@gmail.com> References: <20231205002613.10219-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 ac8da0bc8428..c2a28aed9d34 100644 --- a/drivers/infiniband/sw/rxe/rxe_mcast.c +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c @@ -131,13 +131,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; @@ -166,23 +184,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; @@ -204,20 +210,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; @@ -228,7 +228,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; } @@ -244,19 +244,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); @@ -264,64 +262,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); @@ -355,29 +301,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; @@ -394,7 +335,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; @@ -402,23 +342,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; } @@ -433,7 +365,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; @@ -441,20 +372,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); } /** @@ -470,14 +392,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 Tue Dec 5 00:26:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bob Pearson X-Patchwork-Id: 13479222 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="jvNXgLVQ" 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 21994101 for ; Mon, 4 Dec 2023 16:26:40 -0800 (PST) Received: by mail-oo1-xc31.google.com with SMTP id 006d021491bc7-58d9a4e9464so2119716eaf.0 for ; Mon, 04 Dec 2023 16:26:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701735999; x=1702340799; 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=jvNXgLVQNV2DrieYctnlqbZW1brVmJ82ifY1cFYHWJVp0S+FoUUf+CLy87Q49VGDEy Yyf6YXKKospr3m4yfCp1GH4ldRj6sJt0cprEsWbAkmdbKim7K/JsXSEdMNBHurSP/tsa aIbmk22zqh8voZBKjSvG5sBv7iMi8y+p1yS0k0NdKfIGESalZz4Lf75V38BMid0VqWDY a1DYUSQ2LgDt+KI4rl668yFqUBX9S4wDAWf9EOopQGKpJ3tURvGFXT0BQxJRqjBbsYGB fCa76NPnauiyklorihjfr/qcRz3BEfjM4PYMDOzChlOjHuTetHJ4PVgWXTrn5jTkBwhO PLug== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701735999; x=1702340799; 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=aRcLGxGbXxepH5GJBdvrkM2VfSZjAQVd03OGd6kDXTo+nlJOq974VAgng+An9Vk80g r3oc6+5bwF8TXZ+9O0Gq8OAAVh9wTFGnpdEsRB2XUtilJz8VlmLPU63Q8QyPcHj6gPLi usLvFQ/QmFDs93aeDNzdcibh75l5877gVih2uwBH4oai0gKABKQdmOpH3O1FRneJ1DO1 Dr0WZXJv89o5lEz4S9TgQcYrSNetTEE1yLDt2JBJYWs6XytZVkl2VMrjZ2BUoVbL98Mi epYZeJzSumbPDeAG1NA/urjdhRRy/dAkqAZLT0i0d+nQSXMCtp90oFUAiFDhpw5W6j8+ 3WNQ== X-Gm-Message-State: AOJu0YyRZWZgwOvbxs2FsLFxRF9JZoVmmcdD1ftXCLLlFXIBCwR0Cdc9 Zi3CfpQdTVyfCcaoGHhkQ5w= X-Google-Smtp-Source: AGHT+IHPgbqQjTSpGBS3XWQiknNiZaaxQ69rr989yEo4G3bk316XWrCuye9FaMva/439B4mqbcWUYQ== X-Received: by 2002:a05:6870:55d1:b0:1fb:75b:2bb8 with SMTP id qk17-20020a05687055d100b001fb075b2bb8mr2639213oac.116.1701735999416; Mon, 04 Dec 2023 16:26:39 -0800 (PST) Received: from bob-3900x.lan (2603-8081-1405-679b-e463-fe8f-1aa8-6edb.res6.spectrum.com. [2603:8081:1405:679b:e463:fe8f:1aa8:6edb]) by smtp.gmail.com with ESMTPSA id se6-20020a05687122c600b001faf09f0899sm2524844oab.24.2023.12.04.16.26.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 Dec 2023 16:26:38 -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 v5 7/7] RDMA/rxe: Add module parameters for mcast limits Date: Mon, 4 Dec 2023 18:26:14 -0600 Message-Id: <20231205002613.10219-5-rpearsonhpe@gmail.com> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20231205002613.10219-1-rpearsonhpe@gmail.com> References: <20231205002613.10219-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,