From: Bob Pearson <rpearsonhpe@gmail.com>
To: jgg@nvidia.com, zyjzyj2000@gmail.com, linux-rdma@vger.kernel.org
Cc: Bob Pearson <rpearsonhpe@gmail.com>
Subject: [PATCH for-next 01/13] RDMA/rxe: Decouple rxe_pkt_info from sk_buff
Date: Thu, 29 Jul 2021 17:49:04 -0500 [thread overview]
Message-ID: <20210729224915.38986-2-rpearsonhpe@gmail.com> (raw)
In-Reply-To: <20210729224915.38986-1-rpearsonhpe@gmail.com>
Currently on the receive path the rxe_pkt_info struct is stored in the
skb->cb array. But this patch series requires extending it beyond 48 bytes
and it is already at the limit. This patch places a pointer to the
pkt info struct in skb->cb and allocates it separately. All instances of
freeing the skb on the receive path are collected into rxe_free_pkt() calls
which is extended to free the pkt info struct. In rxe_rcv_mcast_pkt()
if skb_clone fails continue is replaced by break since we are out of
memory and there is no point going on to the other mcast QPs.
Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
---
drivers/infiniband/sw/rxe/rxe_comp.c | 20 +++-------------
drivers/infiniband/sw/rxe/rxe_hdr.h | 13 ++++++++---
drivers/infiniband/sw/rxe/rxe_loc.h | 3 +++
drivers/infiniband/sw/rxe/rxe_net.c | 14 +++++++++--
drivers/infiniband/sw/rxe/rxe_recv.c | 35 +++++++++++++++++++++-------
drivers/infiniband/sw/rxe/rxe_resp.c | 18 ++++----------
6 files changed, 59 insertions(+), 44 deletions(-)
diff --git a/drivers/infiniband/sw/rxe/rxe_comp.c b/drivers/infiniband/sw/rxe/rxe_comp.c
index 1ccd2deff835..4d62e5bdf820 100644
--- a/drivers/infiniband/sw/rxe/rxe_comp.c
+++ b/drivers/infiniband/sw/rxe/rxe_comp.c
@@ -522,11 +522,8 @@ static void rxe_drain_resp_pkts(struct rxe_qp *qp, bool notify)
struct rxe_send_wqe *wqe;
struct rxe_queue *q = qp->sq.queue;
- while ((skb = skb_dequeue(&qp->resp_pkts))) {
- rxe_drop_ref(qp);
- kfree_skb(skb);
- ib_device_put(qp->ibqp.device);
- }
+ while ((skb = skb_dequeue(&qp->resp_pkts)))
+ rxe_free_pkt(SKB_TO_PKT(skb));
while ((wqe = queue_head(q, q->type))) {
if (notify) {
@@ -538,17 +535,6 @@ static void rxe_drain_resp_pkts(struct rxe_qp *qp, bool notify)
}
}
-static void free_pkt(struct rxe_pkt_info *pkt)
-{
- struct sk_buff *skb = PKT_TO_SKB(pkt);
- struct rxe_qp *qp = pkt->qp;
- struct ib_device *dev = qp->ibqp.device;
-
- kfree_skb(skb);
- rxe_drop_ref(qp);
- ib_device_put(dev);
-}
-
int rxe_completer(void *arg)
{
struct rxe_qp *qp = (struct rxe_qp *)arg;
@@ -757,7 +743,7 @@ int rxe_completer(void *arg)
done:
if (pkt)
- free_pkt(pkt);
+ rxe_free_pkt(pkt);
rxe_drop_ref(qp);
return ret;
diff --git a/drivers/infiniband/sw/rxe/rxe_hdr.h b/drivers/infiniband/sw/rxe/rxe_hdr.h
index e432f9e37795..d9d15c672f86 100644
--- a/drivers/infiniband/sw/rxe/rxe_hdr.h
+++ b/drivers/infiniband/sw/rxe/rxe_hdr.h
@@ -12,6 +12,7 @@
* sk_buff for received packets.
*/
struct rxe_pkt_info {
+ struct sk_buff *skb; /* back pointer to skb */
struct rxe_dev *rxe; /* device that owns packet */
struct rxe_qp *qp; /* qp that owns packet */
struct rxe_send_wqe *wqe; /* send wqe */
@@ -24,16 +25,22 @@ struct rxe_pkt_info {
u8 opcode; /* bth opcode of packet */
};
+/* rxe info in skb->cb */
+struct rxe_cb {
+ struct rxe_pkt_info *pkt; /* pointer to pkt info */
+};
+
+#define RXE_CB(skb) ((struct rxe_cb *)skb->cb)
+
/* Macros should be used only for received skb */
static inline struct rxe_pkt_info *SKB_TO_PKT(struct sk_buff *skb)
{
- BUILD_BUG_ON(sizeof(struct rxe_pkt_info) > sizeof(skb->cb));
- return (void *)skb->cb;
+ return RXE_CB(skb)->pkt;
}
static inline struct sk_buff *PKT_TO_SKB(struct rxe_pkt_info *pkt)
{
- return container_of((void *)pkt, struct sk_buff, cb);
+ return pkt->skb;
}
/*
diff --git a/drivers/infiniband/sw/rxe/rxe_loc.h b/drivers/infiniband/sw/rxe/rxe_loc.h
index de75413fb4d9..b4d45c592bd7 100644
--- a/drivers/infiniband/sw/rxe/rxe_loc.h
+++ b/drivers/infiniband/sw/rxe/rxe_loc.h
@@ -139,6 +139,9 @@ static inline int qp_mtu(struct rxe_qp *qp)
return IB_MTU_4096;
}
+/* rxe_recv.c */
+void rxe_free_pkt(struct rxe_pkt_info *pkt);
+
static inline int rcv_wqe_size(int max_sge)
{
return sizeof(struct rxe_recv_wqe) +
diff --git a/drivers/infiniband/sw/rxe/rxe_net.c b/drivers/infiniband/sw/rxe/rxe_net.c
index 4f96437a2a8e..6212e61d267b 100644
--- a/drivers/infiniband/sw/rxe/rxe_net.c
+++ b/drivers/infiniband/sw/rxe/rxe_net.c
@@ -155,7 +155,7 @@ static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
struct udphdr *udph;
struct rxe_dev *rxe;
struct net_device *ndev = skb->dev;
- struct rxe_pkt_info *pkt = SKB_TO_PKT(skb);
+ struct rxe_pkt_info *pkt;
/* takes a reference on rxe->ib_dev
* drop when skb is freed
@@ -172,6 +172,10 @@ static int rxe_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto drop;
}
+ pkt = kzalloc(sizeof(*pkt), GFP_ATOMIC);
+ RXE_CB(skb)->pkt = pkt;
+ pkt->skb = skb;
+
udph = udp_hdr(skb);
pkt->rxe = rxe;
pkt->port_num = 1;
@@ -407,15 +411,21 @@ static int rxe_send(struct sk_buff *skb, struct rxe_pkt_info *pkt)
*/
static int rxe_loopback(struct sk_buff *skb, struct rxe_pkt_info *pkt)
{
- memcpy(SKB_TO_PKT(skb), pkt, sizeof(*pkt));
+ struct rxe_pkt_info *new_pkt;
if (skb->protocol == htons(ETH_P_IP))
skb_pull(skb, sizeof(struct iphdr));
else
skb_pull(skb, sizeof(struct ipv6hdr));
+ new_pkt = kzalloc(sizeof(*new_pkt), GFP_ATOMIC);
+ memcpy(new_pkt, pkt, sizeof(*pkt));
+ RXE_CB(skb)->pkt = new_pkt;
+ new_pkt->skb = skb;
+
if (WARN_ON(!ib_device_try_get(&pkt->rxe->ib_dev))) {
kfree_skb(skb);
+ kfree(new_pkt);
return -EIO;
}
diff --git a/drivers/infiniband/sw/rxe/rxe_recv.c b/drivers/infiniband/sw/rxe/rxe_recv.c
index 8ed4f3bcc779..cf5ac6bba59c 100644
--- a/drivers/infiniband/sw/rxe/rxe_recv.c
+++ b/drivers/infiniband/sw/rxe/rxe_recv.c
@@ -9,6 +9,20 @@
#include "rxe.h"
#include "rxe_loc.h"
+void rxe_free_pkt(struct rxe_pkt_info *pkt)
+{
+ struct sk_buff *skb = PKT_TO_SKB(pkt);
+ struct rxe_qp *qp = pkt->qp;
+
+ if (qp)
+ rxe_drop_ref(qp);
+
+ ib_device_put(&pkt->rxe->ib_dev);
+
+ kfree_skb(skb);
+ kfree(pkt);
+}
+
/* check that QP matches packet opcode type and is in a valid state */
static int check_type_state(struct rxe_dev *rxe, struct rxe_pkt_info *pkt,
struct rxe_qp *qp)
@@ -279,14 +293,22 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
cskb = skb_clone(skb, GFP_ATOMIC);
if (unlikely(!cskb))
- continue;
+ break;
+
+ cpkt = kzalloc(sizeof(*cpkt), GFP_ATOMIC);
+ if (unlikely(!cpkt)) {
+ kfree_skb(cskb);
+ break;
+ }
+ RXE_CB(cskb)->pkt = cpkt;
+ cpkt->skb = cskb;
if (WARN_ON(!ib_device_try_get(&rxe->ib_dev))) {
kfree_skb(cskb);
+ kfree(cpkt);
break;
}
- cpkt = SKB_TO_PKT(cskb);
cpkt->qp = qp;
rxe_add_ref(qp);
rxe_rcv_pkt(cpkt, cskb);
@@ -310,8 +332,7 @@ static void rxe_rcv_mcast_pkt(struct rxe_dev *rxe, struct sk_buff *skb)
*/
drop:
- kfree_skb(skb);
- ib_device_put(&rxe->ib_dev);
+ rxe_free_pkt(SKB_TO_PKT(skb));
}
/**
@@ -396,9 +417,5 @@ void rxe_rcv(struct sk_buff *skb)
return;
drop:
- if (pkt->qp)
- rxe_drop_ref(pkt->qp);
-
- kfree_skb(skb);
- ib_device_put(&rxe->ib_dev);
+ rxe_free_pkt(pkt);
}
diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index c6a6257a299f..ac8d823eb416 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -98,11 +98,8 @@ static inline enum resp_states get_req(struct rxe_qp *qp,
struct sk_buff *skb;
if (qp->resp.state == QP_STATE_ERROR) {
- while ((skb = skb_dequeue(&qp->req_pkts))) {
- rxe_drop_ref(qp);
- kfree_skb(skb);
- ib_device_put(qp->ibqp.device);
- }
+ while ((skb = skb_dequeue(&qp->req_pkts)))
+ rxe_free_pkt(SKB_TO_PKT(skb));
/* go drain recv wr queue */
return RESPST_CHK_RESOURCE;
@@ -1020,9 +1017,7 @@ static enum resp_states cleanup(struct rxe_qp *qp,
if (pkt) {
skb = skb_dequeue(&qp->req_pkts);
- rxe_drop_ref(qp);
- kfree_skb(skb);
- ib_device_put(qp->ibqp.device);
+ rxe_free_pkt(SKB_TO_PKT(skb));
}
if (qp->resp.mr) {
@@ -1183,11 +1178,8 @@ static void rxe_drain_req_pkts(struct rxe_qp *qp, bool notify)
struct sk_buff *skb;
struct rxe_queue *q = qp->rq.queue;
- while ((skb = skb_dequeue(&qp->req_pkts))) {
- rxe_drop_ref(qp);
- kfree_skb(skb);
- ib_device_put(qp->ibqp.device);
- }
+ while ((skb = skb_dequeue(&qp->req_pkts)))
+ rxe_free_pkt(SKB_TO_PKT(skb));
if (notify)
return;
--
2.30.2
next prev parent reply other threads:[~2021-07-29 22:50 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-07-29 22:49 [PATCH for-next 00/13] RDMA:rxe: Implement XRC for rxe Bob Pearson
2021-07-29 22:49 ` Bob Pearson [this message]
2021-08-27 13:01 ` [PATCH for-next 01/13] RDMA/rxe: Decouple rxe_pkt_info from sk_buff Jason Gunthorpe
2021-07-29 22:49 ` [PATCH for-next 02/13] IB/core: Add xrc opcodes to ib_pack.h Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 03/13] RDMA/rxe: Extend rxe_send_wr to support xrceth Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 04/13] RDMA/rxe: Extend rxe_opcode.h to support xrc Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 05/13] RDMA/rxe: Add XRC ETH to rxe_hdr.h Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 06/13] RDMA/rxe: Add XRC QP type to rxe_wr_opcode_info Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 07/13] RDMA/rxe: Add XRC opcodes to rxe_opcode_info Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 08/13] RDMA/rxe: Support alloc/dealloc xrcd Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 09/13] RDMA/rxe: Extend SRQs to support extensions Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 10/13] RDMA/rxe: Compute next opcode for XRC Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 11/13] RDMA/rxe: Extend rxe_verbs and rxe_qp to support XRC Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 12/13] RDMA/rxe: Extend rxe send XRC packets Bob Pearson
2021-07-29 22:49 ` [PATCH for-next 13/13] RDMA/rxe: Enable receiving " Bob Pearson
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210729224915.38986-2-rpearsonhpe@gmail.com \
--to=rpearsonhpe@gmail.com \
--cc=jgg@nvidia.com \
--cc=linux-rdma@vger.kernel.org \
--cc=zyjzyj2000@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.