From: Douglas Anderson Date: Mon, 6 Apr 2026 23:22:58 +0000 (-0700) Subject: driver core: Replace dev->dma_ops_bypass with dev_dma_ops_bypass() X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=9ad67f494ba6bdb4e7bb612640158f645932dca3;p=thirdparty%2Fkernel%2Flinux.git 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 Cc: Alexey Kardashevskiy Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Acked-by: Greg Kroah-Hartman Acked-by: Marek Szyprowski Signed-off-by: Douglas Anderson Link: https://patch.msgid.link/20260406162231.v5.5.If62b84471ef2c85e7ad250f0468867d6dba965ab@changeid Signed-off-by: Danilo Krummrich --- diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 8b4de508d2eb1..1f8b5a0f69be2 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 cc93a5e1e5d23..099533cbdd2ff 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 a81a316971ff4..fe3ab94f3d830 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; }