[ewg] [PATCH] RDMA/nes: Fixes for PAU handling

Tatyana Nikolova Tatyana.E.Nikolova at intel.com
Sat Oct 20 15:51:40 PDT 2012


Fixes for packed and unaligned fpdu handling

Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
---
 .../0007-RDMA-nes-Fix-for-pau-hdr_pbase.patch      |   23 +++++++
 .../0008-RDMA-nes-Check-for-empty-skb-list.patch   |   51 ++++++++++++++++
 .../0009-RDMA-nes-Fix-for-unlinking-NULL-skb.patch |   62 ++++++++++++++++++++
 3 files changed, 136 insertions(+), 0 deletions(-)
 create mode 100644 linux-next-pending/0007-RDMA-nes-Fix-for-pau-hdr_pbase.patch
 create mode 100644 linux-next-pending/0008-RDMA-nes-Check-for-empty-skb-list.patch
 create mode 100644 linux-next-pending/0009-RDMA-nes-Fix-for-unlinking-NULL-skb.patch

diff --git a/linux-next-pending/0007-RDMA-nes-Fix-for-pau-hdr_pbase.patch b/linux-next-pending/0007-RDMA-nes-Fix-for-pau-hdr_pbase.patch
new file mode 100644
index 0000000..706deff
--- /dev/null
+++ b/linux-next-pending/0007-RDMA-nes-Fix-for-pau-hdr_pbase.patch
@@ -0,0 +1,23 @@
+Fix for incorrect hdr_pbase when forwarding fpdus to hardware 
+
+Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+---
+ drivers/infiniband/hw/nes/nes_mgt.c |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/infiniband/hw/nes/nes_mgt.c b/drivers/infiniband/hw/nes/nes_mgt.c
+index 3ba7be3..8cf74fd 100644
+--- a/drivers/infiniband/hw/nes/nes_mgt.c
++++ b/drivers/infiniband/hw/nes/nes_mgt.c
+@@ -447,7 +447,7 @@ static int forward_fpdus(struct nes_vnic *nesvnic, struct nes_qp *nesqp)
+ 		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_LOW_IDX,
+ 				    lower_32_bits(u64tmp));
+ 		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG0_HIGH_IDX,
+-				    upper_32_bits(u64tmp >> 32));
++				    upper_32_bits(u64tmp));
+ 
+ 		set_wqe_32bit_value(cqp_wqe->wqe_words, NES_NIC_SQ_WQE_FRAG1_LOW_IDX,
+ 				    lower_32_bits(fpdu_info->frags[0].physaddr));
+-- 
+1.7.4.2
+
diff --git a/linux-next-pending/0008-RDMA-nes-Check-for-empty-skb-list.patch b/linux-next-pending/0008-RDMA-nes-Check-for-empty-skb-list.patch
new file mode 100644
index 0000000..d42b67a
--- /dev/null
+++ b/linux-next-pending/0008-RDMA-nes-Check-for-empty-skb-list.patch
@@ -0,0 +1,51 @@
+Fix for unlinking skbs from empty list
+
+Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+---
+ drivers/infiniband/hw/nes/nes_mgt.c |   11 +++++++----
+ 1 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/nes/nes_mgt.c b/drivers/infiniband/hw/nes/nes_mgt.c
+index 8cf74fd..2d710e1 100644
+--- a/drivers/infiniband/hw/nes/nes_mgt.c
++++ b/drivers/infiniband/hw/nes/nes_mgt.c
+@@ -210,6 +210,9 @@ static struct sk_buff *nes_get_next_skb(struct nes_device *nesdev, struct nes_qp
+ 	}
+ 
+ 	while (1) {
++		if (skb_queue_empty(&nesqp->pau_list))
++			goto out;
++
+ 		seq = nes_get_seq(skb, ack, wnd, fin_rcvd, rst_rcvd);
+ 		if (seq == nextseq) {
+ 			if (skb->len || processacks)
+@@ -218,14 +221,13 @@ static struct sk_buff *nes_get_next_skb(struct nes_device *nesdev, struct nes_qp
+ 			goto out;
+ 		}
+ 
+-		if (skb->next == (struct sk_buff *)&nesqp->pau_list)
+-			goto out;
+-
+ 		old_skb = skb;
+ 		skb = skb->next;
+ 		skb_unlink(old_skb, &nesqp->pau_list);
+ 		nes_mgt_free_skb(nesdev, old_skb, PCI_DMA_TODEVICE);
+ 		nes_rem_ref_cm_node(nesqp->cm_node);
++		if (skb == (struct sk_buff *)&nesqp->pau_list)
++			goto out;
+ 	}
+ 	return skb;
+ 
+@@ -384,7 +386,8 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
+ 		if (frags[i].skb->len == 0) {
+ 			/* Pull skb off the list - it will be freed in the callback */
+ 			spin_lock_irqsave(&nesqp->pau_lock, flags);
+-			skb_unlink(frags[i].skb, &nesqp->pau_list);
++			if (!skb_queue_empty(&nesqp->pau_list))
++				skb_unlink(frags[i].skb, &nesqp->pau_list);
+ 			spin_unlock_irqrestore(&nesqp->pau_lock, flags);
+ 		} else {
+ 			/* Last skb still has data so update the seq */
+-- 
+1.7.4.2
+
diff --git a/linux-next-pending/0009-RDMA-nes-Fix-for-unlinking-NULL-skb.patch b/linux-next-pending/0009-RDMA-nes-Fix-for-unlinking-NULL-skb.patch
new file mode 100644
index 0000000..f2250fd
--- /dev/null
+++ b/linux-next-pending/0009-RDMA-nes-Fix-for-unlinking-NULL-skb.patch
@@ -0,0 +1,62 @@
+Fix for unlinking NULL skb because of race condition
+
+Signed-off-by: Tatyana Nikolova <Tatyana.E.Nikolova at intel.com>
+---
+ drivers/infiniband/hw/nes/nes_mgt.c |    8 ++++----
+ 1 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/hw/nes/nes_mgt.c b/drivers/infiniband/hw/nes/nes_mgt.c
+index 2d710e1..9d0fd2b 100644
+--- a/drivers/infiniband/hw/nes/nes_mgt.c
++++ b/drivers/infiniband/hw/nes/nes_mgt.c
+@@ -322,11 +322,10 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
+ 		frag_cnt = 1;
+ 	}
+ 
+-	spin_unlock_irqrestore(&nesqp->pau_lock, flags);
+-
+ 	/* Found one */
+ 	fpdu_info = kzalloc(sizeof(*fpdu_info), GFP_ATOMIC);
+ 	if (fpdu_info == NULL) {
++		spin_unlock_irqrestore(&nesqp->pau_lock, flags);
+ 		nes_debug(NES_DBG_PAU, "Failed to alloc a fpdu_info.\n");
+ 		rc = -ENOMEM;
+ 		goto out;
+@@ -334,6 +333,7 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
+ 
+ 	fpdu_info->cqp_request = nes_get_cqp_request(nesdev);
+ 	if (fpdu_info->cqp_request == NULL) {
++		spin_unlock_irqrestore(&nesqp->pau_lock, flags);
+ 		nes_debug(NES_DBG_PAU, "Failed to get a cqp_request.\n");
+ 		rc = -ENOMEM;
+ 		goto out;
+@@ -353,6 +353,7 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
+ 		fpdu_info->hdr_vbase = pci_alloc_consistent(nesdev->pcidev,
+ 							    fpdu_info->hdr_len, &fpdu_info->hdr_pbase);
+ 		if (!fpdu_info->hdr_vbase) {
++			spin_unlock_irqrestore(&nesqp->pau_lock, flags);
+ 			nes_debug(NES_DBG_PAU, "Unable to allocate memory for pau first frag\n");
+ 			rc = -ENOMEM;
+ 			goto out;
+@@ -385,10 +386,8 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
+ 
+ 		if (frags[i].skb->len == 0) {
+ 			/* Pull skb off the list - it will be freed in the callback */
+-			spin_lock_irqsave(&nesqp->pau_lock, flags);
+ 			if (!skb_queue_empty(&nesqp->pau_list))
+ 				skb_unlink(frags[i].skb, &nesqp->pau_list);
+-			spin_unlock_irqrestore(&nesqp->pau_lock, flags);
+ 		} else {
+ 			/* Last skb still has data so update the seq */
+ 			iph = (struct iphdr *)(cb->data_start + ETH_HLEN);
+@@ -396,6 +395,7 @@ static int get_fpdu_info(struct nes_device *nesdev, struct nes_qp *nesqp,
+ 			tcph->seq = cpu_to_be32(nesqp->pau_rcv_nxt);
+ 		}
+ 	}
++	spin_unlock_irqrestore(&nesqp->pau_lock, flags);
+ 
+ out:
+ 	if (rc) {
+-- 
+1.7.4.2
+
-- 
1.7.1




More information about the ewg mailing list