All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tony Battersby <tonyb@cybernetics.com>
To: LABBE Corentin <clabbe.montjoie@gmail.com>,
	herbert@gondor.apana.org.au, davem@davemloft.net,
	akpm@linux-foundation.org, arnd@arndb.de, axboe@fb.com,
	david.s.gordon@intel.com, martin.petersen@oracle.com,
	robert.jarzmik@free.fr, thomas.lendacky@amd.com
Cc: linux-kernel@vger.kernel.org, linux-crypto@vger.kernel.org,
	lee.nipper@gmail.com, yuan.j.kang@gmail.com
Subject: Re: [PATCH v2 5/8] lib: introduce sg_nents_len_chained
Date: Fri, 18 Sep 2015 12:19:33 -0400	[thread overview]
Message-ID: <55FC3995.8050600@cybernetics.com> (raw)
In-Reply-To: <1442581036-23789-6-git-send-email-clabbe.montjoie@gmail.com>

On 09/18/2015 08:57 AM, LABBE Corentin wrote:
> +	for (nents = 0, total = 0; sg; sg = sg_next(sg)) {
> +		nents++;
> +		total += sg->length;
> +		if (!sg_is_last(sg) && (sg + 1)->length == 0 && chained)
> +			*chained = true;
> +		if (total >= len)
> +			return nents;
> +	}
> +
>

(resending with fixed formatting; Thunderbird seems braindamaged lately)

It seems to me like the check for total >= len should be above the check
for chaining.  The way the code is now, it will return chained = true if
the first "unneeded" sg vector is a chain, which does not make intuitive
sense.

But why do drivers even need this at all?  Here is a typical usage:

int qce_mapsg(struct device *dev, struct scatterlist *sg, int nents,
          enum dma_data_direction dir, bool chained)
{
    int err;

    if (chained) {
        while (sg) {
            err = dma_map_sg(dev, sg, 1, dir);
            if (!err)
                return -EFAULT;
            sg = sg_next(sg);
        }
    } else {
        err = dma_map_sg(dev, sg, nents, dir);
        if (!err)
            return -EFAULT;
    }

    return nents;
}

Here is another:

static int talitos_map_sg(struct device *dev, struct scatterlist *sg,
              unsigned int nents, enum dma_data_direction dir,
              bool chained)
{
    if (unlikely(chained))
        while (sg) {
            dma_map_sg(dev, sg, 1, dir);
            sg = sg_next(sg);
        }
    else
        dma_map_sg(dev, sg, nents, dir);
    return nents;
}

Can anyone clarify why you can't just use dma_map_sg(dev, sg, nents,
dir) always?  It should be able to handle chained scatterlists just fine.

If the check for chaining is a just workaround for some problem in
dma_map_sg(), maybe it would be better to fix dma_map_sg() instead,
which would eliminate the need for sg_nents_len_chained() and all these
buggy workarounds (e.g. if chained is true, qce_mapsg() can leave the
DMA list partially mapped when it returns -EFAULT, and talitos_map_sg()
doesn't even check for errors).

One problem that I see is that sg_last() in scatterlist.c has a
"BUG_ON(!sg_is_last(ret));" if CONFIG_DEBUG_SG is enabled, and using a
smaller-than-original nents (as returned by sg_nents_len_chained()) with
the same scatterlist will trigger that bug.  But that should be true
regardless of whether chaining is used or not.  For example, talitos.c
calls sg_last() in a way that can trigger that bug.

For anyone willing to dig further, these are the first two commits that
introduce code like this:

4de9d0b547b9 "crypto: talitos - Add ablkcipher algorithms" (2009)
643b39b031f5 "crypto: caam - chaining support" (2012)
(CC'ing the original authors)

Tony Battersby
Cybernetics

  parent reply	other threads:[~2015-09-18 16:19 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-09-18 12:57 [PATCH v2] crypto: Remove duplicate code of SG helpers functions LABBE Corentin
2015-09-18 12:57 ` [PATCH v2 1/8] crypto: bfin: replace sg_count by sg_nents LABBE Corentin
2015-09-18 12:57 ` [PATCH v2 2/8] crypto: amcc replace get_sg_count by sg_nents_for_len LABBE Corentin
2015-09-18 12:57 ` [PATCH v2 3/8] crypto: sahara: replace sahara_sg_length with sg_nents_for_len LABBE Corentin
2015-09-18 12:57 ` [PATCH v2 4/8] s390: replace zfcp_qdio_sbale_count by sg_nents LABBE Corentin
2015-09-30 13:59   ` Steffen Maier
2015-09-18 12:57 ` [PATCH v2 5/8] lib: introduce sg_nents_len_chained LABBE Corentin
2015-09-18 14:01   ` Tom Lendacky
2015-09-18 16:19   ` Tony Battersby [this message]
2015-09-18 21:25     ` Tony Battersby
2015-09-21 14:19       ` Herbert Xu
2015-09-21 14:59         ` LABBE Corentin
2015-09-18 12:57 ` [PATCH v2 6/8] crypto: talitos: replace sg_count with sg_nents_len_chained LABBE Corentin
2015-09-18 12:57 ` [PATCH v2 7/8] crypto: qce: replace qce_countsg " LABBE Corentin
2015-09-18 12:57 ` [PATCH v2 8/8] crypto: caam: replace __sg_count " LABBE Corentin
2015-09-21 15:09 ` [PATCH v2] crypto: Remove duplicate code of SG helpers functions Herbert Xu

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=55FC3995.8050600@cybernetics.com \
    --to=tonyb@cybernetics.com \
    --cc=akpm@linux-foundation.org \
    --cc=arnd@arndb.de \
    --cc=axboe@fb.com \
    --cc=clabbe.montjoie@gmail.com \
    --cc=davem@davemloft.net \
    --cc=david.s.gordon@intel.com \
    --cc=herbert@gondor.apana.org.au \
    --cc=lee.nipper@gmail.com \
    --cc=linux-crypto@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martin.petersen@oracle.com \
    --cc=robert.jarzmik@free.fr \
    --cc=thomas.lendacky@amd.com \
    --cc=yuan.j.kang@gmail.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 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.