[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