All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, gospo@redhat.com,
	Alexander Duyck <alexander.h.duyck@intel.com>,
	Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>,
	Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>,
	Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Subject: [PATCH 6/9] ixgbe: refactor tx buffer processing to use skb_dma_map/unmap
Date: Wed, 01 Apr 2009 00:34:23 -0700	[thread overview]
Message-ID: <20090401073423.3749.21206.stgit@lost.foo-projects.org> (raw)
In-Reply-To: <20090401073241.3749.36391.stgit@lost.foo-projects.org>

From: Alexander Duyck <alexander.h.duyck@intel.com>

This patch resolves an issue with map single being used to map a buffer and
then unmap page being used to unmap it.  In addition it handles any error
conditions that may be detected using skb_dma_map.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Acked-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala@intel.com>
Acked-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---

 drivers/net/ixgbe/ixgbe_main.c |   79 +++++++++++++++++++++-------------------
 1 files changed, 41 insertions(+), 38 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 63c0f19..f36cff5 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -187,15 +187,14 @@ static void ixgbe_unmap_and_free_tx_resource(struct ixgbe_adapter *adapter,
                                              struct ixgbe_tx_buffer
                                              *tx_buffer_info)
 {
-	if (tx_buffer_info->dma) {
-		pci_unmap_page(adapter->pdev, tx_buffer_info->dma,
-		               tx_buffer_info->length, PCI_DMA_TODEVICE);
-		tx_buffer_info->dma = 0;
-	}
+	tx_buffer_info->dma = 0;
 	if (tx_buffer_info->skb) {
+		skb_dma_unmap(&adapter->pdev->dev, tx_buffer_info->skb,
+		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(tx_buffer_info->skb);
 		tx_buffer_info->skb = NULL;
 	}
+	tx_buffer_info->time_stamp = 0;
 	/* tx_buffer_info must be completely set up in the transmit path */
 }
 
@@ -204,15 +203,11 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
                                        unsigned int eop)
 {
 	struct ixgbe_hw *hw = &adapter->hw;
-	u32 head, tail;
 
 	/* Detect a transmit hang in hardware, this serializes the
 	 * check with the clearing of time_stamp and movement of eop */
-	head = IXGBE_READ_REG(hw, tx_ring->head);
-	tail = IXGBE_READ_REG(hw, tx_ring->tail);
 	adapter->detect_tx_hung = false;
-	if ((head != tail) &&
-	    tx_ring->tx_buffer_info[eop].time_stamp &&
+	if (tx_ring->tx_buffer_info[eop].time_stamp &&
 	    time_after(jiffies, tx_ring->tx_buffer_info[eop].time_stamp + HZ) &&
 	    !(IXGBE_READ_REG(&adapter->hw, IXGBE_TFCS) & IXGBE_TFCS_TXOFF)) {
 		/* detected Tx unit hang */
@@ -227,7 +222,8 @@ static inline bool ixgbe_check_tx_hang(struct ixgbe_adapter *adapter,
 			"  time_stamp           <%lx>\n"
 			"  jiffies              <%lx>\n",
 			tx_ring->queue_index,
-			head, tail,
+			IXGBE_READ_REG(hw, tx_ring->head),
+			IXGBE_READ_REG(hw, tx_ring->tail),
 			tx_ring->next_to_use, eop,
 			tx_ring->tx_buffer_info[eop].time_stamp, jiffies);
 		return true;
@@ -4164,32 +4160,39 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
                         struct sk_buff *skb, unsigned int first)
 {
 	struct ixgbe_tx_buffer *tx_buffer_info;
-	unsigned int len = skb->len;
+	unsigned int len = skb_headlen(skb);
 	unsigned int offset = 0, size, count = 0, i;
 	unsigned int nr_frags = skb_shinfo(skb)->nr_frags;
 	unsigned int f;
-
-	len -= skb->data_len;
+	dma_addr_t *map;
 
 	i = tx_ring->next_to_use;
 
+	if (skb_dma_map(&adapter->pdev->dev, skb, DMA_TO_DEVICE)) {
+		dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
+		return 0;
+	}
+
+	map = skb_shinfo(skb)->dma_maps;
+
 	while (len) {
 		tx_buffer_info = &tx_ring->tx_buffer_info[i];
 		size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
 
 		tx_buffer_info->length = size;
-		tx_buffer_info->dma = pci_map_single(adapter->pdev,
-		                                     skb->data + offset,
-		                                     size, PCI_DMA_TODEVICE);
+		tx_buffer_info->dma = map[0] + offset;
 		tx_buffer_info->time_stamp = jiffies;
 		tx_buffer_info->next_to_watch = i;
 
 		len -= size;
 		offset += size;
 		count++;
-		i++;
-		if (i == tx_ring->count)
-			i = 0;
+
+		if (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+		}
 	}
 
 	for (f = 0; f < nr_frags; f++) {
@@ -4197,33 +4200,27 @@ static int ixgbe_tx_map(struct ixgbe_adapter *adapter,
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = frag->page_offset;
+		offset = 0;
 
 		while (len) {
+			i++;
+			if (i == tx_ring->count)
+				i = 0;
+
 			tx_buffer_info = &tx_ring->tx_buffer_info[i];
 			size = min(len, (uint)IXGBE_MAX_DATA_PER_TXD);
 
 			tx_buffer_info->length = size;
-			tx_buffer_info->dma = pci_map_page(adapter->pdev,
-			                                   frag->page,
-			                                   offset,
-			                                   size,
-			                                   PCI_DMA_TODEVICE);
+			tx_buffer_info->dma = map[f + 1] + offset;
 			tx_buffer_info->time_stamp = jiffies;
 			tx_buffer_info->next_to_watch = i;
 
 			len -= size;
 			offset += size;
 			count++;
-			i++;
-			if (i == tx_ring->count)
-				i = 0;
 		}
 	}
-	if (i == 0)
-		i = tx_ring->count - 1;
-	else
-		i = i - 1;
+
 	tx_ring->tx_buffer_info[i].skb = skb;
 	tx_ring->tx_buffer_info[first].next_to_watch = i;
 
@@ -4389,13 +4386,19 @@ static int ixgbe_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 	         (skb->ip_summed == CHECKSUM_PARTIAL))
 		tx_flags |= IXGBE_TX_FLAGS_CSUM;
 
-	ixgbe_tx_queue(adapter, tx_ring, tx_flags,
-	               ixgbe_tx_map(adapter, tx_ring, skb, first),
-	               skb->len, hdr_len);
+	count = ixgbe_tx_map(adapter, tx_ring, skb, first);
 
-	netdev->trans_start = jiffies;
+	if (count) {
+		ixgbe_tx_queue(adapter, tx_ring, tx_flags, count, skb->len,
+		               hdr_len);
+		netdev->trans_start = jiffies;
+		ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
 
-	ixgbe_maybe_stop_tx(netdev, tx_ring, DESC_NEEDED);
+	} else {
+		dev_kfree_skb_any(skb);
+		tx_ring->tx_buffer_info[first].time_stamp = 0;
+		tx_ring->next_to_use = first;
+	}
 
 	return NETDEV_TX_OK;
 }


  parent reply	other threads:[~2009-04-01  7:34 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-01  7:32 [PATCH 1/9] ixgbe: fix build when DEBUG is defined Jeff Kirsher
2009-04-01  7:33 ` [PATCH 2/9] ixgbe: Fix ethtool output with advertised mode Jeff Kirsher
2009-04-02  8:15   ` David Miller
2009-04-01  7:33 ` [PATCH 3/9] ixgbe: Fix DCB netlink layer for 82599 to enable Priority Flow Control Jeff Kirsher
2009-04-02  8:15   ` David Miller
2009-04-01  7:33 ` [PATCH 4/9] ixgbe: feature - driver to default with FC on Jeff Kirsher
2009-04-02  8:15   ` David Miller
2009-04-01  7:34 ` [PATCH 5/9] ixgbe: Fix 82598 MSI-X allocation on systems with more than 8 CPU cores Jeff Kirsher
2009-04-02  8:15   ` David Miller
2009-04-01  7:34 ` Jeff Kirsher [this message]
2009-04-02  8:15   ` [PATCH 6/9] ixgbe: refactor tx buffer processing to use skb_dma_map/unmap David Miller
2009-04-01  7:34 ` [PATCH 7/9] ixgbe: Patch to fix driver panic while freeing up tx & rx resources Jeff Kirsher
2009-04-02  8:15   ` David Miller
2009-04-01  7:35 ` [PATCH 8/9] ixgbe: fix ethtool -A|a behavior Jeff Kirsher
2009-04-02  8:16   ` David Miller
2009-04-01  7:35 ` [PATCH 9/9] ixgbe: Fix potential memory leak/driver panic issue while setting up Tx & Rx ring parameters Jeff Kirsher
2009-04-02  8:16   ` David Miller
2009-04-02  8:15 ` [PATCH 1/9] ixgbe: fix build when DEBUG is defined David Miller

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=20090401073423.3749.21206.stgit@lost.foo-projects.org \
    --to=jeffrey.t.kirsher@intel.com \
    --cc=alexander.h.duyck@intel.com \
    --cc=davem@davemloft.net \
    --cc=gospo@redhat.com \
    --cc=mallikarjuna.chilakala@intel.com \
    --cc=netdev@vger.kernel.org \
    --cc=peter.p.waskiewicz.jr@intel.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.