lkml.org 
[lkml]   [2013]   [Dec]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 3.10 074/173] ioatdma: fix selection of 16 vs 8 source path
    Date
    3.10-stable review patch.  If anyone has any objections, please let me know.

    ------------------

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

    commit 21e96c7313486390c694919522a76dfea0a86c59 upstream.

    When performing continuations there are implied sources that need to be
    added to the source count. Quoting dma_set_maxpq:

    /* dma_maxpq - reduce maxpq in the face of continued operations
    * @dma - dma device with PQ capability
    * @flags - to check if DMA_PREP_CONTINUE and DMA_PREP_PQ_DISABLE_P are set
    *
    * When an engine does not support native continuation we need 3 extra
    * source slots to reuse P and Q with the following coefficients:
    * 1/ {00} * P : remove P from Q', but use it as a source for P'
    * 2/ {01} * Q : use Q to continue Q' calculation
    * 3/ {00} * Q : subtract Q from P' to cancel (2)
    *
    * In the case where P is disabled we only need 1 extra source:
    * 1/ {01} * Q : use Q to continue Q' calculation
    */

    ...fix the selection of the 16 source path to take these implied sources
    into account.

    Note this also kills the BUG_ON(src_cnt < 9) check in
    __ioat3_prep_pq16_lock(). Besides not accounting for implied sources
    the check is redundant given we already made the path selection.

    Cc: Dave Jiang <dave.jiang@intel.com>
    Acked-by: Dave Jiang <dave.jiang@intel.com>
    Signed-off-by: Dan Williams <dan.j.williams@intel.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/dma/ioat/dma_v3.c | 30 +++++++++++++++---------------
    1 file changed, 15 insertions(+), 15 deletions(-)

    --- a/drivers/dma/ioat/dma_v3.c
    +++ b/drivers/dma/ioat/dma_v3.c
    @@ -1169,9 +1169,6 @@ __ioat3_prep_pq16_lock(struct dma_chan *
    u8 op;
    int i, s, idx, num_descs;

    - /* this function only handles src_cnt 9 - 16 */
    - BUG_ON(src_cnt < 9);
    -
    /* this function is only called with 9-16 sources */
    op = result ? IOAT_OP_PQ_VAL_16S : IOAT_OP_PQ_16S;

    @@ -1257,13 +1254,21 @@ __ioat3_prep_pq16_lock(struct dma_chan *
    return &desc->txd;
    }

    +static int src_cnt_flags(unsigned int src_cnt, unsigned long flags)
    +{
    + if (dmaf_p_disabled_continue(flags))
    + return src_cnt + 1;
    + else if (dmaf_continue(flags))
    + return src_cnt + 3;
    + else
    + return src_cnt;
    +}
    +
    static struct dma_async_tx_descriptor *
    ioat3_prep_pq(struct dma_chan *chan, dma_addr_t *dst, dma_addr_t *src,
    unsigned int src_cnt, const unsigned char *scf, size_t len,
    unsigned long flags)
    {
    - struct dma_device *dma = chan->device;
    -
    /* specify valid address for disabled result */
    if (flags & DMA_PREP_PQ_DISABLE_P)
    dst[0] = dst[1];
    @@ -1283,7 +1288,7 @@ ioat3_prep_pq(struct dma_chan *chan, dma
    single_source_coef[0] = scf[0];
    single_source_coef[1] = 0;

    - return (src_cnt > 8) && (dma->max_pq > 8) ?
    + return src_cnt_flags(src_cnt, flags) > 8 ?
    __ioat3_prep_pq16_lock(chan, NULL, dst, single_source,
    2, single_source_coef, len,
    flags) :
    @@ -1291,7 +1296,7 @@ ioat3_prep_pq(struct dma_chan *chan, dma
    single_source_coef, len, flags);

    } else {
    - return (src_cnt > 8) && (dma->max_pq > 8) ?
    + return src_cnt_flags(src_cnt, flags) > 8 ?
    __ioat3_prep_pq16_lock(chan, NULL, dst, src, src_cnt,
    scf, len, flags) :
    __ioat3_prep_pq_lock(chan, NULL, dst, src, src_cnt,
    @@ -1304,8 +1309,6 @@ ioat3_prep_pq_val(struct dma_chan *chan,
    unsigned int src_cnt, const unsigned char *scf, size_t len,
    enum sum_check_flags *pqres, unsigned long flags)
    {
    - struct dma_device *dma = chan->device;
    -
    /* specify valid address for disabled result */
    if (flags & DMA_PREP_PQ_DISABLE_P)
    pq[0] = pq[1];
    @@ -1317,7 +1320,7 @@ ioat3_prep_pq_val(struct dma_chan *chan,
    */
    *pqres = 0;

    - return (src_cnt > 8) && (dma->max_pq > 8) ?
    + return src_cnt_flags(src_cnt, flags) > 8 ?
    __ioat3_prep_pq16_lock(chan, pqres, pq, src, src_cnt, scf, len,
    flags) :
    __ioat3_prep_pq_lock(chan, pqres, pq, src, src_cnt, scf, len,
    @@ -1328,7 +1331,6 @@ static struct dma_async_tx_descriptor *
    ioat3_prep_pqxor(struct dma_chan *chan, dma_addr_t dst, dma_addr_t *src,
    unsigned int src_cnt, size_t len, unsigned long flags)
    {
    - struct dma_device *dma = chan->device;
    unsigned char scf[src_cnt];
    dma_addr_t pq[2];

    @@ -1337,7 +1339,7 @@ ioat3_prep_pqxor(struct dma_chan *chan,
    flags |= DMA_PREP_PQ_DISABLE_Q;
    pq[1] = dst; /* specify valid address for disabled result */

    - return (src_cnt > 8) && (dma->max_pq > 8) ?
    + return src_cnt_flags(src_cnt, flags) > 8 ?
    __ioat3_prep_pq16_lock(chan, NULL, pq, src, src_cnt, scf, len,
    flags) :
    __ioat3_prep_pq_lock(chan, NULL, pq, src, src_cnt, scf, len,
    @@ -1349,7 +1351,6 @@ ioat3_prep_pqxor_val(struct dma_chan *ch
    unsigned int src_cnt, size_t len,
    enum sum_check_flags *result, unsigned long flags)
    {
    - struct dma_device *dma = chan->device;
    unsigned char scf[src_cnt];
    dma_addr_t pq[2];

    @@ -1363,8 +1364,7 @@ ioat3_prep_pqxor_val(struct dma_chan *ch
    flags |= DMA_PREP_PQ_DISABLE_Q;
    pq[1] = pq[0]; /* specify valid address for disabled result */

    -
    - return (src_cnt > 8) && (dma->max_pq > 8) ?
    + return src_cnt_flags(src_cnt, flags) > 8 ?
    __ioat3_prep_pq16_lock(chan, result, pq, &src[1], src_cnt - 1,
    scf, len, flags) :
    __ioat3_prep_pq_lock(chan, result, pq, &src[1], src_cnt - 1,



    \
     
     \ /
      Last update: 2013-12-02 22:41    [W:3.339 / U:0.164 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site