RE: [PATCH v2 08/11] async_tx: add support for asynchronous GF multiplication

Sosnowski, Maciej
2009-05-29T13:44:28Z

Dan Williams wrote:
> [ Based on an original patch by Yuri Tikhonov ]
>
> This adds support for doing asynchronous GF multiplication by adding
> two additional functions to the async_tx API:
>
>  async_gen_syndrome() does simultaneous XOR and Galois field
>    multiplication of sources.
>
>  async_syndrome_val() validates the given source buffers against known P
>    and Q values.
>
> When a request is made to run async_pq against more than the hardware
> maximum number of supported sources we need to reuse the previous
> generated P and Q values as sources into the next operation.  Care must
> be taken to remove Q from P' and P from Q'.  For example to perform a 5
> source pq op with hardware that only supports 4 sources at a time the
> following approach is taken:
>
> p, q = PQ(src0, src1, src2, src3, COEF({01}, {02}, {04}, {08}))
> p', q' = PQ(p, q, q, src4, COEF({00}, {01}, {00}, {10}))
>
> p' = p + q + q + src4 = p + src4
> q' = {00}*p + {01}*q + {00}*q + {10}*src4 = q + {10}*src4
>
> Note: 4 is the minimum acceptable maxpq otherwise we punt to
> synchronous-software path.
>
> The DMA_PREP_CONTINUE flag indicates to the driver to reuse p and q as
> sources (in the above manner) and fill the remaining slots up to maxpq
> with the new sources/coefficients.
>
> Note: Some devices have native support for P+Q continuation and can skip
> this extra work.  Devices with this capability can advertise it with
> dma_set_maxpq.  It is up to each driver how the DMA_PREP_CONTINUE flag
> is honored.
>
> Signed-off-by: Yuri Tikhonov <yur@emcraft.com>
> Signed-off-by: Ilya Yanok <yanok@emcraft.com>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> ---
>  arch/arm/mach-iop13xx/setup.c |    2
>  crypto/async_tx/Kconfig       |    4
>  crypto/async_tx/Makefile      |    1
>  crypto/async_tx/async_pq.c    |  399 +++++++++++++++++++++++++++++++++++++++++
>  crypto/async_tx/async_xor.c   |    2
>  drivers/dma/dmaengine.c       |    4
>  drivers/dma/iop-adma.c        |    2
>  include/linux/async_tx.h      |    9 +
>  include/linux/dmaengine.h     |   58 +++++-
>  9 files changed, 472 insertions(+), 9 deletions(-)
>  create mode 100644 crypto/async_tx/async_pq.c

(...)

> +               /* Since we have clobbered the src_list we are committed
> +                * to doing this asynchronously.  Drivers force forward
> +                * progress in case they can not provide a descriptor
> +                */
> +               for (;;) {
> +                       tx = dma->device_prep_dma_pq(chan, dma_dest,
> +                                                    &dma_src[src_off],
> +                                                    pq_src_cnt,
> +                                                    &coefs[src_off], len,
> +                                                    dma_flags);
> +                       if (likely(tx))
> +                               break;
> +                       async_tx_quiesce(&submit->depend_tx);
> +                       dma_async_issue_pending(chan);
> +               }

How about adding a timeout to the loop in case we do not get a descriptor at all for some reason?

> +               for (;;) {
> +                       tx = device->device_prep_dma_pq_val(chan, pq, dma_src,
> +                                                           disks - 2,
> +                                                           raid6_gfexp,
> +                                                           len, pqres,
> +                                                           dma_flags);
> +                       if (likely(tx))
> +                               break;
> +                       async_tx_quiesce(&submit->depend_tx);
> +                       dma_async_issue_pending(chan);
> +               }

Same as above...

Thanks,
Maciej