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