]>
Commit | Line | Data |
---|---|---|
632d9a26 GKH |
1 | From 94c5b41b327e08de0ddf563237855f55080652a1 Mon Sep 17 00:00:00 2001 |
2 | From: Guo-Fu Tseng <cooldavid@cooldavid.org> | |
3 | Date: Wed, 20 Jul 2011 16:57:36 +0000 | |
4 | Subject: jme: Fix unmap error (Causing system freeze) | |
5 | ||
6 | From: Guo-Fu Tseng <cooldavid@cooldavid.org> | |
7 | ||
8 | commit 94c5b41b327e08de0ddf563237855f55080652a1 upstream. | |
9 | ||
10 | This patch add the missing dma_unmap(). | |
11 | Which solved the critical issue of system freeze on heavy load. | |
12 | ||
13 | Michal Miroslaw's rejected patch: | |
14 | [PATCH v2 10/46] net: jme: convert to generic DMA API | |
15 | Pointed out the issue also, thank you Michal. | |
16 | But the fix was incorrect. It would unmap needed address | |
17 | when low memory. | |
18 | ||
19 | Got lots of feedback from End user and Gentoo Bugzilla. | |
20 | https://bugs.gentoo.org/show_bug.cgi?id=373109 | |
21 | Thank you all. :) | |
22 | ||
23 | Signed-off-by: Guo-Fu Tseng <cooldavid@cooldavid.org> | |
24 | Acked-by: Chris Wright <chrisw@sous-sol.org> | |
25 | Signed-off-by: David S. Miller <davem@davemloft.net> | |
26 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
27 | ||
28 | --- | |
29 | drivers/net/jme.c | 20 ++++++++++++++------ | |
30 | 1 file changed, 14 insertions(+), 6 deletions(-) | |
31 | ||
32 | --- a/drivers/net/jme.c | |
33 | +++ b/drivers/net/jme.c | |
34 | @@ -753,20 +753,28 @@ jme_make_new_rx_buf(struct jme_adapter * | |
35 | struct jme_ring *rxring = &(jme->rxring[0]); | |
36 | struct jme_buffer_info *rxbi = rxring->bufinf + i; | |
37 | struct sk_buff *skb; | |
38 | + dma_addr_t mapping; | |
39 | ||
40 | skb = netdev_alloc_skb(jme->dev, | |
41 | jme->dev->mtu + RX_EXTRA_LEN); | |
42 | if (unlikely(!skb)) | |
43 | return -ENOMEM; | |
44 | ||
45 | + mapping = pci_map_page(jme->pdev, virt_to_page(skb->data), | |
46 | + offset_in_page(skb->data), skb_tailroom(skb), | |
47 | + PCI_DMA_FROMDEVICE); | |
48 | + if (unlikely(pci_dma_mapping_error(jme->pdev, mapping))) { | |
49 | + dev_kfree_skb(skb); | |
50 | + return -ENOMEM; | |
51 | + } | |
52 | + | |
53 | + if (likely(rxbi->mapping)) | |
54 | + pci_unmap_page(jme->pdev, rxbi->mapping, | |
55 | + rxbi->len, PCI_DMA_FROMDEVICE); | |
56 | + | |
57 | rxbi->skb = skb; | |
58 | rxbi->len = skb_tailroom(skb); | |
59 | - rxbi->mapping = pci_map_page(jme->pdev, | |
60 | - virt_to_page(skb->data), | |
61 | - offset_in_page(skb->data), | |
62 | - rxbi->len, | |
63 | - PCI_DMA_FROMDEVICE); | |
64 | - | |
65 | + rxbi->mapping = mapping; | |
66 | return 0; | |
67 | } | |
68 |