diff options
| author | Douglas Anderson <dianders@chromium.org> | 2026-04-06 16:22:58 -0700 |
|---|---|---|
| committer | Danilo Krummrich <dakr@kernel.org> | 2026-04-26 23:43:05 +0200 |
| commit | 9ad67f494ba6bdb4e7bb612640158f645932dca3 (patch) | |
| tree | 6b171edaed3d41d9c26d005ee4bfb9e19e2090da | |
| parent | d99167df047a12cac636188f994a9e8f1f9779ab (diff) | |
driver core: Replace dev->dma_ops_bypass with dev_dma_ops_bypass()
In C, bitfields are not necessarily safe to modify from multiple
threads without locking. Switch "dma_ops_bypass" over to the "flags"
field so modifications are safe.
Cc: Christoph Hellwig <hch@lst.de>
Cc: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Rafael J. Wysocki (Intel) <rafael@kernel.org>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Link: https://patch.msgid.link/20260406162231.v5.5.If62b84471ef2c85e7ad250f0468867d6dba965ab@changeid
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
| -rw-r--r-- | arch/powerpc/kernel/dma-iommu.c | 8 | ||||
| -rw-r--r-- | include/linux/device.h | 15 | ||||
| -rw-r--r-- | kernel/dma/mapping.c | 4 |
3 files changed, 12 insertions, 15 deletions
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 8b4de508d2eb..1f8b5a0f69be 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -67,7 +67,7 @@ bool arch_dma_unmap_sg_direct(struct device *dev, struct scatterlist *sg, } bool arch_dma_alloc_direct(struct device *dev) { - if (dev->dma_ops_bypass && dev->bus_dma_limit) + if (dev_dma_ops_bypass(dev) && dev->bus_dma_limit) return true; return false; @@ -75,7 +75,7 @@ bool arch_dma_alloc_direct(struct device *dev) bool arch_dma_free_direct(struct device *dev, dma_addr_t dma_handle) { - if (!dev->dma_ops_bypass || !dev->bus_dma_limit) + if (!dev_dma_ops_bypass(dev) || !dev->bus_dma_limit) return false; return is_direct_handle(dev, dma_handle); @@ -164,7 +164,7 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask) * fixed ops will be used for RAM. This is limited by * bus_dma_limit which is set when RAM is pre-mapped. */ - dev->dma_ops_bypass = true; + dev_set_dma_ops_bypass(dev); dev_info(dev, "iommu: 64-bit OK but direct DMA is limited by %llx\n", dev->bus_dma_limit); return 1; @@ -185,7 +185,7 @@ int dma_iommu_dma_supported(struct device *dev, u64 mask) } dev_dbg(dev, "iommu: not 64-bit, using default ops\n"); - dev->dma_ops_bypass = false; + dev_clear_dma_ops_bypass(dev); return 1; } diff --git a/include/linux/device.h b/include/linux/device.h index cc93a5e1e5d2..099533cbdd2f 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -519,6 +519,11 @@ struct device_physical_location { * doesn't rely on dma_ops structure. * @DEV_FLAG_DMA_SKIP_SYNC: DMA sync operations can be skipped for coherent * buffers. + * @DEV_FLAG_DMA_OPS_BYPASS: If set then the dma_ops are bypassed for the + * streaming DMA operations (->map_* / ->unmap_* / ->sync_*), and + * optional (if the coherent mask is large enough) also for dma + * allocations. This flag is managed by the dma ops instance from + * ->dma_supported. * @DEV_FLAG_COUNT: Number of defined struct_device_flags. */ enum struct_device_flags { @@ -526,6 +531,7 @@ enum struct_device_flags { DEV_FLAG_CAN_MATCH = 1, DEV_FLAG_DMA_IOMMU = 2, DEV_FLAG_DMA_SKIP_SYNC = 3, + DEV_FLAG_DMA_OPS_BYPASS = 4, DEV_FLAG_COUNT }; @@ -614,11 +620,6 @@ enum struct_device_flags { * sync_state() callback. * @dma_coherent: this particular device is dma coherent, even if the * architecture supports non-coherent devices. - * @dma_ops_bypass: If set to %true then the dma_ops are bypassed for the - * streaming DMA operations (->map_* / ->unmap_* / ->sync_*), - * 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. * @flags: DEV_FLAG_XXX flags. Use atomic bitfield operations to modify. * * At the lowest level, every device in a Linux system is represented by an @@ -732,9 +733,6 @@ struct device { defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) bool dma_coherent:1; #endif -#ifdef CONFIG_DMA_OPS_BYPASS - bool dma_ops_bypass : 1; -#endif DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; @@ -765,6 +763,7 @@ __create_dev_flag_accessors(ready_to_probe, DEV_FLAG_READY_TO_PROBE); __create_dev_flag_accessors(can_match, DEV_FLAG_CAN_MATCH); __create_dev_flag_accessors(dma_iommu, DEV_FLAG_DMA_IOMMU); __create_dev_flag_accessors(dma_skip_sync, DEV_FLAG_DMA_SKIP_SYNC); +__create_dev_flag_accessors(dma_ops_bypass, DEV_FLAG_DMA_OPS_BYPASS); #undef __create_dev_flag_accessors diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index a81a316971ff..fe3ab94f3d83 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -126,11 +126,9 @@ static bool dma_go_direct(struct device *dev, dma_addr_t mask, if (likely(!ops)) return true; -#ifdef CONFIG_DMA_OPS_BYPASS - if (dev->dma_ops_bypass) + if (IS_ENABLED(CONFIG_DMA_OPS_BYPASS) && dev_dma_ops_bypass(dev)) return min_not_zero(mask, dev->bus_dma_limit) >= dma_direct_get_required_mask(dev); -#endif return false; } |
