linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
From: linux@arm.linux.org.uk (Russell King - ARM Linux)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH] mmc: msm: fix dma usage not to use internal APIs
Date: Thu, 20 Jan 2011 13:02:46 +0000	[thread overview]
Message-ID: <20110120130246.GA23941@n2100.arm.linux.org.uk> (raw)
In-Reply-To: <1295522421.4366.34.camel@m0nster>

On Thu, Jan 20, 2011 at 03:20:21AM -0800, Daniel Walker wrote:
> On Tue, 2011-01-18 at 15:03 -0800, Daniel Walker wrote:
> > Remove parts of this driver which use internal API calls. This
> > replaces the calls as suggested by Russell King.
> > 
> > Cc: Russell King - ARM Linux <linux@arm.linux.org.uk>
> > Signed-off-by: Daniel Walker <dwalker@codeaurora.org>
> > ---
> >  drivers/mmc/host/msm_sdcc.c |   49 +++++++++++++++++++-----------------------
> >  1 files changed, 22 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
> > index 5decfd0..733d233 100644
> > --- a/drivers/mmc/host/msm_sdcc.c
> > +++ b/drivers/mmc/host/msm_sdcc.c
> > @@ -383,14 +383,30 @@ static int msmsdcc_config_dma(struct msmsdcc_host *host, struct mmc_data *data)
> >  	host->curr.user_pages = 0;
> >  
> >  	box = &nc->cmd[0];
> > -	for (i = 0; i < host->dma.num_ents; i++) {
> > -		box->cmd = CMD_MODE_BOX;
> >  
> > -	/* Initialize sg dma address */
> > -	sg->dma_address = page_to_dma(mmc_dev(host->mmc), sg_page(sg))
> > -				+ sg->offset;
> 
> It would seem there was a reason for this change.. The person that added
> this was Brent Degraaf (who is CC'd) ..
> 
> Quoting him below speaking about why dma_map_sg() isn't just used,
> 
> "Previous version of msm_sdcc.c had a cache coherency problem for
> precisely this reason. The dma_map_sg is what cleans the caches for
> these commands and so must be done AFTER the commands are populated. If
> this entry is left until the map function is called, the
> box->dst_row_addr will not be filled properly for reads."

It would be nice if problems such as this were discussed on the
linux-arm-kernel mailing list when they appear.

My response to this is:

dma_map_sg() does two things.  For each scatterlist entry:

* it converts the entry to a DMA address for the device and puts
  this in sg_dma_address().  The length of the entry is sg_dma_len().

* for each of the buffers described by the scatterlist, it ensures
  that the DMA device can see the data for DMA_TO_DEVICE transfers.
  for DMA_FROM_DEVICE transfers, it ensures that there are no dirty
  cache lines.  For some implementations the cache lines are
  invalidated to achieve this.

It is not guaranteed (and implementations do not predictably) cause any
other cache lines to be evicted or written back which are not described
by the scatterlist.

On dma_unmap_sg(), for each scatterlist entry:

* for DMA_FROM_DEVICE, some implementations cause the cache lines
  described by the scatterlist to be invalidated.

So, for anything _outside_ of the scatterlist, it is *unpredictable*
whether anything happens to them by way of the DMA API, and writing a
driver to rely on any behaviour observed is invalid.

The driver uses the passed scatterlist from the MMC layer to map, so the
only thing that the DMA API is going to touch is the pages which it's
performing IO on.

Therefore, it is entirely wrong for this driver to expect this box->blah
data to be written back by the DMA scatterlist mapping code.

Now, looking at the code a little more closely, host->dma.nc is allocated
via dma_alloc_coherent().  This returns either strongly ordered memory
for architectures prior to ARMv6, or 'normal non-cacheable' for ARMv6
onwards.

Strongly ordered requires no additional maintainence to ensure that writes
to it are immediately visible to hardware.  However, ARMv6 and later
requires a data synchronization barrier to ensure that writes to 'normal
non-cachable' memory are visible before writes to 'device' memory complete.

  reply	other threads:[~2011-01-20 13:02 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-18 23:03 [PATCH] mmc: msm: fix dma usage not to use internal APIs Daniel Walker
2011-01-18 23:05 ` Russell King - ARM Linux
2011-01-20 11:20 ` Daniel Walker
2011-01-20 13:02   ` Russell King - ARM Linux [this message]
2011-01-20 13:12     ` Russell King - ARM Linux
2011-01-20 15:08       ` Daniel Walker
2011-01-21 16:13         ` Brent DeGraaf
2011-01-21 16:57           ` Brent DeGraaf
2011-01-21 18:13             ` Russell King - ARM Linux
2011-01-21 19:28           ` Russell King - ARM Linux
2011-01-21 20:45             ` Daniel Walker
2011-01-21 21:17             ` David Brown
2011-01-21 21:37               ` Brent DeGraaf
2011-01-21 21:42                 ` Russell King - ARM Linux
  -- strict thread matches above, loose matches on Subject: below --
2011-01-18 22:25 Daniel Walker
2011-01-18 22:41 ` Russell King - ARM Linux
2011-01-18 22:48   ` Daniel Walker

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=20110120130246.GA23941@n2100.arm.linux.org.uk \
    --to=linux@arm.linux.org.uk \
    --cc=linux-arm-kernel@lists.infradead.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).