aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2026-04-06 16:22:58 -0700
committerDanilo Krummrich <dakr@kernel.org>2026-04-26 23:43:05 +0200
commit9ad67f494ba6bdb4e7bb612640158f645932dca3 (patch)
tree6b171edaed3d41d9c26d005ee4bfb9e19e2090da
parentd99167df047a12cac636188f994a9e8f1f9779ab (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.c8
-rw-r--r--include/linux/device.h15
-rw-r--r--kernel/dma/mapping.c4
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;
}