[PATCH v3 6/9] driver core: Replace dev->state_synced with DEV_FLAG_STATE_SYNCED

From: Douglas Anderson

Date: Thu Apr 02 2026 - 20:55:08 EST


In C, bitfields are not necessarily safe to modify from multiple
threads without locking. Switch "state_synced" over to the "flags"
field so modifications are safe.

Cc: Saravana Kannan <saravanak@xxxxxxxxxx>
Signed-off-by: Douglas Anderson <dianders@xxxxxxxxxxxx>
---
Not fixing any known bugs; problem is theoretical and found by code
inspection. Change is done somewhat manually and only lightly tested
(mostly compile-time tested).

Changes in v3:
- New

drivers/base/core.c | 9 +++++----
drivers/base/dd.c | 8 +++-----
include/linux/device.h | 8 ++++----
3 files changed, 12 insertions(+), 13 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index cbdfee887833..8dbb7a9c7aab 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1123,7 +1123,7 @@ static void __device_links_queue_sync_state(struct device *dev,

if (!dev_has_sync_state(dev))
return;
- if (dev->state_synced)
+ if (test_bit(DEV_FLAG_STATE_SYNCED, &dev->flags))
return;

list_for_each_entry(link, &dev->links.consumers, s_node) {
@@ -1138,7 +1138,7 @@ static void __device_links_queue_sync_state(struct device *dev,
* than once. This can happen if new consumers get added to the device
* and probed before the list is flushed.
*/
- dev->state_synced = true;
+ set_bit(DEV_FLAG_STATE_SYNCED, &dev->flags);

if (WARN_ON(!list_empty(&dev->links.defer_sync)))
return;
@@ -1779,7 +1779,8 @@ static int fw_devlink_dev_sync_state(struct device *dev, void *data)
struct device *sup = link->supplier;

if (!device_link_test(link, DL_FLAG_MANAGED) ||
- link->status == DL_STATE_ACTIVE || sup->state_synced ||
+ link->status == DL_STATE_ACTIVE ||
+ test_bit(DEV_FLAG_STATE_SYNCED, &sup->flags) ||
!dev_has_sync_state(sup))
return 0;

@@ -1793,7 +1794,7 @@ static int fw_devlink_dev_sync_state(struct device *dev, void *data)
return 0;

dev_warn(sup, "Timed out. Forcing sync_state()\n");
- sup->state_synced = true;
+ set_bit(DEV_FLAG_STATE_SYNCED, &sup->flags);
get_device(sup);
list_add_tail(&sup->links.defer_sync, data);

diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 66df31696349..f5d004f919ae 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -581,12 +581,10 @@ static ssize_t state_synced_store(struct device *dev,
return -EINVAL;

device_lock(dev);
- if (!dev->state_synced) {
- dev->state_synced = true;
+ if (!test_and_set_bit(DEV_FLAG_STATE_SYNCED, &dev->flags))
dev_sync_state(dev);
- } else {
+ else
ret = -EINVAL;
- }
device_unlock(dev);

return ret ? ret : count;
@@ -598,7 +596,7 @@ static ssize_t state_synced_show(struct device *dev,
bool val;

device_lock(dev);
- val = dev->state_synced;
+ val = test_bit(DEV_FLAG_STATE_SYNCED, &dev->flags);
device_unlock(dev);

return sysfs_emit(buf, "%u\n", val);
diff --git a/include/linux/device.h b/include/linux/device.h
index f5845bd7c3e6..6c961dac9fdb 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -477,6 +477,9 @@ struct device_physical_location {
* 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_STATE_SYNCED: The hardware state of this device has been synced to
+ * match the software state of this device by calling the
+ * driver/bus sync_state() callback.
*/
enum struct_device_flags {
DEV_FLAG_READY_TO_PROBE,
@@ -484,6 +487,7 @@ enum struct_device_flags {
DEV_FLAG_DMA_IOMMU,
DEV_FLAG_DMA_SKIP_SYNC,
DEV_FLAG_DMA_OPS_BYPASS,
+ DEV_FLAG_STATE_SYNCED,
};

/**
@@ -565,9 +569,6 @@ enum struct_device_flags {
* @offline: Set after successful invocation of bus type's .offline().
* @of_node_reused: Set if the device-tree node is shared with an ancestor
* device.
- * @state_synced: The hardware state of this device has been synced to match
- * the software state of this device by calling the driver/bus
- * sync_state() callback.
* @dma_coherent: this particular device is dma coherent, even if the
* architecture supports non-coherent devices.
* @flags: DEV_FLAG_XXX flags. Use atomic bitfield operations to modify.
@@ -677,7 +678,6 @@ struct device {
bool offline_disabled:1;
bool offline:1;
bool of_node_reused:1;
- bool state_synced:1;
#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
--
2.53.0.1213.gd9a14994de-goog