From patchwork Tue Dec 3 16:32:01 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 11271603 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A6FA1930 for ; Tue, 3 Dec 2019 16:32:10 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8F7E220675 for ; Tue, 3 Dec 2019 16:32:10 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8F7E220675 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 344276E9E8; Tue, 3 Dec 2019 16:32:08 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-wr1-x443.google.com (mail-wr1-x443.google.com [IPv6:2a00:1450:4864:20::443]) by gabe.freedesktop.org (Postfix) with ESMTPS id 7E2C96E9E8 for ; Tue, 3 Dec 2019 16:32:06 +0000 (UTC) Received: by mail-wr1-x443.google.com with SMTP id g17so4506613wro.2 for ; Tue, 03 Dec 2019 08:32:06 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8EYcVq3D13Cv4p0YNI7vV4r0UyMzhZvJG8/eW5rX0Js=; b=n0ypZRmUVNgmJ7DcPTu0+EYALPV4HY3ED82K5yQPfGtayuwrxGDJ0YpNhRfdra6bzB ljgCHDB6Nv6hQk9/4cEaBqhXDjEBwDka+qRuzGhtdMdwhRT9fOQkI/4dEPC0XcE4MsoI /oiEBNlaM9ELlzvyw5WDgrIDdJnuAB+55Ae36Lj/tvSfQuRujWlDX0BxDsakb01lPusq nt8vu3E4EbA3oYaLrz5+6D8OwLwT4LpVLB5JOxV7QbgOA+G6CITdL7dZWO0IrZf0GtdT OL9aAhS5N7XUBmLtIzI93irnHeQKNqu+XUZr750A6unVNtFj+PFGO9gMtJNkUJgKor26 6TjQ== X-Gm-Message-State: APjAAAU2gQYnZcQ/+c40TZ78bV8OdBXfEnKJ4doMINTPQa2Idce5S66l H2FdFTb720yWxb0v1elY8oI= X-Google-Smtp-Source: APXvYqxCJLqegjUn/l5I5qAgvCYWCXdjUUQz8EvWQ8Op1wr04iv9ZZZm3F1PIX8jSwd2TOD6xGCZ4A== X-Received: by 2002:a05:6000:12ce:: with SMTP id l14mr6580381wrx.342.1575390725033; Tue, 03 Dec 2019 08:32:05 -0800 (PST) Received: from localhost (pD9E518ED.dip0.t-ipconnect.de. [217.229.24.237]) by smtp.gmail.com with ESMTPSA id h17sm4460645wrs.18.2019.12.03.08.32.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 03 Dec 2019 08:32:04 -0800 (PST) From: Thierry Reding To: Thierry Reding Subject: [PATCH 1/3] lib/scatterlist: Add contiguous DMA chunks helpers Date: Tue, 3 Dec 2019 17:32:01 +0100 Message-Id: <20191203163203.1486837-1-thierry.reding@gmail.com> X-Mailer: git-send-email 2.23.0 MIME-Version: 1.0 X-Mailman-Original-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=8EYcVq3D13Cv4p0YNI7vV4r0UyMzhZvJG8/eW5rX0Js=; b=M1RiCYW2WNP7GbjFLZELTAtnhtCw8Gpb8OacJDUGjYNnOkqc76EaY7gHlP+UgXvCa1 GJddsGVbqve62OHibGYMYYB8iPyMKbNgYcxCdXW3el6pAJPj6ARv0LUSCbyzcP/TnTrD eTaKuFyO8WaN6LuOcS0vZWE3vxg24NRasxoKICvL2ykDKXGBs2+ABCEV5INxlrKWmr7A 8sAyAaUyU1xhNNo0o/xOh4JCiBdyGuXYE2TxyGheydfWEb8EeLNrAJehemOH4MgPEH/8 pa0hmcvKk60hubUMJL7587wLjV0Gh9YIxYFXuNIvY6W+ZJdhpYQVRaqi2chuYThleQ6M V+Wg== X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-tegra@vger.kernel.org, dri-devel@lists.freedesktop.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" From: Thierry Reding Add a few helpers to count the number of contiguous DMA chunks found in an SG table. This is useful to determine whether or not a mapping can be used by drivers whose devices need contiguous memory. Signed-off-by: Thierry Reding --- include/linux/scatterlist.h | 11 +++++++++++ lib/scatterlist.c | 29 +++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h index 6eec50fb36c8..51a8416623a9 100644 --- a/include/linux/scatterlist.h +++ b/include/linux/scatterlist.h @@ -262,6 +262,7 @@ int sg_split(struct scatterlist *in, const int in_mapped_nents, const size_t *split_sizes, struct scatterlist **out, int *out_mapped_nents, gfp_t gfp_mask); +unsigned int sg_dma_count_chunks(struct scatterlist *sgl, unsigned int nents); typedef struct scatterlist *(sg_alloc_fn)(unsigned int, gfp_t); typedef void (sg_free_fn)(struct scatterlist *, unsigned int); @@ -306,6 +307,16 @@ size_t sg_pcopy_to_buffer(struct scatterlist *sgl, unsigned int nents, size_t sg_zero_buffer(struct scatterlist *sgl, unsigned int nents, size_t buflen, off_t skip); +static inline unsigned int sgt_dma_count_chunks(struct sg_table *sgt) +{ + return sg_dma_count_chunks(sgt->sgl, sgt->nents); +} + +static inline bool sgt_dma_contiguous(struct sg_table *sgt) +{ + return sgt_dma_count_chunks(sgt) == 1; +} + /* * Maximum number of entries that will be allocated in one piece, if * a list larger than this is required then chaining will be utilized. diff --git a/lib/scatterlist.c b/lib/scatterlist.c index c2cf2c311b7d..4c0d11968f8d 100644 --- a/lib/scatterlist.c +++ b/lib/scatterlist.c @@ -142,6 +142,35 @@ void sg_init_one(struct scatterlist *sg, const void *buf, unsigned int buflen) } EXPORT_SYMBOL(sg_init_one); +/** + * sg_dma_count_chunks - return number of contiguous DMA chunks in scatterlist + * @sgl: SG table + * @nents: number of entries in SG table + */ +unsigned int sg_dma_count_chunks(struct scatterlist *sgl, unsigned int nents) +{ + dma_addr_t next = ~(dma_addr_t)0; + unsigned int count = 0, i; + struct scatterlist *s; + + for_each_sg(sgl, s, nents, i) { + /* + * sg_dma_address(s) is only valid for entries that have + * sg_dma_len(s) != 0. + */ + if (!sg_dma_len(s)) + continue; + + if (sg_dma_address(s) != next) { + next = sg_dma_address(s) + sg_dma_len(s); + count++; + } + } + + return count; +} +EXPORT_SYMBOL(sg_dma_count_chunks); + /* * The default behaviour of sg_alloc_table() is to use these kmalloc/kfree * helpers.