RE: [PATCH v0 1/2] DMA: fsldma: Disable DMA_INTERRUPT when Async_tx enabled
-Original Message- From: Ira W. Snyder [mailto:i...@ovro.caltech.edu] Sent: Friday, October 16, 2009 9:04 PM To: Dan Williams Cc: Suresh Vishnu-B05022; herb...@gondor.apana.org.au; linux-ker...@vger.kernel.org; linux-r...@vger.kernel.org; linuxppc-...@ozlabs.org; linux-cry...@vger.kernel.org; Tabi Timur-B04825 Subject: Re: [PATCH v0 1/2] DMA: fsldma: Disable DMA_INTERRUPT when Async_tx enabled On Thu, Oct 15, 2009 at 06:25:14PM -0700, Dan Williams wrote: [ added Leo and Timur to the Cc ] On Wed, Oct 14, 2009 at 11:41 PM, Vishnu Suresh vis...@freescale.com wrote: This patch disables the use of DMA_INTERRUPT capability with Async_tx The fsldma produces a null transfer with DMA_INTERRUPT capability when used with Async_tx. When RAID devices queue a transaction via Async_tx, this results in a hang. Signed-off-by: Vishnu Suresh vis...@freescale.com --- drivers/dma/fsldma.c | 6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 296f9e7..66d9b39 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1200,7 +1200,13 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, - fdev-reg.start + 1); dma_cap_set(DMA_MEMCPY, fdev-common.cap_mask); +#ifndef CONFIG_ASYNC_CORE + /* + * The DMA_INTERRUPT async_tx is a NULL transfer, which will + * triger a PE interrupt. + */ dma_cap_set(DMA_INTERRUPT, fdev-common.cap_mask); +#endif dma_cap_set(DMA_SLAVE, fdev-common.cap_mask); fdev-common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources; fdev-common.device_free_chan_resources = fsl_dma_free_chan_resources; You are basically saying that fsl_dma_prep_interrupt() is buggy. Can that routine be fixed rather than this piecemeal solution? If it cannot be fixed (i.e. hardware issue) then fsl_dma_prep_interrupt() should just be disabled/deleted altogether. We are working to fix this issue. For what it's worth, I've used the following code in the recent past, without any issues. This was on an 83xx, within the last few kernel releases. I haven't tried it on the latest -rc. This works fine as long as only DMA_MEMCPY is being used. The async_tx_channel_switch does not occur and the device_prep_dma_interrupt is not called. However, when a DMA_XOR capable device is exposed, which is differnet from the DMA_MEMCPY/INTERRUPT device, this path is hit. Is it proper to schedule a dma_interrupt from the channel switch call, even when the depend_tx and tx channels correspond to different devices? Using device_prep_dma_memcpy() can trigger a callback as well, so the interrupt feature isn't strictly needed. Just attach the callback to the last memcpy operation. static dma_cookie_t dma_async_interrupt(struct dma_chan *chan, dma_async_tx_callback callback, void *data) { struct dma_device *dev = chan-device; struct dma_async_tx_descriptor *tx; /* Set up the DMA */ tx = dev-device_prep_dma_interrupt(chan, DMA_PREP_INTERRUPT); if (!tx) return -ENOMEM; tx-callback = callback; tx-callback_param = data; return tx-tx_submit(tx); } Ira ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v0 1/2] DMA: fsldma: Disable DMA_INTERRUPT when Async_tx enabled
On Thu, Oct 15, 2009 at 06:25:14PM -0700, Dan Williams wrote: [ added Leo and Timur to the Cc ] On Wed, Oct 14, 2009 at 11:41 PM, Vishnu Suresh vis...@freescale.com wrote: This patch disables the use of DMA_INTERRUPT capability with Async_tx The fsldma produces a null transfer with DMA_INTERRUPT capability when used with Async_tx. When RAID devices queue a transaction via Async_tx, this results in a hang. Signed-off-by: Vishnu Suresh vis...@freescale.com --- drivers/dma/fsldma.c | 6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 296f9e7..66d9b39 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1200,7 +1200,13 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, - fdev-reg.start + 1); dma_cap_set(DMA_MEMCPY, fdev-common.cap_mask); +#ifndef CONFIG_ASYNC_CORE + /* + * The DMA_INTERRUPT async_tx is a NULL transfer, which will + * triger a PE interrupt. + */ dma_cap_set(DMA_INTERRUPT, fdev-common.cap_mask); +#endif dma_cap_set(DMA_SLAVE, fdev-common.cap_mask); fdev-common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources; fdev-common.device_free_chan_resources = fsl_dma_free_chan_resources; You are basically saying that fsl_dma_prep_interrupt() is buggy. Can that routine be fixed rather than this piecemeal solution? If it cannot be fixed (i.e. hardware issue) then fsl_dma_prep_interrupt() should just be disabled/deleted altogether. For what it's worth, I've used the following code in the recent past, without any issues. This was on an 83xx, within the last few kernel releases. I haven't tried it on the latest -rc. Using device_prep_dma_memcpy() can trigger a callback as well, so the interrupt feature isn't strictly needed. Just attach the callback to the last memcpy operation. static dma_cookie_t dma_async_interrupt(struct dma_chan *chan, dma_async_tx_callback callback, void *data) { struct dma_device *dev = chan-device; struct dma_async_tx_descriptor *tx; /* Set up the DMA */ tx = dev-device_prep_dma_interrupt(chan, DMA_PREP_INTERRUPT); if (!tx) return -ENOMEM; tx-callback = callback; tx-callback_param = data; return tx-tx_submit(tx); } Ira ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
[PATCH v0 1/2] DMA: fsldma: Disable DMA_INTERRUPT when Async_tx enabled
This patch disables the use of DMA_INTERRUPT capability with Async_tx The fsldma produces a null transfer with DMA_INTERRUPT capability when used with Async_tx. When RAID devices queue a transaction via Async_tx, this results in a hang. Signed-off-by: Vishnu Suresh vis...@freescale.com --- drivers/dma/fsldma.c |6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 296f9e7..66d9b39 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1200,7 +1200,13 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, - fdev-reg.start + 1); dma_cap_set(DMA_MEMCPY, fdev-common.cap_mask); +#ifndef CONFIG_ASYNC_CORE + /* +* The DMA_INTERRUPT async_tx is a NULL transfer, which will +* triger a PE interrupt. +*/ dma_cap_set(DMA_INTERRUPT, fdev-common.cap_mask); +#endif dma_cap_set(DMA_SLAVE, fdev-common.cap_mask); fdev-common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources; fdev-common.device_free_chan_resources = fsl_dma_free_chan_resources; -- 1.6.4.2 ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev
Re: [PATCH v0 1/2] DMA: fsldma: Disable DMA_INTERRUPT when Async_tx enabled
[ added Leo and Timur to the Cc ] On Wed, Oct 14, 2009 at 11:41 PM, Vishnu Suresh vis...@freescale.com wrote: This patch disables the use of DMA_INTERRUPT capability with Async_tx The fsldma produces a null transfer with DMA_INTERRUPT capability when used with Async_tx. When RAID devices queue a transaction via Async_tx, this results in a hang. Signed-off-by: Vishnu Suresh vis...@freescale.com --- drivers/dma/fsldma.c | 6 ++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 296f9e7..66d9b39 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1200,7 +1200,13 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev, - fdev-reg.start + 1); dma_cap_set(DMA_MEMCPY, fdev-common.cap_mask); +#ifndef CONFIG_ASYNC_CORE + /* + * The DMA_INTERRUPT async_tx is a NULL transfer, which will + * triger a PE interrupt. + */ dma_cap_set(DMA_INTERRUPT, fdev-common.cap_mask); +#endif dma_cap_set(DMA_SLAVE, fdev-common.cap_mask); fdev-common.device_alloc_chan_resources = fsl_dma_alloc_chan_resources; fdev-common.device_free_chan_resources = fsl_dma_free_chan_resources; You are basically saying that fsl_dma_prep_interrupt() is buggy. Can that routine be fixed rather than this piecemeal solution? If it cannot be fixed (i.e. hardware issue) then fsl_dma_prep_interrupt() should just be disabled/deleted altogether. -- Dan ___ Linuxppc-dev mailing list Linuxppc-dev@lists.ozlabs.org https://lists.ozlabs.org/listinfo/linuxppc-dev