]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
driver core: Replace dev->dma_ops_bypass with dev_dma_ops_bypass()
authorDouglas Anderson <dianders@chromium.org>
Mon, 6 Apr 2026 23:22:58 +0000 (16:22 -0700)
committerDanilo Krummrich <dakr@kernel.org>
Sun, 26 Apr 2026 21:43:05 +0000 (23:43 +0200)
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>
arch/powerpc/kernel/dma-iommu.c
include/linux/device.h
kernel/dma/mapping.c

index 8b4de508d2eb10d0ce16e888a7caffc25e58b00e..1f8b5a0f69be28afe4e1f37bd9d332a5be2b98f2 100644 (file)
@@ -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;
 }
 
index cc93a5e1e5d23332c8ececd18627d245d318e611..099533cbdd2ff0cdb439a7a9a08376bbe09d2e2e 100644 (file)
@@ -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
 
index a81a316971ff4a278796a921d4a5984b03a62a6e..fe3ab94f3d830ee5579f5e0099e58aa5123d9db2 100644 (file)
@@ -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;
 }