Resolves: bz 928024
This commit is contained in:
parent
e2fe0f96bd
commit
7d8fdd730a
|
@ -0,0 +1,134 @@
|
|||
From e33f52b67b45dd95b973260c54c6ef207ee44f84 Mon Sep 17 00:00:00 2001
|
||||
From: Neil Horman <nhorman@tuxdriver.com>
|
||||
Date: Tue, 26 Mar 2013 14:36:56 -0400
|
||||
Subject: [PATCH] forcedeth: Do a dma_mapping_error check after
|
||||
skb_frag_dma_map
|
||||
|
||||
This backtrace was recently reported on a 3.9 kernel:
|
||||
|
||||
Actual results: from syslog /var/log/messsages:
|
||||
kernel: [17539.340285] ------------[ cut here ]------------
|
||||
kernel: [17539.341012] WARNING: at lib/dma-debug.c:937 check_unmap+0x493/0x960()
|
||||
kernel: [17539.341012] Hardware name: MS-7125
|
||||
kernel: [17539.341012] forcedeth 0000:00:0a.0: DMA-API: device driver failed to
|
||||
check map error[device address=0x0000000013c88000] [size=544 bytes] [mapped as
|
||||
page]
|
||||
kernel: [17539.341012] Modules linked in: fuse ebtable_nat ipt_MASQUERADE
|
||||
nf_conntrack_netbios_ns nf_conntrack_broadcast ip6table_nat nf_nat_ipv6
|
||||
ip6table_mangle ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 iptable_nat
|
||||
nf_nat_ipv4 nf_nat iptable_mangle nf_conntrack_ipv4 nf_defrag_ipv4 xt_conntrack
|
||||
nf_conntrack bnep bluetooth rfkill ebtable_filter ebtables ip6table_filter
|
||||
ip6_tables snd_hda_codec_hdmi snd_cmipci snd_mpu401_uart snd_hda_intel
|
||||
snd_intel8x0 snd_opl3_lib snd_ac97_codec gameport snd_hda_codec snd_rawmidi
|
||||
ac97_bus snd_hwdep snd_seq snd_seq_device snd_pcm snd_page_alloc snd_timer snd
|
||||
k8temp soundcore serio_raw i2c_nforce2 forcedeth ata_generic pata_acpi nouveau
|
||||
video mxm_wmi wmi i2c_algo_bit drm_kms_helper ttm drm i2c_core sata_sil pata_amd
|
||||
sata_nv uinput
|
||||
kernel: [17539.341012] Pid: 17340, comm: sshd Not tainted
|
||||
3.9.0-0.rc4.git0.1.fc19.i686.PAE #1
|
||||
kernel: [17539.341012] Call Trace:
|
||||
kernel: [17539.341012] [<c045573c>] warn_slowpath_common+0x6c/0xa0
|
||||
kernel: [17539.341012] [<c0701953>] ? check_unmap+0x493/0x960
|
||||
kernel: [17539.341012] [<c0701953>] ? check_unmap+0x493/0x960
|
||||
kernel: [17539.341012] [<c04557a3>] warn_slowpath_fmt+0x33/0x40
|
||||
kernel: [17539.341012] [<c0701953>] check_unmap+0x493/0x960
|
||||
kernel: [17539.341012] [<c049238f>] ? sched_clock_cpu+0xdf/0x150
|
||||
kernel: [17539.341012] [<c0701e87>] debug_dma_unmap_page+0x67/0x70
|
||||
kernel: [17539.341012] [<f7eae8f2>] nv_unmap_txskb.isra.32+0x92/0x100
|
||||
|
||||
Its pretty plainly the result of an skb fragment getting unmapped without having
|
||||
its initial mapping operation checked for errors. This patch corrects that
|
||||
|
||||
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
|
||||
CC: "David S. Miller" <davem@davemloft.net>
|
||||
---
|
||||
drivers/net/ethernet/nvidia/forcedeth.c | 41 ++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 40 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
|
||||
index b62262c..5ae1247 100644
|
||||
--- a/drivers/net/ethernet/nvidia/forcedeth.c
|
||||
+++ b/drivers/net/ethernet/nvidia/forcedeth.c
|
||||
@@ -2200,6 +2200,7 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
struct ring_desc *start_tx;
|
||||
struct ring_desc *prev_tx;
|
||||
struct nv_skb_map *prev_tx_ctx;
|
||||
+ struct nv_skb_map *tmp_tx_ctx = NULL, *start_tx_ctx = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
/* add fragments to entries count */
|
||||
@@ -2261,12 +2262,31 @@ static netdev_tx_t nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
|
||||
do {
|
||||
prev_tx = put_tx;
|
||||
prev_tx_ctx = np->put_tx_ctx;
|
||||
+ if (!start_tx_ctx)
|
||||
+ start_tx_ctx = tmp_tx_ctx = np->put_tx_ctx;
|
||||
+
|
||||
bcnt = (frag_size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : frag_size;
|
||||
np->put_tx_ctx->dma = skb_frag_dma_map(
|
||||
&np->pci_dev->dev,
|
||||
frag, offset,
|
||||
bcnt,
|
||||
DMA_TO_DEVICE);
|
||||
+ if (dma_mapping_error(&np->pci_dev->dev, np->put_tx_ctx->dma)) {
|
||||
+
|
||||
+ /* Unwind the mapped fragments */
|
||||
+ do {
|
||||
+ nv_unmap_txskb(np, start_tx_ctx);
|
||||
+ if (unlikely(tmp_tx_ctx++ == np->last_tx_ctx))
|
||||
+ tmp_tx_ctx = np->first_tx_ctx;
|
||||
+ } while (tmp_tx_ctx != np->put_tx_ctx);
|
||||
+ kfree_skb(skb);
|
||||
+ np->put_tx_ctx = start_tx_ctx;
|
||||
+ u64_stats_update_begin(&np->swstats_tx_syncp);
|
||||
+ np->stat_tx_dropped++;
|
||||
+ u64_stats_update_end(&np->swstats_tx_syncp);
|
||||
+ return NETDEV_TX_OK;
|
||||
+ }
|
||||
+
|
||||
np->put_tx_ctx->dma_len = bcnt;
|
||||
np->put_tx_ctx->dma_single = 0;
|
||||
put_tx->buf = cpu_to_le32(np->put_tx_ctx->dma);
|
||||
@@ -2327,7 +2347,8 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
|
||||
struct ring_desc_ex *start_tx;
|
||||
struct ring_desc_ex *prev_tx;
|
||||
struct nv_skb_map *prev_tx_ctx;
|
||||
- struct nv_skb_map *start_tx_ctx;
|
||||
+ struct nv_skb_map *start_tx_ctx = NULL;
|
||||
+ struct nv_skb_map *tmp_tx_ctx = NULL;
|
||||
unsigned long flags;
|
||||
|
||||
/* add fragments to entries count */
|
||||
@@ -2392,11 +2413,29 @@ static netdev_tx_t nv_start_xmit_optimized(struct sk_buff *skb,
|
||||
prev_tx = put_tx;
|
||||
prev_tx_ctx = np->put_tx_ctx;
|
||||
bcnt = (frag_size > NV_TX2_TSO_MAX_SIZE) ? NV_TX2_TSO_MAX_SIZE : frag_size;
|
||||
+ if (!start_tx_ctx)
|
||||
+ start_tx_ctx = tmp_tx_ctx = np->put_tx_ctx;
|
||||
np->put_tx_ctx->dma = skb_frag_dma_map(
|
||||
&np->pci_dev->dev,
|
||||
frag, offset,
|
||||
bcnt,
|
||||
DMA_TO_DEVICE);
|
||||
+
|
||||
+ if (dma_mapping_error(&np->pci_dev->dev, np->put_tx_ctx->dma)) {
|
||||
+
|
||||
+ /* Unwind the mapped fragments */
|
||||
+ do {
|
||||
+ nv_unmap_txskb(np, start_tx_ctx);
|
||||
+ if (unlikely(tmp_tx_ctx++ == np->last_tx_ctx))
|
||||
+ tmp_tx_ctx = np->first_tx_ctx;
|
||||
+ } while (tmp_tx_ctx != np->put_tx_ctx);
|
||||
+ kfree_skb(skb);
|
||||
+ np->put_tx_ctx = start_tx_ctx;
|
||||
+ u64_stats_update_begin(&np->swstats_tx_syncp);
|
||||
+ np->stat_tx_dropped++;
|
||||
+ u64_stats_update_end(&np->swstats_tx_syncp);
|
||||
+ return NETDEV_TX_OK;
|
||||
+ }
|
||||
np->put_tx_ctx->dma_len = bcnt;
|
||||
np->put_tx_ctx->dma_single = 0;
|
||||
put_tx->bufhigh = cpu_to_le32(dma_high(np->put_tx_ctx->dma));
|
||||
--
|
||||
1.7.11.7
|
||||
|
|
@ -748,6 +748,9 @@ Patch23006: fix-child-thread-introspection.patch
|
|||
|
||||
Patch23007: htmldoc-build-fix.patch
|
||||
|
||||
#rhbz 928024
|
||||
Patch23008: forcedeth-dma-error-check.patch
|
||||
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
%endif
|
||||
|
@ -1446,6 +1449,9 @@ ApplyPatch fix-child-thread-introspection.patch
|
|||
|
||||
ApplyPatch htmldoc-build-fix.patch
|
||||
|
||||
#rhbz 928024
|
||||
ApplyPatch forcedeth-dma-error-check.patch
|
||||
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
%endif
|
||||
|
@ -2278,6 +2284,9 @@ fi
|
|||
# and build.
|
||||
|
||||
%changelog
|
||||
* Tue Apr 02 2013 Neil Horman <nhorman@redhat.com>
|
||||
- Fix dma debug error on unmap (rhbz 928024)
|
||||
|
||||
* Tue Apr 02 2013 Josh Boyer <jwboyer@redhat.com>
|
||||
- Enable CONFIG_SCSI_DMX3191D (rhbz 919874)
|
||||
|
||||
|
|
Loading…
Reference in New Issue