* 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function @ 2009-04-09 12:36 Alexander Beregalov 2009-04-15 12:39 ` Alexander Beregalov 0 siblings, 1 reply; 8+ messages in thread From: Alexander Beregalov @ 2009-04-09 12:36 UTC (permalink / raw) To: Kernel Testers List, LKML, dan.j.williams, maciej.sosnowski ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 ioatdma 0000:00:08.0: setting latency timer to 64 ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, device version 0x12, driver version 3.64 alloc irq_desc for 33 on cpu 0 node 0 alloc kstat_irqs on cpu 0 node 0 ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X ------------[ cut here ]------------ WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() Hardware name: PowerEdge 1950 ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with wrong function [device address=0x000000007f76f800] [size=2000 bytes] [map ped as single] [unmapped as page] Modules linked in: Pid: 1, comm: swapper Not tainted 2.6.30-rc1-00089-gf4efdd6-dirty #96 Call Trace: <IRQ> [<ffffffff8024f9e8>] warn_slowpath+0xe8/0x160 [<ffffffff8028064e>] ? save_trace+0x4e/0xe0 [<ffffffff80280747>] ? add_lock_to_list+0x67/0x110 [<ffffffff80282801>] ? check_irq_usage+0xb1/0x110 [<ffffffff804ea272>] ? check_unmap+0x122/0x6a0 [<ffffffff8027fbc1>] ? put_lock_stats+0x21/0x60 [<ffffffff804ea272>] ? check_unmap+0x122/0x6a0 [<ffffffff806db2d9>] ? _spin_lock_irqsave+0x89/0xb0 [<ffffffff804ea272>] ? check_unmap+0x122/0x6a0 [<ffffffff804ea446>] check_unmap+0x2f6/0x6a0 [<ffffffff804eab1e>] debug_dma_unmap_page+0x5e/0x80 [<ffffffff8061c446>] ioat_dma_unmap+0xd6/0x160 [<ffffffff8061c7a2>] ioat_dma_memcpy_cleanup+0x2d2/0x3f0 [<ffffffff802560e4>] ? tasklet_action+0x84/0x160 [<ffffffff8061c8e0>] ioat_dma_cleanup_tasklet+0x20/0x50 [<ffffffff80283430>] ? trace_hardirqs_on+0x20/0x40 [<ffffffff80256115>] tasklet_action+0xb5/0x160 [<ffffffff802567dc>] __do_softirq+0x9c/0x150 [<ffffffff806db92f>] ? _spin_unlock+0x3f/0x80 [<ffffffff8020cbfc>] call_softirq+0x1c/0x30 [<ffffffff8020f30d>] do_softirq+0x8d/0xe0 [<ffffffff80256465>] irq_exit+0xc5/0xe0 [<ffffffff8020e77d>] do_IRQ+0x9d/0x120 [<ffffffff8020c413>] ret_from_intr+0x0/0xf <EOI> [<ffffffff806d8591>] ? schedule_timeout+0x1/0x220 [<ffffffff806d74a9>] ? wait_for_common+0x129/0x1c0 [<ffffffff802460a0>] ? default_wake_function+0x0/0x40 [<ffffffff806d7641>] ? wait_for_completion_timeout+0x21/0x40 [<ffffffff8061d58a>] ? ioat_dma_probe+0x80a/0xdf0 [<ffffffff806d73d2>] ? wait_for_common+0x52/0x1c0 [<ffffffff806d53b5>] ? ioat_probe+0x175/0x280 [<ffffffff804f3fe5>] ? local_pci_probe+0x25/0x40 [<ffffffff804f43e0>] ? pci_device_probe+0xa0/0xd0 [<ffffffff8057737c>] ? driver_probe_device+0xdc/0x2f0 [<ffffffff80577643>] ? __driver_attach+0xb3/0xc0 [<ffffffff80577590>] ? __driver_attach+0x0/0xc0 [<ffffffff805767bb>] ? bus_for_each_dev+0x7b/0xc0 [<ffffffff8057704f>] ? driver_attach+0x2f/0x50 [<ffffffff80575d85>] ? bus_add_driver+0x175/0x2c0 [<ffffffff80905ea0>] ? ioat_init_module+0x0/0x50 [<ffffffff80577a5f>] ? driver_register+0x8f/0x190 [<ffffffff80905ea0>] ? ioat_init_module+0x0/0x50 [<ffffffff804f4889>] ? __pci_register_driver+0x79/0x110 [<ffffffff806175f9>] ? cpuidle_register_governor+0xe9/0x100 [<ffffffff80905ea0>] ? ioat_init_module+0x0/0x50 [<ffffffff80905ecc>] ? ioat_init_module+0x2c/0x50 [<ffffffff8020907b>] ? do_one_initcall+0x4b/0x1a0 [<ffffffff80330000>] ? __mb_cache_entry_forget+0x20/0xa0 [<ffffffff808db88b>] ? kernel_init+0x1ae/0x250 [<ffffffff8020cafa>] ? child_rip+0xa/0x20 [<ffffffff8020c4c0>] ? restore_args+0x0/0x30 [<ffffffff808db6dd>] ? kernel_init+0x0/0x250 [<ffffffff8020caf0>] ? child_rip+0x0/0x20 ---[ end trace 66cfcd7e86ff08dc ]--- Mapped at: [<ffffffff804e9f05>] debug_dma_map_page+0x95/0x190 [<ffffffff8061d4e7>] ioat_dma_probe+0x767/0xdf0 [<ffffffff806d53b5>] ioat_probe+0x175/0x280 [<ffffffff804f3fe5>] local_pci_probe+0x25/0x40 [<ffffffff804f43e0>] pci_device_probe+0xa0/0xd0 ioatdma 0000:00:08.0: DCA is disabled in BIOS ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function 2009-04-09 12:36 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function Alexander Beregalov @ 2009-04-15 12:39 ` Alexander Beregalov 2009-04-15 17:27 ` Dan Williams 0 siblings, 1 reply; 8+ messages in thread From: Alexander Beregalov @ 2009-04-15 12:39 UTC (permalink / raw) To: Kernel Testers List, LKML, dan.j.williams, maciej.sosnowski 2009/4/9 Alexander Beregalov <a.beregalov@gmail.com>: > ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 > ioatdma 0000:00:08.0: setting latency timer to 64 > ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, > device version 0x12, driver version 3.64 > alloc irq_desc for 33 on cpu 0 node 0 > alloc kstat_irqs on cpu 0 node 0 > ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X > ------------[ cut here ]------------ > WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() > Hardware name: PowerEdge 1950 > ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with > wrong function [device address=0x000000007f76f800] [size=2000 bytes] > [map > ped as single] [unmapped as page] The problem still persists. ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function 2009-04-15 12:39 ` Alexander Beregalov @ 2009-04-15 17:27 ` Dan Williams 2009-04-17 2:38 ` FUJITA Tomonori 2009-04-17 11:49 ` Sosnowski, Maciej 0 siblings, 2 replies; 8+ messages in thread From: Dan Williams @ 2009-04-15 17:27 UTC (permalink / raw) To: Alexander Beregalov; +Cc: Kernel Testers List, LKML, maciej.sosnowski On Wed, Apr 15, 2009 at 5:39 AM, Alexander Beregalov <a.beregalov@gmail.com> wrote: > 2009/4/9 Alexander Beregalov <a.beregalov@gmail.com>: >> ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 >> ioatdma 0000:00:08.0: setting latency timer to 64 >> ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, >> device version 0x12, driver version 3.64 >> alloc irq_desc for 33 on cpu 0 node 0 >> alloc kstat_irqs on cpu 0 node 0 >> ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X >> ------------[ cut here ]------------ >> WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() >> Hardware name: PowerEdge 1950 >> ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with >> wrong function [device address=0x000000007f76f800] [size=2000 bytes] >> [map >> ped as single] [unmapped as page] > > The problem still persists. Thanks for the report Alexander. Maciej and I are looking into a fix. Regards, Dan ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function 2009-04-15 17:27 ` Dan Williams @ 2009-04-17 2:38 ` FUJITA Tomonori 2009-04-17 11:49 ` Sosnowski, Maciej 1 sibling, 0 replies; 8+ messages in thread From: FUJITA Tomonori @ 2009-04-17 2:38 UTC (permalink / raw) To: dan.j.williams Cc: a.beregalov, kernel-testers, linux-kernel, maciej.sosnowski On Wed, 15 Apr 2009 10:27:48 -0700 Dan Williams <dan.j.williams@intel.com> wrote: > On Wed, Apr 15, 2009 at 5:39 AM, Alexander Beregalov > <a.beregalov@gmail.com> wrote: > > 2009/4/9 Alexander Beregalov <a.beregalov@gmail.com>: > >> ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 > >> ioatdma 0000:00:08.0: setting latency timer to 64 > >> ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, > >> device version 0x12, driver version 3.64 > >> alloc irq_desc for 33 on cpu 0 node 0 > >> alloc kstat_irqs on cpu 0 node 0 > >> ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X > >> ------------[ cut here ]------------ > >> WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() > >> Hardware name: PowerEdge 1950 > >> ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with > >> wrong function [device address=0x000000007f76f800] [size=2000 bytes] > >> [map > >> ped as single] [unmapped as page] > > > > The problem still persists. > > Thanks for the report Alexander. Maciej and I are looking into a fix. Looks like the driver uses pci_unmap_page() to unmap the region previously mapped by dma_map_single(), right? It's not the proper usage of DMA API but it doesn't cause any problems. This is not a urgent issue though it's better to fix it. ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function 2009-04-15 17:27 ` Dan Williams 2009-04-17 2:38 ` FUJITA Tomonori @ 2009-04-17 11:49 ` Sosnowski, Maciej 2009-04-17 12:01 ` Alexander Beregalov 1 sibling, 1 reply; 8+ messages in thread From: Sosnowski, Maciej @ 2009-04-17 11:49 UTC (permalink / raw) To: Williams, Dan J, Alexander Beregalov; +Cc: Kernel Testers List, LKML Dan Williams wrote: > On Wed, Apr 15, 2009 at 5:39 AM, Alexander Beregalov > <a.beregalov@gmail.com> wrote: >> 2009/4/9 Alexander Beregalov <a.beregalov@gmail.com>: >>> ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 >>> ioatdma 0000:00:08.0: setting latency timer to 64 >>> ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, >>> device version 0x12, driver version 3.64 >>> alloc irq_desc for 33 on cpu 0 node 0 >>> alloc kstat_irqs on cpu 0 node 0 >>> ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X >>> ------------[ cut here ]------------ >>> WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() >>> Hardware name: PowerEdge 1950 >>> ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with >>> wrong function [device address=0x000000007f76f800] [size=2000 bytes] [map >>> ped as single] [unmapped as page] >> >> The problem still persists. > > Thanks for the report Alexander. Maciej and I are looking into a fix. > > Regards, > Dan Hi Alexander, Could you check if the following patch helps? Thanks, Maciej --- drivers/dma/dmaengine.c | 17 +++++++++++------ drivers/dma/ioat_dma.c | 41 +++++++++++++++++++++++++---------------- include/linux/dmaengine.h | 6 ++++++ 3 files changed, 42 insertions(+), 22 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 92438e9..5a87384 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -804,11 +804,14 @@ dma_async_memcpy_buf_to_buf(struct dma_c dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE); dma_dest = dma_map_single(dev->dev, dest, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK | + DMA_COMPL_SRC_UNMAP_SINGLE | + DMA_COMPL_DEST_UNMAP_SINGLE; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE); @@ -850,11 +853,12 @@ dma_async_memcpy_buf_to_pg(struct dma_ch dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_single(dev->dev, kdata, len, DMA_TO_DEVICE); dma_dest = dma_map_page(dev->dev, page, offset, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK | DMA_COMPL_SRC_UNMAP_SINGLE; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE); @@ -898,12 +902,13 @@ dma_async_memcpy_pg_to_pg(struct dma_cha dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_page(dev->dev, src_pg, src_off, len, DMA_TO_DEVICE); dma_dest = dma_map_page(dev->dev, dest_pg, dest_off, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_page(dev->dev, dma_src, len, DMA_TO_DEVICE); diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index e4fc33c..9d7db7c 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c @@ -1063,22 +1063,31 @@ static void ioat_dma_cleanup_tasklet(uns static void ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc) { - /* - * yes we are unmapping both _page and _single - * alloc'd regions with unmap_page. Is this - * *really* that bad? - */ - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, dst), - pci_unmap_len(desc, len), - PCI_DMA_FROMDEVICE); - - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, src), - pci_unmap_len(desc, len), - PCI_DMA_TODEVICE); + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { + if (desc->async_tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE) + pci_unmap_single(ioat_chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, len), + PCI_DMA_FROMDEVICE); + else + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, len), + PCI_DMA_FROMDEVICE); + } + + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { + if (desc->async_tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE) + pci_unmap_single(ioat_chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, len), + PCI_DMA_TODEVICE); + else + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, len), + PCI_DMA_TODEVICE); + } } /** diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 2e2aa3d..dc3235a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -78,12 +78,18 @@ #define DMA_TX_TYPE_END (DMA_SLAVE + 1) * dependency chains * @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s) * @DMA_COMPL_SKIP_DEST_UNMAP - set to disable dma-unmapping the destination(s) + * @DMA_COMPL_SRC_UNMAP_SINGLE - set to do the source dma-unmapping as single + * (if not set, do the source dma-unmapping as page) + * @DMA_COMPL_DEST_UNMAP_SINGLE - set to do the destination dma-unmapping as single + * (if not set, do the destination dma-unmapping as page) */ enum dma_ctrl_flags { DMA_PREP_INTERRUPT = (1 << 0), DMA_CTRL_ACK = (1 << 1), DMA_COMPL_SKIP_SRC_UNMAP = (1 << 2), DMA_COMPL_SKIP_DEST_UNMAP = (1 << 3), + DMA_COMPL_SRC_UNMAP_SINGLE = (1 << 4), + DMA_COMPL_DEST_UNMAP_SINGLE = (1 << 5), }; /** ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function 2009-04-17 11:49 ` Sosnowski, Maciej @ 2009-04-17 12:01 ` Alexander Beregalov 2009-04-22 14:58 ` Sosnowski, Maciej 0 siblings, 1 reply; 8+ messages in thread From: Alexander Beregalov @ 2009-04-17 12:01 UTC (permalink / raw) To: Sosnowski, Maciej; +Cc: Williams, Dan J, Kernel Testers List, LKML 2009/4/17 Sosnowski, Maciej <maciej.sosnowski@intel.com>: > Dan Williams wrote: >> On Wed, Apr 15, 2009 at 5:39 AM, Alexander Beregalov >> <a.beregalov@gmail.com> wrote: >>> 2009/4/9 Alexander Beregalov <a.beregalov@gmail.com>: >>>> ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 >>>> ioatdma 0000:00:08.0: setting latency timer to 64 >>>> ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, >>>> device version 0x12, driver version 3.64 >>>> alloc irq_desc for 33 on cpu 0 node 0 >>>> alloc kstat_irqs on cpu 0 node 0 >>>> ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X >>>> ------------[ cut here ]------------ >>>> WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() >>>> Hardware name: PowerEdge 1950 >>>> ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with >>>> wrong function [device address=0x000000007f76f800] [size=2000 bytes] [map >>>> ped as single] [unmapped as page] >>> >>> The problem still persists. >> >> Thanks for the report Alexander. Maciej and I are looking into a fix. >> >> Regards, >> Dan > > Hi Alexander, > > Could you check if the following patch helps? Hi Maciej. No, unfortunately it does not help. The same warning message. ^ permalink raw reply [flat|nested] 8+ messages in thread
* RE: 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function 2009-04-17 12:01 ` Alexander Beregalov @ 2009-04-22 14:58 ` Sosnowski, Maciej 2009-04-22 15:48 ` Alexander Beregalov 0 siblings, 1 reply; 8+ messages in thread From: Sosnowski, Maciej @ 2009-04-22 14:58 UTC (permalink / raw) To: Alexander Beregalov; +Cc: Williams, Dan J, Kernel Testers List, LKML Alexander Beregalov wrote: > 2009/4/17 Sosnowski, Maciej <maciej.sosnowski@intel.com>: >> Dan Williams wrote: >>> On Wed, Apr 15, 2009 at 5:39 AM, Alexander Beregalov >>> <a.beregalov@gmail.com> wrote: >>>> 2009/4/9 Alexander Beregalov <a.beregalov@gmail.com>: >>>>> ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 >>>>> ioatdma 0000:00:08.0: setting latency timer to 64 >>>>> ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, >>>>> device version 0x12, driver version 3.64 >>>>> alloc irq_desc for 33 on cpu 0 node 0 >>>>> alloc kstat_irqs on cpu 0 node 0 >>>>> ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X >>>>> ------------[ cut here ]------------ >>>>> WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() >>>>> Hardware name: PowerEdge 1950 >>>>> ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with >>>>> wrong function [device address=0x000000007f76f800] [size=2000 bytes] [map >>>>> ped as single] [unmapped as page] >>>> >>>> The problem still persists. >>> >>> Thanks for the report Alexander. Maciej and I are looking into a fix. >>> >>> Regards, >>> Dan >> >> Hi Alexander, >> >> Could you check if the following patch helps? > > Hi Maciej. > > No, unfortunately it does not help. The same warning message. Ok, I have missed to cover self_test case. How about this one instead? Thanks, Maciej --- drivers/dma/dmaengine.c | 17 +++++++++++------ drivers/dma/ioat_dma.c | 45 ++++++++++++++++++++++++++++----------------- include/linux/dmaengine.h | 6 ++++++ 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 92438e9..5a87384 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c @@ -804,11 +804,14 @@ dma_async_memcpy_buf_to_buf(struct dma_c dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_single(dev->dev, src, len, DMA_TO_DEVICE); dma_dest = dma_map_single(dev->dev, dest, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK | + DMA_COMPL_SRC_UNMAP_SINGLE | + DMA_COMPL_DEST_UNMAP_SINGLE; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE); @@ -850,11 +853,12 @@ dma_async_memcpy_buf_to_pg(struct dma_ch dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_single(dev->dev, kdata, len, DMA_TO_DEVICE); dma_dest = dma_map_page(dev->dev, page, offset, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK | DMA_COMPL_SRC_UNMAP_SINGLE; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_single(dev->dev, dma_src, len, DMA_TO_DEVICE); @@ -898,12 +902,13 @@ dma_async_memcpy_pg_to_pg(struct dma_cha dma_addr_t dma_dest, dma_src; dma_cookie_t cookie; int cpu; + unsigned long flags; dma_src = dma_map_page(dev->dev, src_pg, src_off, len, DMA_TO_DEVICE); dma_dest = dma_map_page(dev->dev, dest_pg, dest_off, len, DMA_FROM_DEVICE); - tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, - DMA_CTRL_ACK); + flags = DMA_CTRL_ACK; + tx = dev->device_prep_dma_memcpy(chan, dma_dest, dma_src, len, flags); if (!tx) { dma_unmap_page(dev->dev, dma_src, len, DMA_TO_DEVICE); diff --git a/drivers/dma/ioat_dma.c b/drivers/dma/ioat_dma.c index e4fc33c..1955ee8 100644 --- a/drivers/dma/ioat_dma.c +++ b/drivers/dma/ioat_dma.c @@ -1063,22 +1063,31 @@ static void ioat_dma_cleanup_tasklet(uns static void ioat_dma_unmap(struct ioat_dma_chan *ioat_chan, struct ioat_desc_sw *desc) { - /* - * yes we are unmapping both _page and _single - * alloc'd regions with unmap_page. Is this - * *really* that bad? - */ - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, dst), - pci_unmap_len(desc, len), - PCI_DMA_FROMDEVICE); - - if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) - pci_unmap_page(ioat_chan->device->pdev, - pci_unmap_addr(desc, src), - pci_unmap_len(desc, len), - PCI_DMA_TODEVICE); + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_DEST_UNMAP)) { + if (desc->async_tx.flags & DMA_COMPL_DEST_UNMAP_SINGLE) + pci_unmap_single(ioat_chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, len), + PCI_DMA_FROMDEVICE); + else + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, dst), + pci_unmap_len(desc, len), + PCI_DMA_FROMDEVICE); + } + + if (!(desc->async_tx.flags & DMA_COMPL_SKIP_SRC_UNMAP)) { + if (desc->async_tx.flags & DMA_COMPL_SRC_UNMAP_SINGLE) + pci_unmap_single(ioat_chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, len), + PCI_DMA_TODEVICE); + else + pci_unmap_page(ioat_chan->device->pdev, + pci_unmap_addr(desc, src), + pci_unmap_len(desc, len), + PCI_DMA_TODEVICE); + } } /** @@ -1363,6 +1372,7 @@ static int ioat_dma_self_test(struct ioa int err = 0; struct completion cmp; unsigned long tmo; + unsigned long flags; src = kzalloc(sizeof(u8) * IOAT_TEST_SIZE, GFP_KERNEL); if (!src) @@ -1392,8 +1402,9 @@ static int ioat_dma_self_test(struct ioa DMA_TO_DEVICE); dma_dest = dma_map_single(dma_chan->device->dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE); + flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_DEST_UNMAP_SINGLE; tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src, - IOAT_TEST_SIZE, 0); + IOAT_TEST_SIZE, flags); if (!tx) { dev_err(&device->pdev->dev, "Self-test prep failed, disabling\n"); diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h index 2e2aa3d..dc3235a 100644 --- a/include/linux/dmaengine.h +++ b/include/linux/dmaengine.h @@ -78,12 +78,18 @@ #define DMA_TX_TYPE_END (DMA_SLAVE + 1) * dependency chains * @DMA_COMPL_SKIP_SRC_UNMAP - set to disable dma-unmapping the source buffer(s) * @DMA_COMPL_SKIP_DEST_UNMAP - set to disable dma-unmapping the destination(s) + * @DMA_COMPL_SRC_UNMAP_SINGLE - set to do the source dma-unmapping as single + * (if not set, do the source dma-unmapping as page) + * @DMA_COMPL_DEST_UNMAP_SINGLE - set to do the destination dma-unmapping as single + * (if not set, do the destination dma-unmapping as page) */ enum dma_ctrl_flags { DMA_PREP_INTERRUPT = (1 << 0), DMA_CTRL_ACK = (1 << 1), DMA_COMPL_SKIP_SRC_UNMAP = (1 << 2), DMA_COMPL_SKIP_DEST_UNMAP = (1 << 3), + DMA_COMPL_SRC_UNMAP_SINGLE = (1 << 4), + DMA_COMPL_DEST_UNMAP_SINGLE = (1 << 5), }; /** ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function 2009-04-22 14:58 ` Sosnowski, Maciej @ 2009-04-22 15:48 ` Alexander Beregalov 0 siblings, 0 replies; 8+ messages in thread From: Alexander Beregalov @ 2009-04-22 15:48 UTC (permalink / raw) To: Sosnowski, Maciej; +Cc: Williams, Dan J, Kernel Testers List, LKML 2009/4/22 Sosnowski, Maciej <maciej.sosnowski@intel.com>: > Alexander Beregalov wrote: >> 2009/4/17 Sosnowski, Maciej <maciej.sosnowski@intel.com>: >>> Dan Williams wrote: >>>> On Wed, Apr 15, 2009 at 5:39 AM, Alexander Beregalov >>>> <a.beregalov@gmail.com> wrote: >>>>> 2009/4/9 Alexander Beregalov <a.beregalov@gmail.com>: >>>>>> ioatdma 0000:00:08.0: PCI INT A -> GSI 16 (level, low) -> IRQ 16 >>>>>> ioatdma 0000:00:08.0: setting latency timer to 64 >>>>>> ioatdma 0000:00:08.0: Intel(R) I/OAT DMA Engine found, 4 channels, >>>>>> device version 0x12, driver version 3.64 >>>>>> alloc irq_desc for 33 on cpu 0 node 0 >>>>>> alloc kstat_irqs on cpu 0 node 0 >>>>>> ioatdma 0000:00:08.0: irq 33 for MSI/MSI-X >>>>>> ------------[ cut here ]------------ >>>>>> WARNING: at lib/dma-debug.c:565 check_unmap+0x2f6/0x6a0() >>>>>> Hardware name: PowerEdge 1950 >>>>>> ioatdma 0000:00:08.0: DMA-API: device driver frees DMA memory with >>>>>> wrong function [device address=0x000000007f76f800] [size=2000 bytes] [map >>>>>> ped as single] [unmapped as page] >>>>> >>>>> The problem still persists. >>>> >>>> Thanks for the report Alexander. Maciej and I are looking into a fix. >>>> >>>> Regards, >>>> Dan >>> >>> Hi Alexander, >>> >>> Could you check if the following patch helps? >> >> Hi Maciej. >> >> No, unfortunately it does not help. The same warning message. > > Ok, I have missed to cover self_test case. > How about this one instead? > It works! Thanks. Reported-by: Alexander Beregalov <a.beregalov@gmail.com> Tested-by: Alexander Beregalov <a.beregalov@gmail.com> ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-04-22 15:49 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2009-04-09 12:36 2.6.30-rc1: ioatdma: DMA-API: device driver frees DMA memory with wrong function Alexander Beregalov 2009-04-15 12:39 ` Alexander Beregalov 2009-04-15 17:27 ` Dan Williams 2009-04-17 2:38 ` FUJITA Tomonori 2009-04-17 11:49 ` Sosnowski, Maciej 2009-04-17 12:01 ` Alexander Beregalov 2009-04-22 14:58 ` Sosnowski, Maciej 2009-04-22 15:48 ` Alexander Beregalov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
Powered by JetHome