diff options
author | Neil Horman <nhorman@tuxdriver.com> | 2013-07-12 10:58:48 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-07-12 19:25:54 -0400 |
commit | 352900b583b2852152a1e05ea0e8b579292e731e (patch) | |
tree | c57c471e61fab440b38ff4ec70a31e46894bc534 /drivers/net/ethernet/atheros | |
parent | 24ab6bec80861d0c55263047e8bf97e460a32e7b (diff) |
atl1e: fix dma mapping warnings
Recently had this backtrace reported:
WARNING: at lib/dma-debug.c:937 check_unmap+0x47d/0x930()
Hardware name: System Product Name
ATL1E 0000:02:00.0: DMA-API: device driver failed to check map error[device
address=0x00000000cbfd1000] [size=90 bytes] [mapped as single]
Modules linked in: xt_conntrack nf_conntrack ebtable_filter ebtables
ip6table_filter ip6_tables snd_hda_codec_hdmi snd_hda_codec_realtek iTCO_wdt
iTCO_vendor_support snd_hda_intel acpi_cpufreq mperf coretemp btrfs zlib_deflate
snd_hda_codec snd_hwdep microcode raid6_pq libcrc32c snd_seq usblp serio_raw xor
snd_seq_device joydev snd_pcm snd_page_alloc snd_timer snd lpc_ich i2c_i801
soundcore mfd_core atl1e asus_atk0110 ata_generic pata_acpi radeon i2c_algo_bit
drm_kms_helper ttm drm i2c_core pata_marvell uinput
Pid: 314, comm: systemd-journal Not tainted 3.9.0-0.rc6.git2.3.fc19.x86_64 #1
Call Trace:
<IRQ> [<ffffffff81069106>] warn_slowpath_common+0x66/0x80
[<ffffffff8106916c>] warn_slowpath_fmt+0x4c/0x50
[<ffffffff8138151d>] check_unmap+0x47d/0x930
[<ffffffff810ad048>] ? sched_clock_cpu+0xa8/0x100
[<ffffffff81381a2f>] debug_dma_unmap_page+0x5f/0x70
[<ffffffff8137ce30>] ? unmap_single+0x20/0x30
[<ffffffffa01569a1>] atl1e_intr+0x3a1/0x5b0 [atl1e]
[<ffffffff810d53fd>] ? trace_hardirqs_off+0xd/0x10
[<ffffffff81119636>] handle_irq_event_percpu+0x56/0x390
[<ffffffff811199ad>] handle_irq_event+0x3d/0x60
[<ffffffff8111cb6a>] handle_fasteoi_irq+0x5a/0x100
[<ffffffff8101c36f>] handle_irq+0xbf/0x150
[<ffffffff811dcb2f>] ? file_sb_list_del+0x3f/0x50
[<ffffffff81073b10>] ? irq_enter+0x50/0xa0
[<ffffffff8172738d>] do_IRQ+0x4d/0xc0
[<ffffffff811dcb2f>] ? file_sb_list_del+0x3f/0x50
[<ffffffff8171c6b2>] common_interrupt+0x72/0x72
<EOI> [<ffffffff810db5b2>] ? lock_release+0xc2/0x310
[<ffffffff8109ea04>] lg_local_unlock_cpu+0x24/0x50
[<ffffffff811dcb2f>] file_sb_list_del+0x3f/0x50
[<ffffffff811dcb6d>] fput+0x2d/0xc0
[<ffffffff811d8ea1>] filp_close+0x61/0x90
[<ffffffff811fae4d>] __close_fd+0x8d/0x150
[<ffffffff811d8ef0>] sys_close+0x20/0x50
[<ffffffff81725699>] system_call_fastpath+0x16/0x1b
The usual straighforward failure to check for dma_mapping_error after a map
operation is completed.
This patch should fix it, the reporter wandered off after filing this bz:
https://bugzilla.redhat.com/show_bug.cgi?id=954170
and I don't have hardware to test, but the fix is pretty straightforward, so I
figured I'd post it for review.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Jay Cliburn <jcliburn@gmail.com>
CC: Chris Snook <chris.snook@gmail.com>
CC: "David S. Miller" <davem@davemloft.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/atheros')
-rw-r--r-- | drivers/net/ethernet/atheros/atl1e/atl1e_main.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c index 895f5377ad1b..6d1a62a84c9d 100644 --- a/drivers/net/ethernet/atheros/atl1e/atl1e_main.c +++ b/drivers/net/ethernet/atheros/atl1e/atl1e_main.c | |||
@@ -1665,8 +1665,8 @@ check_sum: | |||
1665 | return 0; | 1665 | return 0; |
1666 | } | 1666 | } |
1667 | 1667 | ||
1668 | static void atl1e_tx_map(struct atl1e_adapter *adapter, | 1668 | static int atl1e_tx_map(struct atl1e_adapter *adapter, |
1669 | struct sk_buff *skb, struct atl1e_tpd_desc *tpd) | 1669 | struct sk_buff *skb, struct atl1e_tpd_desc *tpd) |
1670 | { | 1670 | { |
1671 | struct atl1e_tpd_desc *use_tpd = NULL; | 1671 | struct atl1e_tpd_desc *use_tpd = NULL; |
1672 | struct atl1e_tx_buffer *tx_buffer = NULL; | 1672 | struct atl1e_tx_buffer *tx_buffer = NULL; |
@@ -1677,6 +1677,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, | |||
1677 | u16 nr_frags; | 1677 | u16 nr_frags; |
1678 | u16 f; | 1678 | u16 f; |
1679 | int segment; | 1679 | int segment; |
1680 | int ring_start = adapter->tx_ring.next_to_use; | ||
1680 | 1681 | ||
1681 | nr_frags = skb_shinfo(skb)->nr_frags; | 1682 | nr_frags = skb_shinfo(skb)->nr_frags; |
1682 | segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; | 1683 | segment = (tpd->word3 >> TPD_SEGMENT_EN_SHIFT) & TPD_SEGMENT_EN_MASK; |
@@ -1689,6 +1690,9 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, | |||
1689 | tx_buffer->length = map_len; | 1690 | tx_buffer->length = map_len; |
1690 | tx_buffer->dma = pci_map_single(adapter->pdev, | 1691 | tx_buffer->dma = pci_map_single(adapter->pdev, |
1691 | skb->data, hdr_len, PCI_DMA_TODEVICE); | 1692 | skb->data, hdr_len, PCI_DMA_TODEVICE); |
1693 | if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) | ||
1694 | return -ENOSPC; | ||
1695 | |||
1692 | ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); | 1696 | ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); |
1693 | mapped_len += map_len; | 1697 | mapped_len += map_len; |
1694 | use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); | 1698 | use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); |
@@ -1715,6 +1719,13 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, | |||
1715 | tx_buffer->dma = | 1719 | tx_buffer->dma = |
1716 | pci_map_single(adapter->pdev, skb->data + mapped_len, | 1720 | pci_map_single(adapter->pdev, skb->data + mapped_len, |
1717 | map_len, PCI_DMA_TODEVICE); | 1721 | map_len, PCI_DMA_TODEVICE); |
1722 | |||
1723 | if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { | ||
1724 | /* Reset the tx rings next pointer */ | ||
1725 | adapter->tx_ring.next_to_use = ring_start; | ||
1726 | return -ENOSPC; | ||
1727 | } | ||
1728 | |||
1718 | ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); | 1729 | ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_SINGLE); |
1719 | mapped_len += map_len; | 1730 | mapped_len += map_len; |
1720 | use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); | 1731 | use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); |
@@ -1750,6 +1761,13 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, | |||
1750 | (i * MAX_TX_BUF_LEN), | 1761 | (i * MAX_TX_BUF_LEN), |
1751 | tx_buffer->length, | 1762 | tx_buffer->length, |
1752 | DMA_TO_DEVICE); | 1763 | DMA_TO_DEVICE); |
1764 | |||
1765 | if (dma_mapping_error(&adapter->pdev->dev, tx_buffer->dma)) { | ||
1766 | /* Reset the ring next to use pointer */ | ||
1767 | adapter->tx_ring.next_to_use = ring_start; | ||
1768 | return -ENOSPC; | ||
1769 | } | ||
1770 | |||
1753 | ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE); | 1771 | ATL1E_SET_PCIMAP_TYPE(tx_buffer, ATL1E_TX_PCIMAP_PAGE); |
1754 | use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); | 1772 | use_tpd->buffer_addr = cpu_to_le64(tx_buffer->dma); |
1755 | use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) | | 1773 | use_tpd->word2 = (use_tpd->word2 & (~TPD_BUFLEN_MASK)) | |
@@ -1767,6 +1785,7 @@ static void atl1e_tx_map(struct atl1e_adapter *adapter, | |||
1767 | /* The last buffer info contain the skb address, | 1785 | /* The last buffer info contain the skb address, |
1768 | so it will be free after unmap */ | 1786 | so it will be free after unmap */ |
1769 | tx_buffer->skb = skb; | 1787 | tx_buffer->skb = skb; |
1788 | return 0; | ||
1770 | } | 1789 | } |
1771 | 1790 | ||
1772 | static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count, | 1791 | static void atl1e_tx_queue(struct atl1e_adapter *adapter, u16 count, |
@@ -1834,10 +1853,13 @@ static netdev_tx_t atl1e_xmit_frame(struct sk_buff *skb, | |||
1834 | return NETDEV_TX_OK; | 1853 | return NETDEV_TX_OK; |
1835 | } | 1854 | } |
1836 | 1855 | ||
1837 | atl1e_tx_map(adapter, skb, tpd); | 1856 | if (atl1e_tx_map(adapter, skb, tpd)) |
1857 | goto out; | ||
1858 | |||
1838 | atl1e_tx_queue(adapter, tpd_req, tpd); | 1859 | atl1e_tx_queue(adapter, tpd_req, tpd); |
1839 | 1860 | ||
1840 | netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ | 1861 | netdev->trans_start = jiffies; /* NETIF_F_LLTX driver :( */ |
1862 | out: | ||
1841 | spin_unlock_irqrestore(&adapter->tx_lock, flags); | 1863 | spin_unlock_irqrestore(&adapter->tx_lock, flags); |
1842 | return NETDEV_TX_OK; | 1864 | return NETDEV_TX_OK; |
1843 | } | 1865 | } |