From: Timur Tabi <timur@freescale.com>
To: lkml <linux-kernel@vger.kernel.org>,
Haavard Skinnemoen <haavard.skinnemoen@atmel.com>,
Dan Williams <dan.j.williams@intel.com>
Subject: dmaengine.c: question about device_alloc_chan_resources
Date: Tue, 16 Sep 2008 16:30:49 -0500 [thread overview]
Message-ID: <48D02589.8070601@freescale.com> (raw)
Dan, Haavard, et al,
I am making some fixes to the Freescale DMA driver (drivers/dma/fsldma.c), and
I've come across a situation I don't understand. Specifically, I have an issue
with the return values from fsl_dma_alloc_chan_resources(), which is fsldma's
device_alloc_chan_resources() function.
fsldma calls dma_async_device_register() for each DMA controller it finds. The
problem is that when I use the dmatest driver, this results in
device_alloc_chan_resources() being called multiple times for the same DMA
channel. When this happens, fsl_dma_alloc_chan_resources() must return -1
otherwise fsldma will hang during unload if the dmatest driver is also loaded.
The hang occurs in dma_async_device_unregister(), when it calls
wait_for_completion().
Here's what happens:
1) fsldma finds one DMA controller with four DMA channels. It creates all the
channel objects and then calls dma_async_device_register().
2) Via dma_clients_notify_available(), dmatest is notified that there's a new
DMA resource. It stores those four channels in its dmatest_channels object.
3) fsldma fins another DMA controller with four DMA channels. Again, it creates
all the channel objects and then calls dma_async_device_register().
4) dma_clients_notify_available() is called again. This time, however, it tells
dmatest about *eight* channels, not just the four additional ones. It does this
because fsl_dma_alloc_chan_resources() returns 1 every time it's called.
The result is that the some DMA channel will appear twice in dmatest's channel
list. For example, I added a bunch of printks to dma_test_add_channnel:
dmatest: Started 1 threads using dma2chan1
dmatest_add_channel:372 chan=df1f2a50
dmatest_add_channel:382 dtc->chan=df1f2898
dmatest_add_channel:382 dtc->chan=df1f2a50
dmatest_add_channel:382 dtc->chan=df1f2898
dmatest_add_channel:382 dtc->chan=df1f2a50
As you can see, df1f2898 appears twice, as does df1f2a50.
So my fix was to add this code to fsl_dma_alloc_chan_resources():
/* Has this channel already been allocated? */
if (fsl_chan->desc_pool)
return -ENOMEM;
This fixes the hang, but I have a suspicion that it's still wrong. When I look
at the other DMA device drivers, they don't do this. For instance,
ioat_dma_alloc_chan_resources() does this:
/* have we already been set up? */
if (!list_empty(&ioat_chan->free_desc))
return ioat_chan->desccount;
In other words, it returns the resources that have been allocated already. But
if I do that, my driver hangs during an unload (if dmatest is loaded).
I think what's happening is that fsldma is the only DMA driver that calls
dma_async_device_register() more than once, and so it's exposing a bug in
dmaengine.c. Can anyone confirm that?
--
Timur Tabi
Linux kernel developer at Freescale
next reply other threads:[~2008-09-16 21:31 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-09-16 21:30 Timur Tabi [this message]
2008-09-17 22:36 ` dmaengine.c: question about device_alloc_chan_resources Dan Williams
2008-09-18 14:13 ` Timur Tabi
2008-09-18 14:28 ` Haavard Skinnemoen
2008-09-18 14:31 ` Timur Tabi
2008-09-18 14:45 ` Haavard Skinnemoen
2008-09-18 14:49 ` Timur Tabi
2008-09-18 15:00 ` Haavard Skinnemoen
2008-09-19 4:20 ` Dan Williams
2008-09-19 11:25 ` Haavard Skinnemoen
2008-09-19 14:34 ` Timur Tabi
2008-09-19 14:50 ` linux-os (Dick Johnson)
2008-09-19 15:01 ` Timur Tabi
2008-09-19 15:28 ` Alan Cox
2008-09-20 23:00 ` Dan Williams
2008-09-21 9:26 ` Haavard Skinnemoen
2008-09-21 19:50 ` Guennadi Liakhovetski
2008-09-22 7:44 ` Haavard Skinnemoen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=48D02589.8070601@freescale.com \
--to=timur@freescale.com \
--cc=dan.j.williams@intel.com \
--cc=haavard.skinnemoen@atmel.com \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.