rpms/kernel/devel dma-api-debug-fixes.patch, NONE, 1.1 TODO, 1.57, 1.58 kernel.spec, 1.1448, 1.1449 linux-2.6-net-tulip-interrupt.patch, 1.1, 1.2

Kyle McMartin kyle at fedoraproject.org
Thu Mar 19 16:10:17 UTC 2009


Author: kyle

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv12472

Modified Files:
	TODO kernel.spec linux-2.6-net-tulip-interrupt.patch 
Added Files:
	dma-api-debug-fixes.patch 
Log Message:
todo update, dma-api-debug-fixes patch, tulip fixes, oh my.


dma-api-debug-fixes.patch:

--- NEW FILE dma-api-debug-fixes.patch ---
commit 0dd54847af013a7fa91c60a9f909f76c3c812d22
Author: Jesse Brandeburg <jesse.brandeburg at intel.com>
Date:   Mon Mar 2 16:02:53 2009 -0800

    e1000e: fix unmap bug
    
    This is in reference to https://bugzilla.redhat.com/show_bug.cgi?id=484494
    Also addresses issue show in kerneloops
    
    The e1000e transmit code was calling pci_unmap_page on dma handles that it
    might have called pci_map_single on.
    
    Signed-off-by: Jesse Brandeburg <jesse.brandeburg at intel.com>
    Acked-by: Bruce Allan <bruce.w.allan at intel.com>
    Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
    Signed-off-by: David S. Miller <davem at davemloft.net>
    Signed-off-by: Ingo Molnar <mingo at elte.hu>

diff --git a/drivers/net/e1000e/netdev.c b/drivers/net/e1000e/netdev.c
index 91817d0..f99e01c 100644
--- a/drivers/net/e1000e/netdev.c
+++ b/drivers/net/e1000e/netdev.c
@@ -565,12 +565,10 @@ next_desc:
 static void e1000_put_txbuf(struct e1000_adapter *adapter,
 			     struct e1000_buffer *buffer_info)
 {
-	if (buffer_info->dma) {
-		pci_unmap_page(adapter->pdev, buffer_info->dma,
-			       buffer_info->length, PCI_DMA_TODEVICE);
-		buffer_info->dma = 0;
-	}
+	buffer_info->dma = 0;
 	if (buffer_info->skb) {
+		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(buffer_info->skb);
 		buffer_info->skb = NULL;
 	}
@@ -683,6 +681,11 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 		 * check with the clearing of time_stamp and movement of i
 		 */
 		adapter->detect_tx_hung = 0;
+		/*
+		 * read barrier to make sure that the ->dma member and time
+		 * stamp are updated fully
+		 */
+		smp_rmb();
 		if (tx_ring->buffer_info[eop].dma &&
 		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp
 			       + (adapter->tx_timeout_factor * HZ))
@@ -3831,15 +3834,25 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 			unsigned int mss)
 {
 	struct e1000_ring *tx_ring = adapter->tx_ring;
-	struct e1000_buffer *buffer_info;
-	unsigned int len = skb->len - skb->data_len;
-	unsigned int offset = 0, size, count = 0, i;
+	unsigned int len = skb_headlen(skb);
+	unsigned int offset, size, count = 0, i;
 	unsigned int f;
+	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");
+		adapter->tx_dma_failed++;
+		dev_kfree_skb(skb);
+		return -2;
+	}
+
+	map = skb_shinfo(skb)->dma_maps[0];
+	offset = 0;
+
 	while (len) {
-		buffer_info = &tx_ring->buffer_info[i];
+		struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
 
 		/* Workaround for premature desc write-backs
@@ -3850,16 +3863,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 		buffer_info->length = size;
 		/* set time_stamp *before* dma to help avoid a possible race */
 		buffer_info->time_stamp = jiffies;
-		buffer_info->dma =
-			pci_map_single(adapter->pdev,
-				skb->data + offset,
-				size,
-				PCI_DMA_TODEVICE);
-		if (pci_dma_mapping_error(adapter->pdev, buffer_info->dma)) {
-			dev_err(&adapter->pdev->dev, "TX DMA map failed\n");
-			adapter->tx_dma_failed++;
-			return -1;
-		}
+		buffer_info->dma = map + offset;
 		buffer_info->next_to_watch = i;
 
 		len -= size;
@@ -3875,9 +3879,11 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = frag->page_offset;
+		map = skb_shinfo(skb)->dma_maps[f + 1];
+		offset = 0;
 
 		while (len) {
+			struct e1000_buffer *buffer_info;
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, max_per_txd);
 			/* Workaround for premature desc write-backs
@@ -3887,20 +3893,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 
 			buffer_info->length = size;
 			buffer_info->time_stamp = jiffies;
-			buffer_info->dma =
-				pci_map_page(adapter->pdev,
-					frag->page,
-					offset,
-					size,
-					PCI_DMA_TODEVICE);
-			if (pci_dma_mapping_error(adapter->pdev,
-						  buffer_info->dma)) {
-				dev_err(&adapter->pdev->dev,
-					"TX DMA page map failed\n");
-				adapter->tx_dma_failed++;
-				return -1;
-			}
-
+			buffer_info->dma = map + offset;
 			buffer_info->next_to_watch = i;
 
 			len -= size;
@@ -3920,6 +3913,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
+	smp_wmb();
 
 	return count;
 }

commit 33bfe0386ff55f5c1c9e18cbb84a17064168bc5c
Author: Jesse Brandeburg <jesse.brandeburg at intel.com>
Date:   Mon Mar 2 16:03:21 2009 -0800

    e1000: fix unmap bug
    
    This is in reference to the issue shown in kerneloops (search e1000 unmap)
    
    The e1000 transmit code was calling pci_unmap_page on dma handles that it
    might have called pci_map_single on.
    
    Same bug as e1000e
    
    Signed-off-by: Jesse Brandeburg <jesse.brandeburg at intel.com>
    Acked-by: Bruce Allan <bruce.w.allan at intel.com>
    Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher at intel.com>
    Signed-off-by: David S. Miller <davem at davemloft.net>
    Signed-off-by: Ingo Molnar <mingo at elte.hu>

diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 6bd63cc..4976e11 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -2056,14 +2056,10 @@ void e1000_free_all_tx_resources(struct e1000_adapter *adapter)
 static void e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter,
 					     struct e1000_buffer *buffer_info)
 {
-	if (buffer_info->dma) {
-		pci_unmap_page(adapter->pdev,
-				buffer_info->dma,
-				buffer_info->length,
-				PCI_DMA_TODEVICE);
-		buffer_info->dma = 0;
-	}
+	buffer_info->dma = 0;
 	if (buffer_info->skb) {
+		skb_dma_unmap(&adapter->pdev->dev, buffer_info->skb,
+		              DMA_TO_DEVICE);
 		dev_kfree_skb_any(buffer_info->skb);
 		buffer_info->skb = NULL;
 	}
@@ -2914,16 +2910,24 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 			unsigned int mss)
 {
 	struct e1000_hw *hw = &adapter->hw;
-	struct e1000_buffer *buffer_info;
-	unsigned int len = skb->len;
-	unsigned int offset = 0, size, count = 0, i;
+	unsigned int len = skb_headlen(skb);
+	unsigned int offset, size, count = 0, i;
 	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");
+		dev_kfree_skb(skb);
+		return -2;
+	}
+
+	map = skb_shinfo(skb)->dma_maps[0];
+	offset = 0;
+
 	while (len) {
-		buffer_info = &tx_ring->buffer_info[i];
+		struct e1000_buffer *buffer_info = &tx_ring->buffer_info[i];
 		size = min(len, max_per_txd);
 		/* Workaround for Controller erratum --
 		 * descriptor for non-tso packet in a linear SKB that follows a
@@ -2956,11 +2960,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 			size -= 4;
 
 		buffer_info->length = size;
-		buffer_info->dma =
-			pci_map_single(adapter->pdev,
-				skb->data + offset,
-				size,
-				PCI_DMA_TODEVICE);
+		buffer_info->dma = map + offset;
 		buffer_info->time_stamp = jiffies;
 		buffer_info->next_to_watch = i;
 
@@ -2975,9 +2975,11 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 
 		frag = &skb_shinfo(skb)->frags[f];
 		len = frag->size;
-		offset = frag->page_offset;
+		map = skb_shinfo(skb)->dma_maps[f + 1];
+		offset = 0;
 
 		while (len) {
+			struct e1000_buffer *buffer_info;
 			buffer_info = &tx_ring->buffer_info[i];
 			size = min(len, max_per_txd);
 			/* Workaround for premature desc write-backs
@@ -2993,12 +2995,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 				size -= 4;
 
 			buffer_info->length = size;
-			buffer_info->dma =
-				pci_map_page(adapter->pdev,
-					frag->page,
-					offset,
-					size,
-					PCI_DMA_TODEVICE);
+			buffer_info->dma = map + offset;
 			buffer_info->time_stamp = jiffies;
 			buffer_info->next_to_watch = i;
 
@@ -3012,6 +3009,7 @@ static int e1000_tx_map(struct e1000_adapter *adapter,
 	i = (i == 0) ? tx_ring->count - 1 : i - 1;
 	tx_ring->buffer_info[i].skb = skb;
 	tx_ring->buffer_info[first].next_to_watch = i;
+	smp_wmb();
 
 	return count;
 }
@@ -3869,6 +3867,11 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter,
 		/* Detect a transmit hang in hardware, this serializes the
 		 * check with the clearing of time_stamp and movement of i */
 		adapter->detect_tx_hung = false;
+		/*
+		 * read barrier to make sure that the ->dma member and time
+		 * stamp are updated fully
+		 */
+		smp_rmb();
 		if (tx_ring->buffer_info[eop].dma &&
 		    time_after(jiffies, tx_ring->buffer_info[eop].time_stamp +
 		               (adapter->tx_timeout_factor * HZ))


Index: TODO
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/TODO,v
retrieving revision 1.57
retrieving revision 1.58
diff -u -r1.57 -r1.58
--- TODO	12 Mar 2009 03:33:46 -0000	1.57
+++ TODO	19 Mar 2009 16:09:45 -0000	1.58
@@ -18,9 +18,11 @@
 * linux-2.6-debug-spinlock-taint.patch
 * linux-2.6-debug-taint-vm.patch
 * linux-2.6-debug-vm-would-have-oomkilled.patch
-* linux-2.6-scsi-cpqarray-set-master.patch
 	Push for 2.6.29
 
+* linux-2.6-scsi-cpqarray-set-master.patch
+	Queued for 2.6.30 by Jens Axboe
+
 * linux-2.6-cdrom-door-status.patch
 	Getting some testing here before I go back to upstream with more
 	data.  See the thread at:
@@ -83,6 +85,4 @@
 	http://lkml.org/lkml/2006/8/2/208
 
 * linux-2.6-net-tulip-interrupt.patch
-	DEBUG_SHIRQ causes an oops.
-	Needs testing, if it works, it'll go upstream soon.
-
+	Queued by DaveM for next release.


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.1448
retrieving revision 1.1449
diff -u -r1.1448 -r1.1449
--- kernel.spec	19 Mar 2009 15:47:56 -0000	1.1448
+++ kernel.spec	19 Mar 2009 16:09:45 -0000	1.1449
@@ -1819,6 +1819,7 @@
 %changelog
 * Thu Mar 19 2009 Kyle McMartin <kyle at redhat.com>
 - dma-api debug fixes for e1000 and e1000e from tip.
+- fix dma leak in tulip request_irq error path.
 
 * Thu Mar 19 2009 Kyle McMartin <kyle at redhat.com> 2.6.29-0.267.rc8.git4
 - build fixes for v4l tree.

linux-2.6-net-tulip-interrupt.patch:

Index: linux-2.6-net-tulip-interrupt.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-net-tulip-interrupt.patch,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- linux-2.6-net-tulip-interrupt.patch	8 Oct 2008 17:58:49 -0000	1.1
+++ linux-2.6-net-tulip-interrupt.patch	19 Mar 2009 16:09:46 -0000	1.2
@@ -1,22 +1,121 @@
-https://bugzilla.redhat.com/show_bug.cgi?id=454575
+From netdev-owner at vger.kernel.org Sun Mar 15 01:35:56 2009
+Date:	Sun, 15 Mar 2009 01:35:52 -0400
+From:	Kyle McMartin <kyle at infradead.org>
+Subject: [PATCH] tulip: fix crash on iface up with shirq debug
 
-Signed-off-by: Dave Jones <davej at redhat.com>
+From: Kyle McMartin <kyle at redhat.com>
 
+Tulip is currently doing request_irq before it has done its
+initialization. This is usually not a problem because it hasn't
+enable interrupts yet, but with DEBUG_SHIRQ on, we call the irq handler
+when registering the interrupt as a sanity check.
+
+This can result in a NULL ptr dereference, so call tulip_init_ring
+before request_irq, and add a free_ring function to do the freeing
+now shared with tulip_close.
+
+Tested with a shell loop running ifup, ifdown in a loop a few hundred
+times with DEBUG_SHIRQ on.
+
+Signed-off-by: Kyle McMartin <kyle at redhat.com>
+---
 diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
-index cafa89e..daa83a7 100644
+index bee75fa..2abb5d3 100644
 --- a/drivers/net/tulip/tulip_core.c
 +++ b/drivers/net/tulip/tulip_core.c
-@@ -502,11 +502,11 @@ tulip_open(struct net_device *dev)
+@@ -255,6 +255,7 @@ const char tulip_media_cap[32] =
+ 
+ static void tulip_tx_timeout(struct net_device *dev);
+ static void tulip_init_ring(struct net_device *dev);
++static void tulip_free_ring(struct net_device *dev);
+ static int tulip_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static int tulip_open(struct net_device *dev);
+ static int tulip_close(struct net_device *dev);
+@@ -502,16 +503,21 @@ tulip_open(struct net_device *dev)
  {
  	int retval;
  
-+	tulip_init_ring(dev);
-+
- 	if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev)))
- 		return retval;
- 
--	tulip_init_ring (dev);
+-	if ((retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev)))
+-		return retval;
 -
+ 	tulip_init_ring (dev);
+ 
++	retval = request_irq(dev->irq, &tulip_interrupt, IRQF_SHARED, dev->name, dev);
++	if (retval)
++		goto free_ring;
++
  	tulip_up (dev);
  
  	netif_start_queue (dev);
+ 
+ 	return 0;
++
++free_ring:
++	tulip_free_ring (dev);
++	return retval;
+ }
+ 
+ 
+@@ -768,23 +774,11 @@ static void tulip_down (struct net_device *dev)
+ 	tulip_set_power_state (tp, 0, 1);
+ }
+ 
+-
+-static int tulip_close (struct net_device *dev)
++static void tulip_free_ring (struct net_device *dev)
+ {
+ 	struct tulip_private *tp = netdev_priv(dev);
+-	void __iomem *ioaddr = tp->base_addr;
+ 	int i;
+ 
+-	netif_stop_queue (dev);
+-
+-	tulip_down (dev);
+-
+-	if (tulip_debug > 1)
+-		printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
+-			dev->name, ioread32 (ioaddr + CSR5));
+-
+-	free_irq (dev->irq, dev);
+-
+ 	/* Free all the skbuffs in the Rx queue. */
+ 	for (i = 0; i < RX_RING_SIZE; i++) {
+ 		struct sk_buff *skb = tp->rx_buffers[i].skb;
+@@ -803,6 +797,7 @@ static int tulip_close (struct net_device *dev)
+ 			dev_kfree_skb (skb);
+ 		}
+ 	}
++
+ 	for (i = 0; i < TX_RING_SIZE; i++) {
+ 		struct sk_buff *skb = tp->tx_buffers[i].skb;
+ 
+@@ -814,6 +809,24 @@ static int tulip_close (struct net_device *dev)
+ 		tp->tx_buffers[i].skb = NULL;
+ 		tp->tx_buffers[i].mapping = 0;
+ 	}
++}
++
++static int tulip_close (struct net_device *dev)
++{
++	struct tulip_private *tp = netdev_priv(dev);
++	void __iomem *ioaddr = tp->base_addr;
++
++	netif_stop_queue (dev);
++
++	tulip_down (dev);
++
++	if (tulip_debug > 1)
++		printk (KERN_DEBUG "%s: Shutting down ethercard, status was %2.2x.\n",
++			dev->name, ioread32 (ioaddr + CSR5));
++
++	free_irq (dev->irq, dev);
++
++	tulip_free_ring (dev);
+ 
+ 	return 0;
+ }
+--
+To unsubscribe from this list: send the line "unsubscribe netdev" in
+the body of a message to majordomo at vger.kernel.org
+More majordomo info at  http://vger.kernel.org/majordomo-info.html
+




More information about the fedora-extras-commits mailing list