All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next 0/3] enic: Check for DMA mapping error
@ 2014-12-24 10:29 Govindarajulu Varadarajan
  2014-12-24 10:29 ` [PATCH net-next 1/3] enic: make vnic_wq_buf doubly linked Govindarajulu Varadarajan
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Govindarajulu Varadarajan @ 2014-12-24 10:29 UTC (permalink / raw)
  To: davem, netdev, sassmann; +Cc: ssujith, benve, Govindarajulu Varadarajan

After dma mapping the buffers, enic does not call dma_mapping_error() to check
if mapping is successful.

This series fixes the issue by checking return value of pci_dma_mapping_error()
after pci_map_single().

This is reported by redhat here
https://bugzilla.redhat.com/show_bug.cgi?id=1145016

Govindarajulu Varadarajan (3):
  enic: make vnic_wq_buf doubly linked
  enic: check dma_mapping_error
  enic: add stats for dma mapping error

 drivers/net/ethernet/cisco/enic/enic.h         |  14 +++
 drivers/net/ethernet/cisco/enic/enic_ethtool.c |  19 +++-
 drivers/net/ethernet/cisco/enic/enic_main.c    | 152 +++++++++++++++----------
 drivers/net/ethernet/cisco/enic/vnic_stats.h   |   5 +
 drivers/net/ethernet/cisco/enic/vnic_wq.c      |   3 +
 drivers/net/ethernet/cisco/enic/vnic_wq.h      |   1 +
 6 files changed, 135 insertions(+), 59 deletions(-)

-- 
2.2.1

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH net-next 1/3] enic: make vnic_wq_buf doubly linked
  2014-12-24 10:29 [PATCH net-next 0/3] enic: Check for DMA mapping error Govindarajulu Varadarajan
@ 2014-12-24 10:29 ` Govindarajulu Varadarajan
  2015-01-05 17:30   ` David Laight
  2014-12-24 10:29 ` [PATCH net-next 2/3] enic: check dma_mapping_error Govindarajulu Varadarajan
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Govindarajulu Varadarajan @ 2014-12-24 10:29 UTC (permalink / raw)
  To: davem, netdev, sassmann; +Cc: ssujith, benve, Govindarajulu Varadarajan

This patch makes vnic_wq_buf doubly liked list. This is needed for dma_mapping
error check, in case some frag's dma map fails, we need to move back and remove
previously queued buffers.

Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
 drivers/net/ethernet/cisco/enic/vnic_wq.c | 3 +++
 drivers/net/ethernet/cisco/enic/vnic_wq.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c
index 3e6b8d5..b5a1c93 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_wq.c
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c
@@ -47,11 +47,14 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
 				wq->ring.desc_size * buf->index;
 			if (buf->index + 1 == count) {
 				buf->next = wq->bufs[0];
+				buf->next->prev = buf;
 				break;
 			} else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES(count)) {
 				buf->next = wq->bufs[i + 1];
+				buf->next->prev = buf;
 			} else {
 				buf->next = buf + 1;
+				buf->next->prev = buf;
 				buf++;
 			}
 		}
diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.h b/drivers/net/ethernet/cisco/enic/vnic_wq.h
index 816f1ad..2961543 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_wq.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_wq.h
@@ -62,6 +62,7 @@ struct vnic_wq_buf {
 	uint8_t cq_entry; /* Gets completion event from hw */
 	uint8_t desc_skip_cnt; /* Num descs to occupy */
 	uint8_t compressed_send; /* Both hdr and payload in one desc */
+	struct vnic_wq_buf *prev;
 };
 
 /* Break the vnic_wq_buf allocations into blocks of 32/64 entries */
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 2/3] enic: check dma_mapping_error
  2014-12-24 10:29 [PATCH net-next 0/3] enic: Check for DMA mapping error Govindarajulu Varadarajan
  2014-12-24 10:29 ` [PATCH net-next 1/3] enic: make vnic_wq_buf doubly linked Govindarajulu Varadarajan
@ 2014-12-24 10:29 ` Govindarajulu Varadarajan
  2015-01-05 17:28   ` David Laight
  2014-12-24 10:29 ` [PATCH net-next 3/3] enic: add stats for dma mapping error Govindarajulu Varadarajan
  2014-12-31 18:09 ` [PATCH net-next 0/3] enic: Check for DMA " David Miller
  3 siblings, 1 reply; 7+ messages in thread
From: Govindarajulu Varadarajan @ 2014-12-24 10:29 UTC (permalink / raw)
  To: davem, netdev, sassmann; +Cc: ssujith, benve, Govindarajulu Varadarajan

This patch checks for pci_dma_mapping_error() after dma mapping the data.
If the dma mapping fails we remove the previously queued frags and return
NETDEV_TX_OK.

Reported-by: Jan Stancek <jstancek@redhat.com>
Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
 drivers/net/ethernet/cisco/enic/enic.h      |  12 +++
 drivers/net/ethernet/cisco/enic/enic_main.c | 152 +++++++++++++++++-----------
 2 files changed, 106 insertions(+), 58 deletions(-)

diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index 25c4d88..b2ea35a 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -242,6 +242,18 @@ static inline unsigned int enic_msix_notify_intr(struct enic *enic)
 	return enic->rq_count + enic->wq_count + 1;
 }
 
+static inline int enic_dma_map_check(struct enic *enic, dma_addr_t dma_addr)
+{
+	if (unlikely(pci_dma_mapping_error(enic->pdev, dma_addr))) {
+		net_warn_ratelimited("%s: PCI dma mapping failed!\n",
+				     enic->netdev->name);
+
+		return -ENOMEM;
+	}
+
+	return 0;
+}
+
 void enic_reset_addr_lists(struct enic *enic);
 int enic_sriov_enabled(struct enic *enic);
 int enic_is_valid_vf(struct enic *enic, int vf);
diff --git a/drivers/net/ethernet/cisco/enic/enic_main.c b/drivers/net/ethernet/cisco/enic/enic_main.c
index 868d0f6..95c4804 100644
--- a/drivers/net/ethernet/cisco/enic/enic_main.c
+++ b/drivers/net/ethernet/cisco/enic/enic_main.c
@@ -351,80 +351,94 @@ static irqreturn_t enic_isr_msix_notify(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static inline void enic_queue_wq_skb_cont(struct enic *enic,
-	struct vnic_wq *wq, struct sk_buff *skb,
-	unsigned int len_left, int loopback)
+static int enic_queue_wq_skb_cont(struct enic *enic, struct vnic_wq *wq,
+				  struct sk_buff *skb, unsigned int len_left,
+				  int loopback)
 {
 	const skb_frag_t *frag;
+	dma_addr_t dma_addr;
 
 	/* Queue additional data fragments */
 	for (frag = skb_shinfo(skb)->frags; len_left; frag++) {
 		len_left -= skb_frag_size(frag);
-		enic_queue_wq_desc_cont(wq, skb,
-			skb_frag_dma_map(&enic->pdev->dev,
-					 frag, 0, skb_frag_size(frag),
-					 DMA_TO_DEVICE),
-			skb_frag_size(frag),
-			(len_left == 0),	/* EOP? */
-			loopback);
+		dma_addr = skb_frag_dma_map(&enic->pdev->dev, frag, 0,
+					    skb_frag_size(frag),
+					    DMA_TO_DEVICE);
+		if (unlikely(enic_dma_map_check(enic, dma_addr)))
+			return -ENOMEM;
+		enic_queue_wq_desc_cont(wq, skb, dma_addr, skb_frag_size(frag),
+					(len_left == 0),	/* EOP? */
+					loopback);
 	}
+
+	return 0;
 }
 
-static inline void enic_queue_wq_skb_vlan(struct enic *enic,
-	struct vnic_wq *wq, struct sk_buff *skb,
-	int vlan_tag_insert, unsigned int vlan_tag, int loopback)
+static int enic_queue_wq_skb_vlan(struct enic *enic, struct vnic_wq *wq,
+				  struct sk_buff *skb, int vlan_tag_insert,
+				  unsigned int vlan_tag, int loopback)
 {
 	unsigned int head_len = skb_headlen(skb);
 	unsigned int len_left = skb->len - head_len;
 	int eop = (len_left == 0);
+	dma_addr_t dma_addr;
+	int err = 0;
+
+	dma_addr = pci_map_single(enic->pdev, skb->data, head_len,
+				  PCI_DMA_TODEVICE);
+	if (unlikely(enic_dma_map_check(enic, dma_addr)))
+		return -ENOMEM;
 
 	/* Queue the main skb fragment. The fragments are no larger
 	 * than max MTU(9000)+ETH_HDR_LEN(14) bytes, which is less
 	 * than WQ_ENET_MAX_DESC_LEN length. So only one descriptor
 	 * per fragment is queued.
 	 */
-	enic_queue_wq_desc(wq, skb,
-		pci_map_single(enic->pdev, skb->data,
-			head_len, PCI_DMA_TODEVICE),
-		head_len,
-		vlan_tag_insert, vlan_tag,
-		eop, loopback);
+	enic_queue_wq_desc(wq, skb, dma_addr, head_len,	vlan_tag_insert,
+			   vlan_tag, eop, loopback);
 
 	if (!eop)
-		enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
+		err = enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
+
+	return err;
 }
 
-static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
-	struct vnic_wq *wq, struct sk_buff *skb,
-	int vlan_tag_insert, unsigned int vlan_tag, int loopback)
+static int enic_queue_wq_skb_csum_l4(struct enic *enic, struct vnic_wq *wq,
+				     struct sk_buff *skb, int vlan_tag_insert,
+				     unsigned int vlan_tag, int loopback)
 {
 	unsigned int head_len = skb_headlen(skb);
 	unsigned int len_left = skb->len - head_len;
 	unsigned int hdr_len = skb_checksum_start_offset(skb);
 	unsigned int csum_offset = hdr_len + skb->csum_offset;
 	int eop = (len_left == 0);
+	dma_addr_t dma_addr;
+	int err = 0;
+
+	dma_addr = pci_map_single(enic->pdev, skb->data, head_len,
+				  PCI_DMA_TODEVICE);
+	if (unlikely(enic_dma_map_check(enic, dma_addr)))
+		return -ENOMEM;
 
 	/* Queue the main skb fragment. The fragments are no larger
 	 * than max MTU(9000)+ETH_HDR_LEN(14) bytes, which is less
 	 * than WQ_ENET_MAX_DESC_LEN length. So only one descriptor
 	 * per fragment is queued.
 	 */
-	enic_queue_wq_desc_csum_l4(wq, skb,
-		pci_map_single(enic->pdev, skb->data,
-			head_len, PCI_DMA_TODEVICE),
-		head_len,
-		csum_offset,
-		hdr_len,
-		vlan_tag_insert, vlan_tag,
-		eop, loopback);
+	enic_queue_wq_desc_csum_l4(wq, skb, dma_addr, head_len,	csum_offset,
+				   hdr_len, vlan_tag_insert, vlan_tag, eop,
+				   loopback);
 
 	if (!eop)
-		enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
+		err = enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
+
+	return err;
 }
 
-static inline void enic_queue_wq_skb_tso(struct enic *enic,
-	struct vnic_wq *wq, struct sk_buff *skb, unsigned int mss,
-	int vlan_tag_insert, unsigned int vlan_tag, int loopback)
+static int enic_queue_wq_skb_tso(struct enic *enic, struct vnic_wq *wq,
+				 struct sk_buff *skb, unsigned int mss,
+				 int vlan_tag_insert, unsigned int vlan_tag,
+				 int loopback)
 {
 	unsigned int frag_len_left = skb_headlen(skb);
 	unsigned int len_left = skb->len - frag_len_left;
@@ -454,20 +468,19 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
 	 */
 	while (frag_len_left) {
 		len = min(frag_len_left, (unsigned int)WQ_ENET_MAX_DESC_LEN);
-		dma_addr = pci_map_single(enic->pdev, skb->data + offset,
-				len, PCI_DMA_TODEVICE);
-		enic_queue_wq_desc_tso(wq, skb,
-			dma_addr,
-			len,
-			mss, hdr_len,
-			vlan_tag_insert, vlan_tag,
-			eop && (len == frag_len_left), loopback);
+		dma_addr = pci_map_single(enic->pdev, skb->data + offset, len,
+					  PCI_DMA_TODEVICE);
+		if (unlikely(enic_dma_map_check(enic, dma_addr)))
+			return -ENOMEM;
+		enic_queue_wq_desc_tso(wq, skb, dma_addr, len, mss, hdr_len,
+				       vlan_tag_insert, vlan_tag,
+				       eop && (len == frag_len_left), loopback);
 		frag_len_left -= len;
 		offset += len;
 	}
 
 	if (eop)
-		return;
+		return 0;
 
 	/* Queue WQ_ENET_MAX_DESC_LEN length descriptors
 	 * for additional data fragments
@@ -483,16 +496,18 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
 			dma_addr = skb_frag_dma_map(&enic->pdev->dev, frag,
 						    offset, len,
 						    DMA_TO_DEVICE);
-			enic_queue_wq_desc_cont(wq, skb,
-				dma_addr,
-				len,
-				(len_left == 0) &&
-				(len == frag_len_left),		/* EOP? */
-				loopback);
+			if (unlikely(enic_dma_map_check(enic, dma_addr)))
+				return -ENOMEM;
+			enic_queue_wq_desc_cont(wq, skb, dma_addr, len,
+						(len_left == 0) &&
+						 (len == frag_len_left),/*EOP*/
+						loopback);
 			frag_len_left -= len;
 			offset += len;
 		}
 	}
+
+	return 0;
 }
 
 static inline void enic_queue_wq_skb(struct enic *enic,
@@ -502,6 +517,7 @@ static inline void enic_queue_wq_skb(struct enic *enic,
 	unsigned int vlan_tag = 0;
 	int vlan_tag_insert = 0;
 	int loopback = 0;
+	int err;
 
 	if (vlan_tx_tag_present(skb)) {
 		/* VLAN tag from trunking driver */
@@ -513,14 +529,30 @@ static inline void enic_queue_wq_skb(struct enic *enic,
 	}
 
 	if (mss)
-		enic_queue_wq_skb_tso(enic, wq, skb, mss,
-			vlan_tag_insert, vlan_tag, loopback);
+		err = enic_queue_wq_skb_tso(enic, wq, skb, mss,
+					    vlan_tag_insert, vlan_tag,
+					    loopback);
 	else if	(skb->ip_summed == CHECKSUM_PARTIAL)
-		enic_queue_wq_skb_csum_l4(enic, wq, skb,
-			vlan_tag_insert, vlan_tag, loopback);
+		err = enic_queue_wq_skb_csum_l4(enic, wq, skb, vlan_tag_insert,
+						vlan_tag, loopback);
 	else
-		enic_queue_wq_skb_vlan(enic, wq, skb,
-			vlan_tag_insert, vlan_tag, loopback);
+		err = enic_queue_wq_skb_vlan(enic, wq, skb, vlan_tag_insert,
+					     vlan_tag, loopback);
+	if (unlikely(err)) {
+		struct vnic_wq_buf *buf;
+
+		buf = wq->to_use->prev;
+		/* while not EOP of previous pkt && queue not empty.
+		 * For all non EOP bufs, os_buf is NULL.
+		 */
+		while (!buf->os_buf && (buf->next != wq->to_clean)) {
+			enic_free_wq_buf(wq, buf);
+			wq->ring.desc_avail++;
+			buf = buf->prev;
+		}
+		wq->to_use = buf->next;
+		dev_kfree_skb(skb);
+	}
 }
 
 /* netif_tx_lock held, process context with BHs disabled, or BH */
@@ -950,8 +982,12 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
 	if (!skb)
 		return -ENOMEM;
 
-	dma_addr = pci_map_single(enic->pdev, skb->data,
-		len, PCI_DMA_FROMDEVICE);
+	dma_addr = pci_map_single(enic->pdev, skb->data, len,
+				  PCI_DMA_FROMDEVICE);
+	if (unlikely(enic_dma_map_check(enic, dma_addr))) {
+		dev_kfree_skb(skb);
+		return -ENOMEM;
+	}
 
 	enic_queue_rq_desc(rq, skb, os_buf_index,
 		dma_addr, len);
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH net-next 3/3] enic: add stats for dma mapping error
  2014-12-24 10:29 [PATCH net-next 0/3] enic: Check for DMA mapping error Govindarajulu Varadarajan
  2014-12-24 10:29 ` [PATCH net-next 1/3] enic: make vnic_wq_buf doubly linked Govindarajulu Varadarajan
  2014-12-24 10:29 ` [PATCH net-next 2/3] enic: check dma_mapping_error Govindarajulu Varadarajan
@ 2014-12-24 10:29 ` Govindarajulu Varadarajan
  2014-12-31 18:09 ` [PATCH net-next 0/3] enic: Check for DMA " David Miller
  3 siblings, 0 replies; 7+ messages in thread
From: Govindarajulu Varadarajan @ 2014-12-24 10:29 UTC (permalink / raw)
  To: davem, netdev, sassmann; +Cc: ssujith, benve, Govindarajulu Varadarajan

This patch adds generic statistics for enic. As of now dma_map_error is the only
member. dma_map_erro is incremented every time dma maping error happens.

Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
---
 drivers/net/ethernet/cisco/enic/enic.h         |  2 ++
 drivers/net/ethernet/cisco/enic/enic_ethtool.c | 19 ++++++++++++++++++-
 drivers/net/ethernet/cisco/enic/vnic_stats.h   |  5 +++++
 3 files changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/cisco/enic/enic.h b/drivers/net/ethernet/cisco/enic/enic.h
index b2ea35a..d2a1035 100644
--- a/drivers/net/ethernet/cisco/enic/enic.h
+++ b/drivers/net/ethernet/cisco/enic/enic.h
@@ -188,6 +188,7 @@ struct enic {
 	struct enic_rfs_flw_tbl rfs_h;
 	u32 rx_copybreak;
 	u8 rss_key[ENIC_RSS_LEN];
+	struct vnic_gen_stats gen_stats;
 };
 
 static inline struct device *enic_get_dev(struct enic *enic)
@@ -247,6 +248,7 @@ static inline int enic_dma_map_check(struct enic *enic, dma_addr_t dma_addr)
 	if (unlikely(pci_dma_mapping_error(enic->pdev, dma_addr))) {
 		net_warn_ratelimited("%s: PCI dma mapping failed!\n",
 				     enic->netdev->name);
+		enic->gen_stats.dma_map_error++;
 
 		return -ENOMEM;
 	}
diff --git a/drivers/net/ethernet/cisco/enic/enic_ethtool.c b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
index eba1eb8..0c396c1 100644
--- a/drivers/net/ethernet/cisco/enic/enic_ethtool.c
+++ b/drivers/net/ethernet/cisco/enic/enic_ethtool.c
@@ -24,6 +24,7 @@
 #include "enic_dev.h"
 #include "enic_clsf.h"
 #include "vnic_rss.h"
+#include "vnic_stats.h"
 
 struct enic_stat {
 	char name[ETH_GSTRING_LEN];
@@ -40,6 +41,11 @@ struct enic_stat {
 	.index = offsetof(struct vnic_rx_stats, stat) / sizeof(u64) \
 }
 
+#define ENIC_GEN_STAT(stat) { \
+	.name = #stat, \
+	.index = offsetof(struct vnic_gen_stats, stat) / sizeof(u64)\
+}
+
 static const struct enic_stat enic_tx_stats[] = {
 	ENIC_TX_STAT(tx_frames_ok),
 	ENIC_TX_STAT(tx_unicast_frames_ok),
@@ -78,8 +84,13 @@ static const struct enic_stat enic_rx_stats[] = {
 	ENIC_RX_STAT(rx_frames_to_max),
 };
 
+static const struct enic_stat enic_gen_stats[] = {
+	ENIC_GEN_STAT(dma_map_error),
+};
+
 static const unsigned int enic_n_tx_stats = ARRAY_SIZE(enic_tx_stats);
 static const unsigned int enic_n_rx_stats = ARRAY_SIZE(enic_rx_stats);
+static const unsigned int enic_n_gen_stats = ARRAY_SIZE(enic_gen_stats);
 
 void enic_intr_coal_set_rx(struct enic *enic, u32 timer)
 {
@@ -146,6 +157,10 @@ static void enic_get_strings(struct net_device *netdev, u32 stringset,
 			memcpy(data, enic_rx_stats[i].name, ETH_GSTRING_LEN);
 			data += ETH_GSTRING_LEN;
 		}
+		for (i = 0; i < enic_n_gen_stats; i++) {
+			memcpy(data, enic_gen_stats[i].name, ETH_GSTRING_LEN);
+			data += ETH_GSTRING_LEN;
+		}
 		break;
 	}
 }
@@ -154,7 +169,7 @@ static int enic_get_sset_count(struct net_device *netdev, int sset)
 {
 	switch (sset) {
 	case ETH_SS_STATS:
-		return enic_n_tx_stats + enic_n_rx_stats;
+		return enic_n_tx_stats + enic_n_rx_stats + enic_n_gen_stats;
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -173,6 +188,8 @@ static void enic_get_ethtool_stats(struct net_device *netdev,
 		*(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].index];
 	for (i = 0; i < enic_n_rx_stats; i++)
 		*(data++) = ((u64 *)&vstats->rx)[enic_rx_stats[i].index];
+	for (i = 0; i < enic_n_gen_stats; i++)
+		*(data++) = ((u64 *)&enic->gen_stats)[enic_gen_stats[i].index];
 }
 
 static u32 enic_get_msglevel(struct net_device *netdev)
diff --git a/drivers/net/ethernet/cisco/enic/vnic_stats.h b/drivers/net/ethernet/cisco/enic/vnic_stats.h
index 77750ec..74c81ed 100644
--- a/drivers/net/ethernet/cisco/enic/vnic_stats.h
+++ b/drivers/net/ethernet/cisco/enic/vnic_stats.h
@@ -62,6 +62,11 @@ struct vnic_rx_stats {
 	u64 rsvd[16];
 };
 
+/* Generic statistics */
+struct vnic_gen_stats {
+	u64 dma_map_error;
+};
+
 struct vnic_stats {
 	struct vnic_tx_stats tx;
 	struct vnic_rx_stats rx;
-- 
2.2.1

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next 0/3] enic: Check for DMA mapping error
  2014-12-24 10:29 [PATCH net-next 0/3] enic: Check for DMA mapping error Govindarajulu Varadarajan
                   ` (2 preceding siblings ...)
  2014-12-24 10:29 ` [PATCH net-next 3/3] enic: add stats for dma mapping error Govindarajulu Varadarajan
@ 2014-12-31 18:09 ` David Miller
  3 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2014-12-31 18:09 UTC (permalink / raw)
  To: _govind; +Cc: netdev, sassmann, ssujith, benve

From: Govindarajulu Varadarajan <_govind@gmx.com>
Date: Wed, 24 Dec 2014 15:59:35 +0530

> After dma mapping the buffers, enic does not call dma_mapping_error() to check
> if mapping is successful.
> 
> This series fixes the issue by checking return value of pci_dma_mapping_error()
> after pci_map_single().
> 
> This is reported by redhat here
> https://bugzilla.redhat.com/show_bug.cgi?id=1145016

Series applied, thank you.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH net-next 2/3] enic: check dma_mapping_error
  2014-12-24 10:29 ` [PATCH net-next 2/3] enic: check dma_mapping_error Govindarajulu Varadarajan
@ 2015-01-05 17:28   ` David Laight
  0 siblings, 0 replies; 7+ messages in thread
From: David Laight @ 2015-01-05 17:28 UTC (permalink / raw)
  To: 'Govindarajulu Varadarajan', davem, netdev, sassmann
  Cc: ssujith, benve

> This patch checks for pci_dma_mapping_error() after dma mapping the data.
> If the dma mapping fails we remove the previously queued frags and return
> NETDEV_TX_OK.

This patch contains a lot of whitespace changes that make it
very difficult to review.

Split the patch.

	David

^ permalink raw reply	[flat|nested] 7+ messages in thread

* RE: [PATCH net-next 1/3] enic: make vnic_wq_buf doubly linked
  2014-12-24 10:29 ` [PATCH net-next 1/3] enic: make vnic_wq_buf doubly linked Govindarajulu Varadarajan
@ 2015-01-05 17:30   ` David Laight
  0 siblings, 0 replies; 7+ messages in thread
From: David Laight @ 2015-01-05 17:30 UTC (permalink / raw)
  To: 'Govindarajulu Varadarajan', davem, netdev, sassmann
  Cc: ssujith, benve

> This patch makes vnic_wq_buf doubly liked list. This is needed for dma_mapping
> error check, in case some frag's dma map fails, we need to move back and remove
> previously queued buffers.

I can't see any code that keeps the back-pointers valid when items are removed.
Maybe they aren't needed, but I'd like to be convinced.

If errors are really unlikely, and the list likely to be short,
then just traverse the entire list forwards in the error path.

	David

> 
> Signed-off-by: Govindarajulu Varadarajan <_govind@gmx.com>
> ---
>  drivers/net/ethernet/cisco/enic/vnic_wq.c | 3 +++
>  drivers/net/ethernet/cisco/enic/vnic_wq.h | 1 +
>  2 files changed, 4 insertions(+)
> 
> diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.c b/drivers/net/ethernet/cisco/enic/vnic_wq.c
> index 3e6b8d5..b5a1c93 100644
> --- a/drivers/net/ethernet/cisco/enic/vnic_wq.c
> +++ b/drivers/net/ethernet/cisco/enic/vnic_wq.c
> @@ -47,11 +47,14 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
>  				wq->ring.desc_size * buf->index;
>  			if (buf->index + 1 == count) {
>  				buf->next = wq->bufs[0];
> +				buf->next->prev = buf;
>  				break;
>  			} else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES(count)) {
>  				buf->next = wq->bufs[i + 1];
> +				buf->next->prev = buf;
>  			} else {
>  				buf->next = buf + 1;
> +				buf->next->prev = buf;
>  				buf++;
>  			}
>  		}
> diff --git a/drivers/net/ethernet/cisco/enic/vnic_wq.h b/drivers/net/ethernet/cisco/enic/vnic_wq.h
> index 816f1ad..2961543 100644
> --- a/drivers/net/ethernet/cisco/enic/vnic_wq.h
> +++ b/drivers/net/ethernet/cisco/enic/vnic_wq.h
> @@ -62,6 +62,7 @@ struct vnic_wq_buf {
>  	uint8_t cq_entry; /* Gets completion event from hw */
>  	uint8_t desc_skip_cnt; /* Num descs to occupy */
>  	uint8_t compressed_send; /* Both hdr and payload in one desc */
> +	struct vnic_wq_buf *prev;
>  };
> 
>  /* Break the vnic_wq_buf allocations into blocks of 32/64 entries */
> --
> 2.2.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-01-05 17:40 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-12-24 10:29 [PATCH net-next 0/3] enic: Check for DMA mapping error Govindarajulu Varadarajan
2014-12-24 10:29 ` [PATCH net-next 1/3] enic: make vnic_wq_buf doubly linked Govindarajulu Varadarajan
2015-01-05 17:30   ` David Laight
2014-12-24 10:29 ` [PATCH net-next 2/3] enic: check dma_mapping_error Govindarajulu Varadarajan
2015-01-05 17:28   ` David Laight
2014-12-24 10:29 ` [PATCH net-next 3/3] enic: add stats for dma mapping error Govindarajulu Varadarajan
2014-12-31 18:09 ` [PATCH net-next 0/3] enic: Check for DMA " David Miller

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.