Fix forcedeth DMA check error (rhbz 928024)
This commit is contained in:
		
							parent
							
								
									77c62fd3ed
								
							
						
					
					
						commit
						e98edb5c67
					
				
							
								
								
									
										132
									
								
								forcedeth-dma-error-check.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								forcedeth-dma-error-check.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,132 @@ | |||||||
|  | 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 | ||||||
|  | 
 | ||||||
|  | --
 | ||||||
|  | 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 | ||||||
| @ -749,6 +749,9 @@ Patch23006: fix-child-thread-introspection.patch | |||||||
| #rhbz 949875 | #rhbz 949875 | ||||||
| Patch23007: libsas-use-right-function-to-alloc-smp-response.patch | Patch23007: libsas-use-right-function-to-alloc-smp-response.patch | ||||||
| 
 | 
 | ||||||
|  | #rhbz 928024 | ||||||
|  | Patch23008: forcedeth-dma-error-check.patch | ||||||
|  | 
 | ||||||
| # END OF PATCH DEFINITIONS | # END OF PATCH DEFINITIONS | ||||||
| 
 | 
 | ||||||
| %endif | %endif | ||||||
| @ -1448,6 +1451,9 @@ ApplyPatch fix-child-thread-introspection.patch | |||||||
| #rhbz 949875 | #rhbz 949875 | ||||||
| ApplyPatch libsas-use-right-function-to-alloc-smp-response.patch | ApplyPatch libsas-use-right-function-to-alloc-smp-response.patch | ||||||
| 
 | 
 | ||||||
|  | #rhbz 928024 | ||||||
|  | ApplyPatch forcedeth-dma-error-check.patch | ||||||
|  | 
 | ||||||
| # END OF PATCH APPLICATIONS | # END OF PATCH APPLICATIONS | ||||||
| 
 | 
 | ||||||
| %endif | %endif | ||||||
| @ -2281,6 +2287,9 @@ fi | |||||||
| #                 ||----w | | #                 ||----w | | ||||||
| #                 ||     || | #                 ||     || | ||||||
| %changelog | %changelog | ||||||
|  | * Fri Apr 12 2013 Justin M. Forbes <jforbes@redhat.com> | ||||||
|  | - Fix forcedeth DMA check error (rhbz 928024) | ||||||
|  | 
 | ||||||
| * Thu Apr 11 2013 Dave Jones <davej@redhat.com> | * Thu Apr 11 2013 Dave Jones <davej@redhat.com> | ||||||
| - Print out some extra debug information when we hit bad page tables. | - Print out some extra debug information when we hit bad page tables. | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user