From: Marek Szyprowski <m.szyprowski@samsung.com>
To: Alexander Lobakin <aleksander.lobakin@intel.com>,
Christoph Hellwig <hch@lst.de>
Cc: Eric Dumazet <edumazet@google.com>,
Jakub Kicinski <kuba@kernel.org>,
Steven Price <steven.price@arm.com>,
Robin Murphy <robin.murphy@arm.com>,
Joerg Roedel <joro@8bytes.org>, Will Deacon <will@kernel.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
Magnus Karlsson <magnus.karlsson@intel.com>,
nex.sw.ncis.osdt.itp.upstreaming@intel.com, bpf@vger.kernel.org,
netdev@vger.kernel.org, iommu@lists.linux.dev,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH] dma: fix DMA sync for drivers not calling dma_set_mask*()
Date: Thu, 9 May 2024 17:27:31 +0200 [thread overview]
Message-ID: <34f29631-af45-462a-a168-e9f4bb4451cf@samsung.com> (raw)
In-Reply-To: <20240509144616.938519-1-aleksander.lobakin@intel.com>
On 09.05.2024 16:46, Alexander Lobakin wrote:
> There are several reports that the DMA sync shortcut broke non-coherent
> devices.
> dev->dma_need_sync is false after the &device allocation and if a driver
> didn't call dma_set_mask*(), it will still be false even if the device
> is not DMA-coherent and thus needs synchronizing. Due to historical
> reasons, there's still a lot of drivers not calling it.
> Invert the boolean, so that the sync will be performed by default and
> the shortcut will be enabled only when calling dma_set_mask*().
>
> Reported-by: Marek Szyprowski <m.szyprowski@samsung.com>
> Closes: https://lore.kernel.org/lkml/46160534-5003-4809-a408-6b3a3f4921e9@samsung.com
> Reported-by: Steven Price <steven.price@arm.com>
> Closes: https://lore.kernel.org/lkml/010686f5-3049-46a1-8230-7752a1b433ff@arm.com
> Fixes: 32ba8b823252 ("dma: avoid redundant calls for sync operations")
> Signed-off-by: Alexander Lobakin <aleksander.lobakin@intel.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
> ---
> include/linux/device.h | 4 ++--
> include/linux/dma-map-ops.h | 4 ++--
> include/linux/dma-mapping.h | 2 +-
> kernel/dma/mapping.c | 10 +++++-----
> kernel/dma/swiotlb.c | 2 +-
> 5 files changed, 11 insertions(+), 11 deletions(-)
>
> diff --git a/include/linux/device.h b/include/linux/device.h
> index ed95b829f05b..d4b50accff26 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -691,7 +691,7 @@ struct device_physical_location {
> * and optionall (if the coherent mask is large enough) also
> * for dma allocations. This flag is managed by the dma ops
> * instance from ->dma_supported.
> - * @dma_need_sync: The device needs performing DMA sync operations.
> + * @dma_skip_sync: DMA sync operations can be skipped for coherent buffers.
> *
> * At the lowest level, every device in a Linux system is represented by an
> * instance of struct device. The device structure contains the information
> @@ -805,7 +805,7 @@ struct device {
> bool dma_ops_bypass : 1;
> #endif
> #ifdef CONFIG_DMA_NEED_SYNC
> - bool dma_need_sync:1;
> + bool dma_skip_sync:1;
> #endif
> };
>
> diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h
> index 4893cb89cb52..5217b922d29f 100644
> --- a/include/linux/dma-map-ops.h
> +++ b/include/linux/dma-map-ops.h
> @@ -280,8 +280,8 @@ static inline void dma_reset_need_sync(struct device *dev)
> {
> #ifdef CONFIG_DMA_NEED_SYNC
> /* Reset it only once so that the function can be called on hotpath */
> - if (unlikely(!dev->dma_need_sync))
> - dev->dma_need_sync = true;
> + if (unlikely(dev->dma_skip_sync))
> + dev->dma_skip_sync = false;
> #endif
> }
>
> diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
> index eb4e15893b6c..f693aafe221f 100644
> --- a/include/linux/dma-mapping.h
> +++ b/include/linux/dma-mapping.h
> @@ -295,7 +295,7 @@ bool __dma_need_sync(struct device *dev, dma_addr_t dma_addr);
> static inline bool dma_dev_need_sync(const struct device *dev)
> {
> /* Always call DMA sync operations when debugging is enabled */
> - return dev->dma_need_sync || IS_ENABLED(CONFIG_DMA_API_DEBUG);
> + return !dev->dma_skip_sync || IS_ENABLED(CONFIG_DMA_API_DEBUG);
> }
>
> static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t addr,
> diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c
> index 3524bc92c37f..3f77c3f8d16d 100644
> --- a/kernel/dma/mapping.c
> +++ b/kernel/dma/mapping.c
> @@ -392,7 +392,7 @@ bool __dma_need_sync(struct device *dev, dma_addr_t dma_addr)
>
> if (dma_map_direct(dev, ops))
> /*
> - * dma_need_sync could've been reset on first SWIOTLB buffer
> + * dma_skip_sync could've been reset on first SWIOTLB buffer
> * mapping, but @dma_addr is not necessary an SWIOTLB buffer.
> * In this case, fall back to more granular check.
> */
> @@ -407,20 +407,20 @@ static void dma_setup_need_sync(struct device *dev)
>
> if (dma_map_direct(dev, ops) || (ops->flags & DMA_F_CAN_SKIP_SYNC))
> /*
> - * dma_need_sync will be reset to %true on first SWIOTLB buffer
> + * dma_skip_sync will be reset to %false on first SWIOTLB buffer
> * mapping, if any. During the device initialization, it's
> * enough to check only for the DMA coherence.
> */
> - dev->dma_need_sync = !dev_is_dma_coherent(dev);
> + dev->dma_skip_sync = dev_is_dma_coherent(dev);
> else if (!ops->sync_single_for_device && !ops->sync_single_for_cpu &&
> !ops->sync_sg_for_device && !ops->sync_sg_for_cpu)
> /*
> * Synchronization is not possible when none of DMA sync ops
> * is set.
> */
> - dev->dma_need_sync = false;
> + dev->dma_skip_sync = true;
> else
> - dev->dma_need_sync = true;
> + dev->dma_skip_sync = false;
> }
> #else /* !CONFIG_DMA_NEED_SYNC */
> static inline void dma_setup_need_sync(struct device *dev) { }
> diff --git a/kernel/dma/swiotlb.c b/kernel/dma/swiotlb.c
> index ae3e593eaadb..068134697cf1 100644
> --- a/kernel/dma/swiotlb.c
> +++ b/kernel/dma/swiotlb.c
> @@ -1409,7 +1409,7 @@ phys_addr_t swiotlb_tbl_map_single(struct device *dev, phys_addr_t orig_addr,
> }
>
> /*
> - * If dma_need_sync wasn't set, reset it on first SWIOTLB buffer
> + * If dma_skip_sync was set, reset it on first SWIOTLB buffer
> * mapping to always sync SWIOTLB buffers.
> */
> dma_reset_need_sync(dev);
Best regards
--
Marek Szyprowski, PhD
Samsung R&D Institute Poland
next prev parent reply other threads:[~2024-05-09 15:27 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20240509144704eucas1p2fe6bfb07a9b39f548e7db0f24e47eb0a@eucas1p2.samsung.com>
2024-05-09 14:46 ` [PATCH] dma: fix DMA sync for drivers not calling dma_set_mask*() Alexander Lobakin
2024-05-09 15:11 ` Steven Price
2024-05-09 15:16 ` Alexander Lobakin
2024-05-09 15:19 ` Christoph Hellwig
2024-05-09 15:27 ` Marek Szyprowski [this message]
2024-05-10 7:12 ` Przemek Kitszel
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=34f29631-af45-462a-a168-e9f4bb4451cf@samsung.com \
--to=m.szyprowski@samsung.com \
--cc=aleksander.lobakin@intel.com \
--cc=bpf@vger.kernel.org \
--cc=edumazet@google.com \
--cc=hch@lst.de \
--cc=iommu@lists.linux.dev \
--cc=joro@8bytes.org \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=magnus.karlsson@intel.com \
--cc=netdev@vger.kernel.org \
--cc=nex.sw.ncis.osdt.itp.upstreaming@intel.com \
--cc=rafael@kernel.org \
--cc=robin.murphy@arm.com \
--cc=steven.price@arm.com \
--cc=will@kernel.org \
/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.