linux-raid.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Yuri Tikhonov <yur@emcraft.com>
To: Dan Williams <dan.j.williams@intel.com>
Cc: "linux-raid@vger.kernel.org" <linux-raid@vger.kernel.org>,
	"linuxppc-dev@ozlabs.org" <linuxppc-dev@ozlabs.org>,
	"dzu@denx.de" <dzu@denx.de>, "wd@denx.de" <wd@denx.de>,
	Ilya Yanok <yanok@emcraft.com>, Saeed Bishara <saeed@marvell.com>
Subject: Re[2]: [PATCH] ASYNC_TX: async_xor mapping fix
Date: Wed, 10 Dec 2008 22:07:18 +0300	[thread overview]
Message-ID: <724394867.20081210220718@emcraft.com> (raw)
In-Reply-To: <1228934826.1224.5.camel@dwillia2-linux.ch.intel.com>



 Hello Dan,

On Wednesday, December 10, 2008 you wrote:

> On Mon, 2008-12-08 at 14:08 -0700, Dan Williams wrote:
>> On Mon, 2008-12-08 at 12:14 -0700, Yuri Tikhonov wrote:
>> > The destination address may be present in the source list, so we should
>> > map the addresses from the source list first.
>> >  Otherwise, if page corresponding to destination is not marked as write-
>> > through (with regards to CPU cache), then mapping it with DMA_FROM_DEVICE
>> > may lead to data loss, and finally to an incorrect result of calculations.
>> > 
>> 
>> Thanks Yuri.  I think we should avoid mapping the destination twice
>> altogether, and for simplicity just always map it bidirectionally.

> Yuri, Saeed, can I get your acked-by's for the following 2.6.28 patch:

 I would do the "src_list[i] == dest" check with unlikely(), since we 
a-priori aware that only one of all src_cnt addresses is the possible 
destination.

 As for the rest:

Acked-by: Yuri Tikhonov <yur@emcraft.com>

> Thanks,
> Dan


----snip---->>
> async_xor: dma_map destination DMA_BIDIRECTIONAL

> From: Dan Williams <dan.j.williams@intel.com>

> Mapping the destination multiple times is a misuse of the dma-api.
> Since the destination may be reused as a source, ensure that it is only
> mapped once and that it is mapped bidirectionally.  This appears to add
> ugliness on the unmap side in that it always reads back the destination
> address from the descriptor, but gcc can determine that dma_unmap is a
> nop and not emit the code that calculates its arguments.

> Cc: <stable@kernel.org>
> Cc: Saeed Bishara <saeed@marvell.com>
> Reported-by: Yuri Tikhonov <yur@emcraft.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  crypto/async_tx/async_xor.c |   11 +++++++++--
>  drivers/dma/iop-adma.c      |   16 +++++++++++++---
>  drivers/dma/mv_xor.c        |   15 ++++++++++++---
>  3 files changed, 34 insertions(+), 8 deletions(-)

> diff --git a/crypto/async_tx/async_xor.c b/crypto/async_tx/async_xor.c
> index c029d3e..a6faa90 100644
> --- a/crypto/async_tx/async_xor.c
> +++ b/crypto/async_tx/async_xor.c
> @@ -53,10 +53,17 @@ do_async_xor(struct dma_chan *chan, struct page *dest, struct page **src_list,
>         int xor_src_cnt;
>         dma_addr_t dma_dest;
>  
> -       dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_FROM_DEVICE);
> -       for (i = 0; i < src_cnt; i++)
> +       /* map the dest bidrectional in case it is re-used as a source */
> +       dma_dest = dma_map_page(dma->dev, dest, offset, len, DMA_BIDIRECTIONAL);
> +       for (i = 0; i < src_cnt; i++) {
> +               /* only map the dest once */
> +               if (src_list[i] == dest) {
> +                       dma_src[i] = dma_dest;
> +                       continue;
> +               }
>                 dma_src[i] = dma_map_page(dma->dev, src_list[i], offset,
>                                           len, DMA_TO_DEVICE);
> +       }
>  
>         while (src_cnt) {
>                 async_flags = flags;
> diff --git a/drivers/dma/iop-adma.c b/drivers/dma/iop-adma.c
> index c7a9306..6be3172 100644
> --- a/drivers/dma/iop-adma.c
> +++ b/drivers/dma/iop-adma.c
> @@ -85,18 +85,28 @@ iop_adma_run_tx_complete_actions(struct iop_adma_desc_slot *desc,
>                         enum dma_ctrl_flags flags = desc->async_tx.flags;
>                         u32 src_cnt;
>                         dma_addr_t addr;
> +                       dma_addr_t dest;
>  
> +                       src_cnt = unmap->unmap_src_cnt;
> +                       dest = iop_desc_get_dest_addr(unmap, iop_chan);
>                         if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
> -                               addr =
> iop_desc_get_dest_addr(unmap, iop_chan);
> -                               dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
> +                               enum dma_data_direction dir;
> +
> +                               if (src_cnt > 1) /* is xor? */
> +                                       dir = DMA_BIDIRECTIONAL;
> +                               else
> +                                       dir = DMA_FROM_DEVICE;
> +
> +                               dma_unmap_page(dev, dest, len, dir);
>                         }
>  
>                         if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
> -                               src_cnt = unmap->unmap_src_cnt;
>                                 while (src_cnt--) {
>                                         addr = iop_desc_get_src_addr(unmap,
>                                                                     iop_chan,
>                                                                     src_cnt);
> +                                       if (addr == dest)
> +                                               continue;
>                                         dma_unmap_page(dev, addr, len,
>                                                        DMA_TO_DEVICE);
>                                 }
> diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
> index 0328da0..bcda174 100644
> --- a/drivers/dma/mv_xor.c
> +++ b/drivers/dma/mv_xor.c
> @@ -311,17 +311,26 @@ mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc,
>                         enum dma_ctrl_flags flags = desc->async_tx.flags;
>                         u32 src_cnt;
>                         dma_addr_t addr;
> +                       dma_addr_t dest;
>  
> +                       src_cnt = unmap->unmap_src_cnt;
> +                       dest = mv_desc_get_dest_addr(unmap);
>                         if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
> -                               addr = mv_desc_get_dest_addr(unmap);
> -                               dma_unmap_page(dev, addr, len, DMA_FROM_DEVICE);
> +                               enum dma_data_direction dir;
> +
> +                               if (src_cnt > 1) /* is xor ? */
> +                                       dir = DMA_BIDIRECTIONAL;
> +                               else
> +                                       dir = DMA_FROM_DEVICE;
> +                               dma_unmap_page(dev, dest, len, dir);
>                         }
>  
>                         if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
> -                               src_cnt = unmap->unmap_src_cnt;
>                                 while (src_cnt--) {
>                                         addr = mv_desc_get_src_addr(unmap,
>                                                                     src_cnt);
> +                                       if (addr == dest)
> +                                               continue;
>                                         dma_unmap_page(dev, addr, len,
>                                                        DMA_TO_DEVICE);
>                                 }





 Regards, Yuri

 --
 Yuri Tikhonov, Senior Software Engineer
 Emcraft Systems, www.emcraft.com


      reply	other threads:[~2008-12-10 19:07 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-08 19:14 [PATCH] ASYNC_TX: async_xor mapping fix Yuri Tikhonov
2008-12-08 21:08 ` Dan Williams
2008-12-10 18:47   ` Dan Williams
2008-12-10 19:07     ` Yuri Tikhonov [this message]

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=724394867.20081210220718@emcraft.com \
    --to=yur@emcraft.com \
    --cc=dan.j.williams@intel.com \
    --cc=dzu@denx.de \
    --cc=linux-raid@vger.kernel.org \
    --cc=linuxppc-dev@ozlabs.org \
    --cc=saeed@marvell.com \
    --cc=wd@denx.de \
    --cc=yanok@emcraft.com \
    /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).