DMA sync errors
Subsystems (5)
cover DMA sync errors
According to the DMA-API.txt
Synchronise a single contiguous or scatter/gather mapping. All the parameters must be the same as those passed into the single mapping API.
Reviewed the following drivers with potentail for this problem; those with - are ok, and the ones with + have a patch in this series.
+ drivers/infiniband/ulp/ipoib/ipoib_cm.c
- drivers/message/fusion/mptlan.c
- drivers/net/b44.c
- drivers/net/bnx2.c
+ drivers/net/cassini.c
- drivers/net/chelsio/sge.c
+ drivers/net/cxgb3/sge.c
- drivers/net/irda/vlsi_ir.c
- drivers/net/myri_sbus.c
+ drivers/net/r8169.c
+ drivers/net/rrunner.c
+ drivers/net/skge.c
+ drivers/net/sky2.c
+ drivers/net/sungem.c
+ drivers/net/sunhme.c
+ drivers/net/tg3.c
- drivers/net/tokenring/3c359.c
- drivers/net/tokenring/olympic.c
+ drivers/net/tulip/de2104x.c
- drivers/net/via-velocity.c
- drivers/net/wireless/ipw2x00/ipw2100.c
- drivers/net/wireless/ipw2x00/ipw2200.c
PATCH 11/11 ipoib: fix DMA sync_single length error
The DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/infiniband/ulp/ipoib/ipoib_cm.c +8 -4
@@ -624,11 +624,15 @@ void ipoib_cm_handle_rx_wc(struct net_de small_skb =dev_alloc_skb (dlen +12 );if (small_skb) {skb_reserve (small_skb,12 ); -ib_dma_sync_single_for_cpu (priv->ca, rx_ring[wr_id].mapping[0 ], - dlen,DMA_FROM_DEVICE ); +ib_dma_sync_single_for_cpu (priv->ca, + rx_ring[wr_id].mapping[0 ], +IPOIB_CM_HEAD_SIZE , +DMA_FROM_DEVICE );skb_copy_from_linear_data (skb, small_skb->data, dlen); -ib_dma_sync_single_for_device (priv->ca, rx_ring[wr_id].mapping[0 ], - dlen,DMA_FROM_DEVICE ); +ib_dma_sync_single_for_device (priv->ca, + rx_ring[wr_id].mapping[0 ], +IPOIB_CM_HEAD_SIZE , +DMA_FROM_DEVICE );skb_put (small_skb, dlen); skb = small_skb; goto copied;
Signature · 4 lines
-- To unsubscribe from this list: send the line "unsubscribe linux-rdma" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH 1/11 tg3: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/tg3.c +6 -2
@@ -4653,9 +4653,13 @@ static int tg3_rx(struct tg3_napi *tnapiskb_reserve (copy_skb,TG3_RAW_IP_ALIGN );skb_put (copy_skb, len); -pci_dma_sync_single_for_cpu (tp->pdev, dma_addr, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_cpu (tp->pdev, dma_addr, + tp->rx_pkt_map_sz, +PCI_DMA_FROMDEVICE );skb_copy_from_linear_data (skb, copy_skb->data, len); -pci_dma_sync_single_for_device (tp->pdev, dma_addr, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_device (tp->pdev, dma_addr, + tp->rx_pkt_map_sz, +PCI_DMA_FROMDEVICE );/* We'll reuse the original ring buffer. */ skb = copy_skb;
PATCH 2/11 sky2: fix DMA sync_single length error
In reply to Stephen HemmingerFrom: Jarek Poplawski <[email protected]>
Using pci_unmap_len(), with the same length as pci_map_single(), with pci_dma_sync_single_for_cpu()/_device() fixes this warning (2.6.32.4):
Quoted 6 lines
Jan 19 10:43:50 mail kernel: WARNING: at lib/dma-debug.c:902 check_sync+0xc1/0x43f() Jan 19 10:43:50 mail kernel: Hardware name: System Product Name Jan 19 10:43:50 mail kernel: sky2 0000:04:00.0: DMA-API: device drivertries to sync DMA memory it has not allocated [device address=0x0000000320a0b022] [size=60 bytes]
drivers/net/sky2.c +4 -2
@@ -2252,12 +2252,14 @@ static struct sk_buff *receive_copy(stru skb =netdev_alloc_skb_ip_align (sky2->netdev, length);if (likely (skb)) {pci_dma_sync_single_for_cpu (sky2->hw->pdev, re->data_addr, - length,PCI_DMA_FROMDEVICE ); +pci_unmap_len (re, data_size), +PCI_DMA_FROMDEVICE );skb_copy_from_linear_data (re->skb, skb->data, length); skb->ip_summed = re->skb->ip_summed; skb->csum = re->skb->csum;pci_dma_sync_single_for_device (sky2->hw->pdev, re->data_addr, - length,PCI_DMA_FROMDEVICE ); +pci_unmap_len (re, data_size), +PCI_DMA_FROMDEVICE ); re->skb->ip_summed =CHECKSUM_NONE ;skb_put (skb, length); }
Re: [PATCH 02/11] sky2: fix DMA sync_single length error
Quoted 12 lines · Stephen Hemminger
From: Jarek Poplawski <[email protected]>
Using
pci_unmap_len(), with the same length aspci_map_single(), with pci_dma_sync_single_for_cpu()/_device() fixes this warning (2.6.32.4):Quoted 6 lines
Jan 19 10:43:50 mail kernel: WARNING: at lib/dma-debug.c:902 check_sync+0xc1/0x43f() Jan 19 10:43:50 mail kernel: Hardware name: System Product Name Jan 19 10:43:50 mail kernel: sky2 0000:04:00.0: DMA-API: device drivertries to sync DMA memory it has not allocated [device address=0x0000000320a0b022] [size=60 bytes]
Quoted 4 lines
Reported-by Michael Breuer <[email protected]>Tested-by Michael Breuer <[email protected]>Signed-off-by Jarek Poplawski <[email protected]>
Thanks for acking and completing this, Stephen!
Jarek P.
Quoted 23 lines
drivers/net/sky2.c +4
-2@@ -2252,12 +2252,14 @@ static struct sk_buff *receive_copy(stru skb =netdev_alloc_skb_ip_align (sky2->netdev, length);if (likely (skb)) {pci_dma_sync_single_for_cpu (sky2->hw->pdev, re->data_addr, - length,PCI_DMA_FROMDEVICE ); +pci_unmap_len (re, data_size), +PCI_DMA_FROMDEVICE );skb_copy_from_linear_data (re->skb, skb->data, length); skb->ip_summed = re->skb->ip_summed; skb->csum = re->skb->csum;pci_dma_sync_single_for_device (sky2->hw->pdev, re->data_addr, - length,PCI_DMA_FROMDEVICE ); +pci_unmap_len (re, data_size), +PCI_DMA_FROMDEVICE ); re->skb->ip_summed =CHECKSUM_NONE ;skb_put (skb, length); }Signature · 1 line
--
David Miller
maintainerRe: [PATCH 02/11] sky2: fix DMA sync_single length error
From: Jarek Poplawski <[email protected]>
Date: Wed, 20 Jan 2010 22:32:59 +0100
Quoted 13 lines · Stephen Hemminger
Quoted 12 lines
From: Jarek Poplawski <[email protected]>
Using
pci_unmap_len(), with the same length aspci_map_single(), with pci_dma_sync_single_for_cpu()/_device() fixes this warning (2.6.32.4):Quoted 6 lines
Jan 19 10:43:50 mail kernel: WARNING: at lib/dma-debug.c:902 check_sync+0xc1/0x43f() Jan 19 10:43:50 mail kernel: Hardware name: System Product Name Jan 19 10:43:50 mail kernel: sky2 0000:04:00.0: DMA-API: device drivertries to sync DMA memory it has not allocated [device address=0x0000000320a0b022] [size=60 bytes]
Quoted 6 lines
Quoted 4 lines
Reported-by Michael Breuer <[email protected]>Tested-by Michael Breuer <[email protected]>Signed-off-by Jarek Poplawski <[email protected]>Thanks for acking and completing this, Stephen!
It's not a bug, lib/dma-debug.c and the DMA API documentation are both buggy.
I'm not applying any of this, the fix belongs in the infrastructure debugging and documentation not in the drivers, they are doing the correct and only reasonable thing.
Re: [PATCH 02/11] sky2: fix DMA sync_single length error
Quoted 21 lines · David Miller
From: Jarek Poplawski <[email protected]>
Date: Wed, 20 Jan 2010 22:32:59 +0100Quoted 18 lines · Stephen Hemminger
Quoted 16 lines
From: Jarek Poplawski <[email protected]>
Using
pci_unmap_len(), with the same length aspci_map_single(), with pci_dma_sync_single_for_cpu()/_device() fixes this warning (2.6.32.4):Quoted 6 lines
Jan 19 10:43:50 mail kernel: WARNING: at lib/dma-debug.c:902 check_sync+0xc1/0x43f() Jan 19 10:43:50 mail kernel: Hardware name: System Product Name Jan 19 10:43:50 mail kernel: sky2 0000:04:00.0: DMA-API: device drivertries to sync DMA memory it has not allocated [device address=0x0000000320a0b022] [size=60 bytes]
Reported-by Michael Breuer <[email protected]>Tested-by Michael Breuer <[email protected]>Signed-off-by Jarek Poplawski <[email protected]>
Quoted 8 lines
Quoted 1 line
Thanks for acking and completing this, Stephen!
It's not a bug,
lib/dma-debug.cand the DMA API documentation are both buggy.I'm not applying any of this, the fix belongs in the infrastructure debugging and documentation not in the drivers, they are doing the correct and only reasonable thing.
You might be 100% right, but why do you want users to pay for this even one day longer than necessary?
1) The warning was called "oops" by the reporter at the beginning, and it's meaningful; it frightens people at least.
2) Fixing this temporarily e.g. in sky2 looks safe and simple, while checking if it's more than a buggy warning needs time; and this:
"dma_sync_single_range(struct device *dev, dma_addr_t dma_handle,
unsigned long offset, size_t size, enum dma_data_direction direction)
Does a partial sync, starting at offset and continuing for size. You must be careful to observe the cache alignment and width when doing anything like this. You must also be extra careful about accessing memory you intend to sync partially." [Documentation/DMA-API.txt]
looks like even if implemented might be very tricky, especially if untested.
Jarek P.
David Miller
maintainerRe: [PATCH 02/11] sky2: fix DMA sync_single length error
From: Jarek Poplawski <[email protected]>
Date: Thu, 21 Jan 2010 00:21:02 +0100
Quoted 11 lines
"dma_sync_single_range(struct device *dev,
dma_addr_tdma_handle,
unsigned long offset,size_tsize, enumdma_data_directiondirection)Does a partial sync, starting at offset and continuing for size. You must be careful to observe the cache alignment and width when doing anything like this. You must also be extra careful about accessing memory you intend to sync partially." [
Documentation/DMA-API.txt]looks like even if implemented might be very tricky, especially if untested.
This is an absurd set of requirements. What driver author is going to get this right?
Any alignment issues are of the domain of the implementation and as Alan said should be handled there.
Back to the main issue, these localized fixes in the driver leave all of the other cases in the tree unhandled. There are likely to be SCSI, USB host controller, SOUND, and other drivers with the same issue.
At what point do we understand that peppering workarounds in the drivers is the wrong way to go about this?
Whereas 1 patch in the 1 place in the DMA API implementation would fix everything for everybody.
It's great that we had this report to track down the issue, now let's fix it correctly so nobody else (regardless of device they have) has to see it.
David Miller
maintainerRe: [PATCH 02/11] sky2: fix DMA sync_single length error
From: David Miller <[email protected]>
Date: Wed, 20 Jan 2010 15:34:51 -0800 (PST)
Quoted 2 lines
Whereas 1 patch in the 1 place in the DMA API implementation would fix everything for everybody.
For the record I just checked DMAR and Intel-IOMMU and they don't even implement the SYNC ops, they are NULL and thus can't be effected by the changes being discussed here.
The generic DMA SYNC operations check for a NULL function pointer in the DMA operations, and do nothing if it is NULL.
Thus, so far it is proven that only the DMA debugging code actually has this SYNC length requirement.
Re: [PATCH 02/11] sky2: fix DMA sync_single length error
Quoted 10 lines · David Miller
From: David Miller <[email protected]>
Date: Wed, 20 Jan 2010 15:34:51 -0800 (PST)Quoted 2 lines
Whereas 1 patch in the 1 place in the DMA API implementation would fix everything for everybody.
For the record I just checked DMAR and Intel-IOMMU and they don't even implement the SYNC ops, they are NULL and thus can't be effected by the changes being discussed here.
Quoted 5 lines
The generic DMA SYNC operations check for a NULL function pointer in the DMA operations, and do nothing if it is NULL.
Thus, so far it is proven that only the DMA debugging code actually has this SYNC length requirement.
Thanks, I feel at least 75% safer ;-)
Good night!
Jarek P.
Re: [PATCH 02/11] sky2: fix DMA sync_single length error
Quoted 11 lines · On Thu, 21 Jan 2010 00:59:20 +0100 Jarek Poplawski <[email protected]> wrote:
Quoted 10 lines · David Miller
From: David Miller <[email protected]>
Date: Wed, 20 Jan 2010 15:34:51 -0800 (PST)Quoted 2 lines
Whereas 1 patch in the 1 place in the DMA API implementation would fix everything for everybody.
For the record I just checked DMAR and Intel-IOMMU and they don't even implement the SYNC ops, they are NULL and thus can't be effected by the changes being discussed here.
Quoted 8 lines
Quoted 5 lines
The generic DMA SYNC operations check for a NULL function pointer in the DMA operations, and do nothing if it is NULL.
Thus, so far it is proven that only the DMA debugging code actually has this SYNC length requirement.
Thanks, I feel at least 75% safer ;-)
The usage of jumbo frames on the Marvell Yukon-2 chip version that Michael has is suspect. In order to do Jumbo frames, the driver has turns off the store-forward buffer; this reduces the window for transmit underrun, and triggers a problem. I suspect the unwind logic for transmit underrun is broken and may not be fixable without more hardware information. Turning off jumbo frame support for that chip type is probably the safest solution.
David Miller
maintainerRe: [PATCH 02/11] sky2: fix DMA sync_single length error
From: Stephen Hemminger <[email protected]>
Date: Wed, 20 Jan 2010 16:04:07 -0800
Quoted 7 lines
The usage of jumbo frames on the Marvell Yukon-2 chip version that Michael has is suspect. In order to do Jumbo frames, the driver has turns off the store-forward buffer; this reduces the window for transmit underrun, and triggers a problem. I suspect the unwind logic for transmit underrun is broken and may not be fixable without more hardware information. Turning off jumbo frame support for that chip type is probably the safest solution.
So let's do that.
Meanwhile I think the DMA debugging patch you posted earlier today need a little work, will reply there.
Re: [PATCH 02/11] sky2: fix DMA sync_single length error
In reply to David MillerQuoted 21 lines · David Miller
From: Jarek Poplawski <[email protected]>
Date: Thu, 21 Jan 2010 00:21:02 +0100Quoted 11 lines
"dma_sync_single_range(struct device *dev,
dma_addr_tdma_handle,
unsigned long offset,size_tsize, enumdma_data_directiondirection)Does a partial sync, starting at offset and continuing for size. You must be careful to observe the cache alignment and width when doing anything like this. You must also be extra careful about accessing memory you intend to sync partially." [
Documentation/DMA-API.txt]looks like even if implemented might be very tricky, especially if untested.
This is an absurd set of requirements. What driver author is going to get this right?
Any alignment issues are of the domain of the implementation and as Alan said should be handled there.
Quoted 7 lines
Back to the main issue, these localized fixes in the driver leave all of the other cases in the tree unhandled. There are likely to be SCSI, USB host controller, SOUND, and other drivers with the same issue.
At what point do we understand that peppering workarounds in the drivers is the wrong way to go about this?
*Temporary* only workarounds. Mainly simple cases. (e.g. I'm not sure of tg3)
Quoted 3 lines
Whereas 1 patch in the 1 place in the DMA API implementation would fix everything for everybody.
1) As I mentioned earlier there were similar dmar errors reported with real oopses, but of course it might be unconnected. (But why risk...)
2) Why would the author of this doc above warn us so much if it were so obviously simple and safe?
Quoted 4 lines
It's great that we had this report to track down the issue, now let's fix it correctly so nobody else (regardless of device they have) has to see it.
I hope you're right as usual! (But I disagree as usual ;-)
Jarek P.
David Miller
maintainerRe: [PATCH 02/11] sky2: fix DMA sync_single length error
From: Jarek Poplawski <[email protected]>
Date: Thu, 21 Jan 2010 00:52:45 +0100
Quoted 6 lines · David Miller
Quoted 2 lines
Whereas 1 patch in the 1 place in the DMA API implementation would fix everything for everybody.
1) As I mentioned earlier there were similar dmar errors reported with real oopses, but of course it might be unconnected. (But why risk...)
Show me the DMAR code that handles DMA SYNC requests.
There isn't any.
So it's impossible for this to fix things for DMAR users.
PATCH 3/11 skge: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/skge.c +4 -2
@@ -3078,11 +3078,13 @@ static struct sk_buff *skge_rx_get(strucpci_dma_sync_single_for_cpu (skge->hw->pdev,pci_unmap_addr (e, mapaddr), - len,PCI_DMA_FROMDEVICE ); +pci_unmap_len (e, maplen), +PCI_DMA_FROMDEVICE );skb_copy_from_linear_data (e->skb, skb->data, len);pci_dma_sync_single_for_device (skge->hw->pdev,pci_unmap_addr (e, mapaddr), - len,PCI_DMA_FROMDEVICE ); +pci_unmap_len (e, maplen), +PCI_DMA_FROMDEVICE );skge_rx_reuse (e, skge->rx_buf_size); }else {struct sk_buff *nskb;
PATCH 4/11 r8169: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
Get rid of unnecessary flag variable and move sync for device to logical place next to sync_for_cpu
drivers/net/r8169.c +8 -11
@@ -4437,22 +4437,21 @@ static inline bool rtl8169_try_rx_copy(s dma_addr_t addr) {struct sk_buff *skb; -bool done = false;if (pkt_size >= rx_copybreak) - goto out; +return false; skb =netdev_alloc_skb_ip_align (tp->dev, pkt_size);if (!skb) - goto out; +return false; -pci_dma_sync_single_for_cpu (tp->pci_dev, addr, pkt_size, +pci_dma_sync_single_for_cpu (tp->pci_dev, addr, tp->rx_buf_sz,PCI_DMA_FROMDEVICE );skb_copy_from_linear_data (*sk_buff, skb->data, pkt_size); *sk_buff = skb; - done = true; -out: -return done; +pci_dma_sync_single_for_device (tp->pci_dev, addr, tp->rx_buf_sz, +PCI_DMA_FROMDEVICE ); +return true; } static int rtl8169_rx_interrupt(struct net_device *dev,
@@ -4512,11 +4511,9 @@ static int rtl8169_rx_interrupt(struct nrtl8169_rx_csum (skb, desc); -if (rtl8169_try_rx_copy (&skb, tp, pkt_size, addr)) { -pci_dma_sync_single_for_device (pdev, addr, - pkt_size,PCI_DMA_FROMDEVICE ); +if (rtl8169_try_rx_copy (&skb, tp, pkt_size, addr))rtl8169_mark_to_asic (desc, tp->rx_buf_sz); - }else { +else {pci_unmap_single (pdev, addr, tp->rx_buf_sz,PCI_DMA_FROMDEVICE ); tp->Rx_skbuff[entry] =NULL ;
PATCH 5/11 rrunner: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/rrunner.c +2 -2
@@ -971,7 +971,7 @@ static void rx_int(struct net_device *de }else {pci_dma_sync_single_for_cpu (rrpriv->pci_dev, desc->addr.addrlo, - pkt_len, + dev->mtu +HIPPI_HLEN ,PCI_DMA_FROMDEVICE ); memcpy(skb_put(skb, pkt_len),
@@ -979,7 +979,7 @@ static void rx_int(struct net_device *depci_dma_sync_single_for_device (rrpriv->pci_dev, desc->addr.addrlo, - pkt_len, + dev->mtu +HIPPI_HLEN ,PCI_DMA_FROMDEVICE ); } }else {
PATCH 6/11 de2104x: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/tulip/de2104x.c +4 -2
@@ -456,11 +456,13 @@ static void de_rx (struct de_private *de buflen, PCI_DMA_FROMDEVICE); de->rx_skb[rx_tail].skb = copy_skb; }else { -pci_dma_sync_single_for_cpu (de->pdev, mapping, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_cpu (de->pdev, mapping, + buflen,PCI_DMA_FROMDEVICE );skb_reserve (copy_skb,RX_OFFSET );skb_copy_from_linear_data (skb,skb_put (copy_skb, len), len); -pci_dma_sync_single_for_device (de->pdev, mapping, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_device (de->pdev, mapping, + buflen,PCI_DMA_FROMDEVICE );/* We'll reuse the original ring buffer. */ skb = copy_skb;
Re: [PATCH 06/11] de2104x: fix DMA sync_single length error
Quoted 2 lines · Stephen Hemminger
The DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
Are you referring to the example code in Documentation/PCI/PCI-DMA-mapping.txt?
I don't see any "Use the full mapping" statement otherwise.
Is there a DMA HW implementation that requires the syncing full buffer?
I think it would be interesting to point that out in the commit comments since other NIC drivers are likely to also have this issue as well.
I have no objection to this patch. Just want to be clear why it's being pushed.
Please added Acked-by: Grant Grundler <[email protected]>
thanks,
grant
Quoted 23 lines
Signed-off-by Stephen Hemminger <[email protected]>drivers/net/tulip/de2104x.c +4
-2@@ -456,11 +456,13 @@ static void de_rx (struct de_private *de buflen, PCI_DMA_FROMDEVICE); de->rx_skb[rx_tail].skb = copy_skb; }else { -pci_dma_sync_single_for_cpu (de->pdev, mapping, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_cpu (de->pdev, mapping, + buflen,PCI_DMA_FROMDEVICE );skb_reserve (copy_skb,RX_OFFSET );skb_copy_from_linear_data (skb,skb_put (copy_skb, len), len); -pci_dma_sync_single_for_device (de->pdev, mapping, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_device (de->pdev, mapping, + buflen,PCI_DMA_FROMDEVICE );/* We'll reuse the original ring buffer. */ skb = copy_skb;Signature · 1 line
--
Re: [PATCH 06/11] de2104x: fix DMA sync_single length error
Quoted 10 lines · On Thu, 21 Jan 2010 18:02:44 -0700 Grant Grundler <[email protected]>…
Quoted 2 lines · Stephen Hemminger
The DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
Are you referring to the example code in
Documentation/PCI/PCI-DMA-mapping.txt?I don't see any "Use the full mapping" statement otherwise.
Is there a DMA HW implementation that requires the syncing full buffer?
Quoted 7 lines
I think it would be interesting to point that out in the commit comments since other NIC drivers are likely to also have this issue as well.
I have no objection to this patch. Just want to be clear why it's being pushed.
Please added Acked-by: Grant Grundler <[email protected]>
The documentation was in DMA-API.txt and it was wrong. The DMA debug library was enforcing a bogus restriction. Dave correctly dropped the patch.
PATCH 7/11 sungem: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/sungem.c +6 -2
@@ -847,9 +847,13 @@ static int gem_rx(struct gem *gp, int woskb_reserve (copy_skb,2 );skb_put (copy_skb, len); -pci_dma_sync_single_for_cpu (gp->pdev, dma_addr, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_cpu (gp->pdev, dma_addr, +RX_BUF_ALLOC_SIZE (gp), +PCI_DMA_FROMDEVICE );skb_copy_from_linear_data (skb, copy_skb->data, len); -pci_dma_sync_single_for_device (gp->pdev, dma_addr, len,PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_device (gp->pdev, dma_addr, +RX_BUF_ALLOC_SIZE (gp), +PCI_DMA_FROMDEVICE );/* We'll reuse the original ring buffer. */ skb = copy_skb;
PATCH 8/11 sunhme: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/sunhme.c +4 -2
@@ -2062,9 +2062,11 @@ static void happy_meal_rx(struct happy_mskb_reserve (copy_skb,2 );skb_put (copy_skb, len); -dma_sync_single_for_cpu (hp->dma_dev, dma_addr, len,DMA_FROM_DEVICE ); +dma_sync_single_for_cpu (hp->dma_dev, dma_addr, +RX_BUF_ALLOC_SIZE ,DMA_FROM_DEVICE );skb_copy_from_linear_data (skb, copy_skb->data, len); -dma_sync_single_for_device (hp->dma_dev, dma_addr, len,DMA_FROM_DEVICE ); +dma_sync_single_for_device (hp->dma_dev, dma_addr, +RX_BUF_ALLOC_SIZE ,DMA_FROM_DEVICE );/* Reuse original ring buffer. */ hme_write_rxd(hp, this, (RXFLAG_OWN|((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
PATCH 9/11 cassini: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/cassini.c +4 -4
@@ -2027,12 +2027,12 @@ static int cas_rx_process_pkt(struct cas i = hlen;if (!dlen)/* attach FCS */ i += cp->crc_size; -pci_dma_sync_single_for_cpu (cp->pdev, page->dma_addr + off, i, -PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_cpu (cp->pdev, page->dma_addr, + cp->page_size,PCI_DMA_FROMDEVICE ); addr =cas_page_map (page->buffer);memcpy (p, addr + off, i); -pci_dma_sync_single_for_device (cp->pdev, page->dma_addr + off, i, -PCI_DMA_FROMDEVICE ); +pci_dma_sync_single_for_device (cp->pdev, page->dma_addr, + cp->page_size,PCI_DMA_FROMDEVICE );cas_page_unmap (addr);RX_USED_ADD (page,0x100 ); p += hlen;
PATCH 10/11 cxgb3: fix DMA sync_single length error
In reply to Stephen HemmingerThe DMA api requires that the full mapping be sync'd when copying frame. First found by Jarek on sky2.
drivers/net/cxgb3/sge.c +7 -4
@@ -788,12 +788,15 @@ static struct sk_buff *get_packet(structif (likely (skb !=NULL )) {__skb_put (skb, len);pci_dma_sync_single_for_cpu (adap->pdev, -pci_unmap_addr (sd, dma_addr), len, -PCI_DMA_FROMDEVICE ); +pci_unmap_addr (sd, dma_addr), + fl->alloc_size, + +PCI_DMA_FROMDEVICE );memcpy (skb->data, sd->skb->data, len);pci_dma_sync_single_for_device (adap->pdev, -pci_unmap_addr (sd, dma_addr), len, -PCI_DMA_FROMDEVICE ); +pci_unmap_addr (sd, dma_addr), + fl->alloc_size, +PCI_DMA_FROMDEVICE ); }else if (!drop_thres) goto use_orig_buf; recycle:
David Miller
maintainerFrom: Stephen Hemminger <[email protected]>
Date: Wed, 20 Jan 2010 12:44:59 -0800
Quoted 4 lines
According to the DMA-API.txt
Synchronise a single contiguous or scatter/gather mapping. All the parameters must be the same as those passed into the single mapping API.
I think this is unreasonable.
And it's going to kill performance for reception of small packets.
We might as well not do RX copybreak in any of these drivers any more if we have to DMA sync the whole thing.
I think better to look at the various implementations of DMA APIs, I bet they all handle this case just fine. And those that don't are easily fixed. Then the documentation can be updated to match and we can forget these crazy patches.
This should fix the dma-debug API code (and documentation), to avoid false positives when sync is done on a partial map.
Documentation/DMA-API.txt +4 -3
@@ -377,9 +377,10 @@ void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int direction) -Synchronise a single contiguous or scatter/gather mapping. All the -parameters must be the same as those passed into the single mapping -API. +Synchronise a single contiguous or scatter/gather mapping. The +device and handle must be the same as those passed into the single mapping +API. The size can be less than the original mapping if only part +of the mapping needs to be accessed. Notes: You must do this:
lib/dma-debug.c +2 -4
@@ -285,11 +285,9 @@ static struct dma_debug_entry *hash_buck }/* -* If we have multiple matches but no perfect-fit, just return -* NULL. +* If we have multiple matches but no perfect-fit +* return best value and let caller deal with it. */ - ret = (matches ==1 ) ? ret :NULL ; -return ret; }
David Miller
maintainerFrom: Stephen Hemminger <[email protected]>
Date: Wed, 20 Jan 2010 15:28:32 -0800
Quoted 4 lines
This should fix the dma-debug API code (and documentation), to avoid false positives when sync is done on a partial map.
Signed-off-by Stephen Hemminger <[email protected]>
...
Quoted 6 lines
lib/dma-debug.c +0
-0@@ -285,11 +285,9 @@ static struct dma_debug_entry *hash_buck }/*
lib/dma-debug.c static struct dma_debug_entry *hash_buck · line 293
Quoted 10 lines
lib/dma-debug.c +2
-4-* If we have multiple matches but no perfect-fit, just return -* NULL. +* If we have multiple matches but no perfect-fit +* return best value and let caller deal with it. */ - ret = (matches ==1 ) ? ret :NULL ; -return ret; }
I think you have to enforce a perfect-fit match for the non-SYNC cases.
check_sync() can pass in 'true' for a new bool argument "partial_ok" added to hash_bucket_find() whereas check_unmap() can pass 'false'.
get_nr_mapped_entries() should pass 'false' as well.
Quoted 28 lines · On Wed, 20 Jan 2010 16:18:05 -0800 (PST) David Miller <[email protected]>…
From: Stephen Hemminger <[email protected]>
Date: Wed, 20 Jan 2010 15:28:32 -0800Quoted 4 lines
This should fix the dma-debug API code (and documentation), to avoid false positives when sync is done on a partial map.
Signed-off-by Stephen Hemminger <[email protected]>...
Quoted 6 lines
lib/dma-debug.c +0
-0@@ -285,11 +285,9 @@ static struct dma_debug_entry *hash_buck }/* lib/dma-debug.c static struct dma_debug_entry *hash_buck · line 293
Quoted 10 lines
lib/dma-debug.c +2
-4-* If we have multiple matches but no perfect-fit, just return -* NULL. +* If we have multiple matches but no perfect-fit +* return best value and let caller deal with it. */ - ret = (matches ==1 ) ? ret :NULL ; -return ret; }I think you have to enforce a perfect-fit match for the non-SYNC cases.
Quoted 4 lines
check_sync()can pass in 'true' for a new bool argument "partial_ok" added tohash_bucket_find()whereascheck_unmap()can pass 'false'.
get_nr_mapped_entries()should pass 'false' as well.
check_unmap has checks for different size, different type, call_ents, direction etc.
The code for get_nr_mapped_entries() is the only question; it is used by unmap_sg() and probably needs perfect match only.
David Miller
maintainerFrom: Stephen Hemminger <[email protected]>
Date: Wed, 20 Jan 2010 16:34:10 -0800
Quoted 5 lines
check_unmaphas checks for different size, different type,call_ents, direction etc.The code for
get_nr_mapped_entries()is the only question; it is used byunmap_sg()and probably needs perfect match only.
Ok.
Quoted 34 lines · Stephen Hemminger
Quoted 31 lines · On Wed, 20 Jan 2010 16:18:05 -0800 (PST) David Miller <[email protected]>…
From: Stephen Hemminger <[email protected]>
Date: Wed, 20 Jan 2010 15:28:32 -0800Quoted 4 lines
This should fix the dma-debug API code (and documentation), to avoid false positives when sync is done on a partial map.
Signed-off-by Stephen Hemminger <[email protected]>...
Quoted 6 lines
lib/dma-debug.c +0
-0@@ -285,11 +285,9 @@ static struct dma_debug_entry *hash_buck }/* lib/dma-debug.c static struct dma_debug_entry *hash_buck · line 293
Quoted 10 lines
lib/dma-debug.c +2
-4-* If we have multiple matches but no perfect-fit, just return -* NULL. +* If we have multiple matches but no perfect-fit +* return best value and let caller deal with it. */ - ret = (matches ==1 ) ? ret :NULL ; -return ret; }I think you have to enforce a perfect-fit match for the non-SYNC cases.
check_sync()can pass in 'true' for a new bool argument "partial_ok" added tohash_bucket_find()whereascheck_unmap()can pass 'false'.
Quoted 8 lines
Quoted 1 line
get_nr_mapped_entries()should pass 'false' as well.
check_unmaphas checks for different size, different type,call_ents, direction etc.The code for
get_nr_mapped_entries()is the only question; it is used byunmap_sg()and probably needs perfect match only.
Hmm... After looking at it more, mainly dma_sync_single_range() implementations, I didn't find any reasons for these comments in DMA-API.txt, but even if I missed something, this patch definitely shows these lib/dma-debug warnings are buggy if they depend on the number of mapped entries (while otherwise ref->size < entry->size isn't reported). Btw, it seems code should try to return minimum entry->size for such a check.
Thanks Stephen, now I feel 99.9% safe ;-)
Sorry for mistrust, David!
Jarek P.
David Miller
maintainerFrom: Jarek Poplawski <[email protected]>
Date: Thu, 21 Jan 2010 12:44:23 +0000
Quoted 1 line
Sorry for mistrust, David!
That's twice in the past week Jarek.
One more and you will be in real troubles :-)