From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dy1-f181.google.com (mail-dy1-f181.google.com [74.125.82.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C41278C9C for ; Sat, 4 Apr 2026 00:07:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261244; cv=none; b=uE8JnC5CR+PUIHLRaSs0df1z5Zn5UE+ubpptDyuLANsd9DAPOmlNMkC5ND/zTm1JVFMzJigXL6Mku0TsuhEMDauwYLSqs9GxMxqvFLkhr0UVdMUBwZUaxIgTD/n2edP9+q5UjBT3U27eCG1AXTk4wZMsqkx0iCD/0aqcID57K2Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261244; c=relaxed/simple; bh=III6jfoTjxrvqqvxvqPImVr6gqYLV5UXkESYuPeEMdk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KufL1VuUiFLKKc1VnoZu/VAaLEg0gDgyTfjYpIeZWEVFWO8cOKRHy1aMjj2wiZHbV1o4d4IjIhlH4+8jYAcJD6x6m/063gIq6SHptDXR+jDXWlrql+akutVZdbTH4vs4Rn+HIb1OR0hQVR1Q4AQKGjL+RaXidh83aVN1daMJdfM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=jGsuYDxl; arc=none smtp.client-ip=74.125.82.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="jGsuYDxl" Received: by mail-dy1-f181.google.com with SMTP id 5a478bee46e88-2c4db6bca03so1216144eec.1 for ; Fri, 03 Apr 2026 17:07:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261242; x=1775866042; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LJEW8I+GJiIRTdX3t2bIsrL+T4N6bIAtJLVhOniwR48=; b=jGsuYDxls1mCr6U9W1qnEUv/bjrBffGsxMbgJ3W8AZM7FK5xP4NZX4hhUCrydWOIjf nMQHargI5bR7MySGSGo0JzqBibjBNBSdt1LSNeO5beeuh9nXJ3U6jt28yyGyXJoIUC8P sRZ9IMlfs5VrykiwdUvVxKW42TSF/UwQWDErI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261242; x=1775866042; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=LJEW8I+GJiIRTdX3t2bIsrL+T4N6bIAtJLVhOniwR48=; b=dOHSTzYTXiJTZA0FofOpQqB/bb/IAbXdR1cEzMljkYiNO5xNBOXQeX7w6vAuwTScik 2rSvoiUZAbudXUm/Vey8WTzoGTs6/UthEqnhFrz+gj0r8eb+CDSTAXYbcqfc+6JmJ1/Y zh6SrF5ARSIsF3cqf7huTOyTlWczDBgrQ7aU5P0HiIBvHx4xoy3sccKNsNHgIT9ITl8o BJKOu5H27/u2j0vJQjouau6Xh3VyTvnex1tDRk/GQ76w8HQMsy9FZSAxp6fiE9oVsSTI 6opuMZvQGKbf5qa/bLpw8HVscbAXEucB0tt0PItJq0gPhjxuFFQ1VwB7IQRghZQUbe11 4REA== X-Forwarded-Encrypted: i=1; AJvYcCVdjOWKY3vETBahqt4Ln2/ivvnUZ/+PLkeIhGhHTLPHxqYHrwn8pCMwI0pCxxF6q4v2cQjC1/xbsIdr7lc=@vger.kernel.org X-Gm-Message-State: AOJu0YyVr2EGr85702GYgfm7OdyDKVqyMJqAAVGQ9htsz2sEDxkUqq/O rXmtLVqpqXV2/W10/aZ9IT8icKdfAY47KBegWvbcyy/DL8YbalCCooozgon3jOUnfQ== X-Gm-Gg: AeBDievpBNZJ6E7Qn3liaQVNRd+zHNLEkfUma1XIJ2Qiqcg0vIGUWyx6OIvFeLPEJlv o8cHrjopfZYRHM3cyuXM6R6xG+gzVCi83fbNDPDuDYMQW+RpALzJC4G5hItoY/71HYl01LXeiOZ 2IJ/YZKRAOycdbCh6CtgnIQM9yYDhiTnKkxYypD4I02mFTg1VJYxCmb/TZOcGgtVMI9UguwQoZR FKuaPOoE7iENXJ+JpfJg9e1qRpM8vLbtGhsSbdyL+LvJ8+l4wFDlgOT/+K8ds2aa42tt5CAUvVZ FJt+1P5F+Qn94PXQuo9LQ9QHTWXjFm/RH+1/QDq0CQ5oo5pZOVvduFogmNr53R8HhPlpf+sPCVI eiKmdDMX6+4NMB9U/y+LpPMeTnUpksVkxPQkqITLeHPKiTN6YycBbvHtq/0LqkLY+GXu7IRakHk qGkZzzYEiz883m9fQ+3F8l+18jHJkk/K9zbrpiPwsGS3InM/66/oV0PlxGv6lUZxf5RuveexlCS f4T47Aziwc= X-Received: by 2002:a05:7301:1f01:b0:2c5:704f:7142 with SMTP id 5a478bee46e88-2cbf920f3c9mr1937248eec.2.1775261242319; Fri, 03 Apr 2026 17:07:22 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:21 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , stable@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 1/9] driver core: Don't let a device probe until it's ready Date: Fri, 3 Apr 2026 17:04:55 -0700 Message-ID: <20260403170432.v4.1.Id750b0fbcc94f23ed04b7aecabcead688d0d8c17@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The moment we link a "struct device" into the list of devices for the bus, it's possible probe can happen. This is because another thread can load the driver at any time and that can cause the device to probe. This has been seen in practice with a stack crawl that looks like this [1]: really_probe() __driver_probe_device() driver_probe_device() __driver_attach() bus_for_each_dev() driver_attach() bus_add_driver() driver_register() __platform_driver_register() init_module() [some module] do_one_initcall() do_init_module() load_module() __arm64_sys_finit_module() invoke_syscall() As a result of the above, it was seen that device_links_driver_bound() could be called for the device before "dev->fwnode->dev" was assigned. This prevented __fw_devlink_pickup_dangling_consumers() from being called which meant that other devices waiting on our driver's sub-nodes were stuck deferring forever. It's believed that this problem is showing up suddenly for two reasons: 1. Android has recently (last ~1 year) implemented an optimization to the order it loads modules [2]. When devices opt-in to this faster loading, modules are loaded one-after-the-other very quickly. This is unlike how other distributions do it. The reproduction of this problem has only been seen on devices that opt-in to Android's "parallel module loading". 2. Android devices typically opt-in to fw_devlink, and the most noticeable issue is the NULL "dev->fwnode->dev" in device_links_driver_bound(). fw_devlink is somewhat new code and also not in use by all Linux devices. Even though the specific symptom where "dev->fwnode->dev" wasn't assigned could be fixed by moving that assignment higher in device_add(), other parts of device_add() (like the call to device_pm_add()) are also important to run before probe. Only moving the "dev->fwnode->dev" assignment would likely fix the current symptoms but lead to difficult-to-debug problems in the future. Fix the problem by preventing probe until device_add() has run far enough that the device is ready to probe. If somehow we end up trying to probe before we're allowed, __driver_probe_device() will return -EPROBE_DEFER which will make certain the device is noticed. In the race condition that was seen with Android's faster module loading, we will temporarily add the device to the deferred list and then take it off immediately when device_add() probes the device. Instead of adding another flag to the bitfields already in "struct device", instead add a new "flags" field and use that. This allows us to freely change the bit from different thread without holding the device lock and without worrying about corrupting nearby bits. [1] Captured on a machine running a downstream 6.6 kernel [2] https://cs.android.com/android/platform/superproject/main/+/main:system= /core/libmodprobe/libmodprobe.cpp?q=3DLoadModulesParallel Cc: stable@vger.kernel.org Fixes: 2023c610dc54 ("Driver core: add new device to bus's list before prob= ing") Reviewed-by: Alan Stern Reviewed-by: Rafael J. Wysocki (Intel) Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich --- v1: https://lore.kernel.org/r/20260320200656.RFC.1.Id750b0fbcc94f23ed04b7ae= cabcead688d0d8c17@changeid v2: https://lore.kernel.org/r/20260330072839.v2.1.Id750b0fbcc94f23ed04b7aec= abcead688d0d8c17@changeid v3: https://lore.kernel.org/r/20260403005005.30424-1-dianders@chromium.org/ As of v2 this feels like a very safe change. It doesn't change the ordering of any steps of probe and it _just_ prevents the early probe from happening. I ran tests where I turned the printout "Device not ready_to_probe" on and I could see the printout happening, evidence of the race occurring from other printouts, and things successfully being resolved. I kept Alan and Rafael's Reviewed-by tags in v3 even though I changed the implementation to use "flags" as per Danilo's request. This didn't seem like a major enough change to remove tags, but please shout if you'd like your tag removed. Changes in v4: - Use accessor functions for flags Changes in v3: - Use a new "flags" bitfield - Add missing \n in probe error message Changes in v2: - Instead of adjusting the ordering, use "ready_to_probe" flag drivers/base/core.c | 13 +++++++++++++ drivers/base/dd.c | 12 ++++++++++++ include/linux/device.h | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 09b98f02f559..f07745659de3 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3688,6 +3688,19 @@ int device_add(struct device *dev) fw_devlink_link_device(dev); } =20 + /* + * The moment the device was linked into the bus's "klist_devices" in + * bus_add_device() then it's possible that probe could have been + * attempted in a different thread via userspace loading a driver + * matching the device. "ready_to_prove" being unset would have + * blocked those attempts. Now that all of the above initialization has + * happened, unblock probe. If probe happens through another thread + * after this point but before bus_probe_device() runs then it's fine. + * bus_probe_device() -> device_initial_probe() -> __device_attach() + * will notice (under device_lock) that the device is already bound. + */ + dev_set_ready_to_probe(dev); + bus_probe_device(dev); =20 /* diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 37c7e54e0e4c..8ec93128ea98 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -848,6 +848,18 @@ static int __driver_probe_device(const struct device_d= river *drv, struct device if (dev->driver) return -EBUSY; =20 + /* + * In device_add(), the "struct device" gets linked into the subsystem's + * list of devices and broadcast to userspace (via uevent) before we're + * quite ready to probe. Those open pathways to driver probe before + * we've finished enough of device_add() to reliably support probe. + * Detect this and tell other pathways to try again later. device_add() + * itself will also try to probe immediately after setting + * "ready_to_probe". + */ + if (!dev_ready_to_probe(dev)) + return dev_err_probe(dev, -EPROBE_DEFER, "Device not ready to probe\n"); + dev->can_match =3D true; dev_dbg(dev, "bus: '%s': %s: matched device with driver %s\n", drv->bus->name, __func__, drv->name); diff --git a/include/linux/device.h b/include/linux/device.h index e65d564f01cd..5eb0b22958e4 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -458,6 +458,21 @@ struct device_physical_location { bool lid; }; =20 +/** + * enum struct_device_flags - Flags in struct device + * + * Each flag should have a set of accessor functions created via + * __create_dev_flag_accessors() for each access. + * + * @DEV_FLAG_READY_TO_PROBE: If set then device_add() has finished enough + * initialization that probe could be called. + */ +enum struct_device_flags { + DEV_FLAG_READY_TO_PROBE =3D 0, + + DEV_FLAG_COUNT +}; + /** * struct device - The basic device structure * @parent: The device's "parent" device, the device to which it is attach= ed. @@ -553,6 +568,7 @@ struct device_physical_location { * @dma_skip_sync: DMA sync operations can be skipped for coherent buffers. * @dma_iommu: Device is using default IOMMU implementation for DMA and * doesn't rely on dma_ops structure. + * @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 * instance of struct device. The device structure contains the information @@ -675,8 +691,34 @@ struct device { #ifdef CONFIG_IOMMU_DMA bool dma_iommu:1; #endif + + DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; =20 +#define __create_dev_flag_accessors(accessor_name, flag_name) \ +static inline bool dev_##accessor_name(const struct device *dev) \ +{ \ + return test_bit(flag_name, dev->flags); \ +} \ +static inline void dev_set_##accessor_name(struct device *dev) \ +{ \ + set_bit(flag_name, dev->flags); \ +} \ +static inline void dev_clear_##accessor_name(struct device *dev) \ +{ \ + clear_bit(flag_name, dev->flags); \ +} \ +static inline void dev_assign_##accessor_name(struct device *dev, bool val= ue) \ +{ \ + assign_bit(flag_name, dev->flags, value); \ +} \ +static inline bool dev_test_and_set_##accessor_name(struct device *dev) \ +{ \ + return test_and_set_bit(flag_name, dev->flags); \ +} + +__create_dev_flag_accessors(ready_to_probe, DEV_FLAG_READY_TO_PROBE); + /** * struct device_link - Device link representation. * @supplier: The device on the supplier end of the link. --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dy1-f181.google.com (mail-dy1-f181.google.com [74.125.82.181]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A4C7B50276 for ; Sat, 4 Apr 2026 00:07:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.181 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261247; cv=none; b=jExxh0WCuYc7nAWXP/apT7tkwD3DML2s50VqDLTPf+YOkppWKeWDE88UZ9f9U6gxbmwUQIF5G8GP+jHH9DIAnofyW5AkyXco1fJFxQxgTFK89ZqcCBy+dI8q2Yixm5J/bafDDrDMITfJMXO4WimONINgYOCl9I4ONXPrOGQHaso= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261247; c=relaxed/simple; bh=JY7h+w0GKt4GsXMg76jK5zvh+LiKytkPd1+jRUhDFvA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=htf1XBF52U5wKJ8EFGhsem8S6E2bmN9Xd1tMEmIyEPQIl097WvMKVIvRK7GjwGqQmDBy6IpwcMW6rEMSY3iUYkFvE4RFQmSw9P5tlgXRL9EJLWQuDACi9YUTz81MAypzqpeQuBSwItlsScpbOKsrHOCaJoShVwY+R17Ouw5nLK8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=H5NdvqzF; arc=none smtp.client-ip=74.125.82.181 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="H5NdvqzF" Received: by mail-dy1-f181.google.com with SMTP id 5a478bee46e88-2c156c4a9efso2737504eec.1 for ; Fri, 03 Apr 2026 17:07:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261245; x=1775866045; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Y7NMSciOmg5XkKsUSZgnNDTKkHjdVzk1T1Rc96+x1Ko=; b=H5NdvqzFFvXguxNQAsCY9sysdr22R8GhdDEJJa7Lq4CfL+TFY4waWG5Nw2IbUqfDnV IWPbjAUhN2l0iE/Z/wDhCkjV+lOgLAqxpDfKteyPWpQP/rJrC7rPXn2RNcuesObcwLdX GfBl9LatfFPnAshh/apNGu27x5eS6yd6hI7LI= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261245; x=1775866045; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Y7NMSciOmg5XkKsUSZgnNDTKkHjdVzk1T1Rc96+x1Ko=; b=ViSezfTMV4T1ahb77nqEat5Hzp8IpPcEXb7GNHeol+1L656pfR1zRJAp7q4k8YNPAA cODvRYDq+9L2ElTDsgfyA+LbJM9Y39XB1YhBlilND99CiKKSaGBvKsF6JkdLv91rXtkn EmU2guxRBCpBIg15+1S0VmOF9tG9J4+3+4LoUKIqzJVd1nZ8TpHrOzcylPXR6GQ520YS 4hOyHziSBuvQQe28bdfe97+ST4RsdNHmHrQIq67OYoaNo+UjCRyJuLWthNBKPR61ZLPB 68Wn1BQBscEwTEduJnpcWua5qcLpSXkT1QCwz39ln/qjFSR/+QROiA/MLhgtinNHwZgw ihBQ== X-Forwarded-Encrypted: i=1; AJvYcCXD/st20VQpGetKZ1mHR8cn/Osqp/41x3vT1re4K6xdc6r/a02dRw6zFyG/xvw9CKVviEqyDYTtAmLhnOE=@vger.kernel.org X-Gm-Message-State: AOJu0Yx1pgjLRkkunx2brImOyJQVVVzVwu4cgaIIjQ6pc/zJXkB2wLdI 65OysF+qnmheB/vT8uxWGQ/U4ypanLDZ3BIR0+189PyIbE6scNd7rL34uAEVZDNh3Q== X-Gm-Gg: AeBDievjwq46Wvq8GTy+X6r2mNE/QKErAcqOlrx1G0N8RVQqqCCOVDls0A/RKHhJkhl TL8AxNgWFCu0uMON9n2Bc7lX6Aao15KBLJvpov4bKNRmpWEgIt/y6CiX54ZOIkUz4E308L5U6Xk bQLmE2RB1DMs4eeB/9gMFiyeDfV4K86LbpQfEmrtSpUOIt0QbNoTWZZWhQNqHZjj21Ugb5nH74v /wM08XGCG9WA8aFkugGbK/1lYXE7pIbHT95tdt1JoO4SBpeHvmJXs81BWK+P7gXpjNsz31x4TU+ UcCzlMxgCcXGtQyTshbPc0/GVl+nZNF9Oa9HCRXxTkPvTBieMkd34Y7s9BfIhF7zqCQ2c1k4gH2 gyJxXV6aimNPajcPMwc19mIwogFdFBXPftJ3NrSFPaHZjEyMrQWul6FDoPjfJdcMNHNCGOGx1iY gV0vdnS/+GsrdDMfWOzm9cVDaWIEuPvn/XJEB0PKsCBwQOAukY1sAt8y+zqmyZxpXXR9G6BfOwj NgClRMXC7M= X-Received: by 2002:a05:7300:6d23:b0:2a4:3593:466c with SMTP id 5a478bee46e88-2cbf9fe2d96mr2541861eec.8.1775261244759; Fri, 03 Apr 2026 17:07:24 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:23 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 2/9] driver core: Replace dev->can_match with dev_can_match() Date: Fri, 3 Apr 2026 17:04:56 -0700 Message-ID: <20260403170432.v4.2.I54b3ae6311ff34ad30227659d91bb109911a4aea@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In C, bitfields are not necessarily safe to modify from multiple threads without locking. Switch "can_match" over to the "flags" field so modifications are safe. Cc: Saravana Kannan Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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 v4: - Use accessor functions for flags Changes in v3: - New drivers/base/core.c | 10 +++++----- drivers/base/dd.c | 8 ++++---- include/linux/device.h | 9 +++++---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index f07745659de3..8acf7f684417 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1011,7 +1011,7 @@ static void device_links_missing_supplier(struct devi= ce *dev) =20 static bool dev_is_best_effort(struct device *dev) { - return (fw_devlink_best_effort && dev->can_match) || + return (fw_devlink_best_effort && dev_can_match(dev)) || (dev->fwnode && (dev->fwnode->flags & FWNODE_FLAG_BEST_EFFORT)); } =20 @@ -1079,7 +1079,7 @@ int device_links_check_suppliers(struct device *dev) =20 if (dev_is_best_effort(dev) && device_link_test(link, DL_FLAG_INFERRED) && - !link->supplier->can_match) { + !dev_can_match(link->supplier)) { ret =3D -EAGAIN; continue; } @@ -1370,7 +1370,7 @@ void device_links_driver_bound(struct device *dev) } else if (dev_is_best_effort(dev) && device_link_test(link, DL_FLAG_INFERRED) && link->status !=3D DL_STATE_CONSUMER_PROBE && - !link->supplier->can_match) { + !dev_can_match(link->supplier)) { /* * When dev_is_best_effort() is true, we ignore device * links to suppliers that don't have a driver. If the @@ -1758,7 +1758,7 @@ static int fw_devlink_no_driver(struct device *dev, v= oid *data) { struct device_link *link =3D to_devlink(dev); =20 - if (!link->supplier->can_match) + if (!dev_can_match(link->supplier)) fw_devlink_relax_link(link); =20 return 0; @@ -3708,7 +3708,7 @@ int device_add(struct device *dev) * match with any driver, don't block its consumers from probing in * case the consumer device is able to operate without this supplier. */ - if (dev->fwnode && fw_devlink_drv_reg_done && !dev->can_match) + if (dev->fwnode && fw_devlink_drv_reg_done && !dev_can_match(dev)) fw_devlink_unblock_consumers(dev); =20 if (parent) diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 8ec93128ea98..c7c0851ae073 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -132,7 +132,7 @@ static DECLARE_WORK(deferred_probe_work, deferred_probe= _work_func); =20 void driver_deferred_probe_add(struct device *dev) { - if (!dev->can_match) + if (!dev_can_match(dev)) return; =20 mutex_lock(&deferred_probe_mutex); @@ -860,7 +860,7 @@ static int __driver_probe_device(const struct device_dr= iver *drv, struct device if (!dev_ready_to_probe(dev)) return dev_err_probe(dev, -EPROBE_DEFER, "Device not ready to probe\n"); =20 - dev->can_match =3D true; + dev_set_can_match(dev); dev_dbg(dev, "bus: '%s': %s: matched device with driver %s\n", drv->bus->name, __func__, drv->name); =20 @@ -1006,7 +1006,7 @@ static int __device_attach_driver(struct device_drive= r *drv, void *_data) return 0; } else if (ret =3D=3D -EPROBE_DEFER) { dev_dbg(dev, "Device match requests probe deferral\n"); - dev->can_match =3D true; + dev_set_can_match(dev); driver_deferred_probe_add(dev); /* * Device can't match with a driver right now, so don't attempt @@ -1258,7 +1258,7 @@ static int __driver_attach(struct device *dev, void *= data) return 0; } else if (ret =3D=3D -EPROBE_DEFER) { dev_dbg(dev, "Device match requests probe deferral\n"); - dev->can_match =3D true; + dev_set_can_match(dev); driver_deferred_probe_add(dev); /* * Driver could not match with device, but may match with diff --git a/include/linux/device.h b/include/linux/device.h index 5eb0b22958e4..5e42261ba3aa 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -466,9 +466,13 @@ struct device_physical_location { * * @DEV_FLAG_READY_TO_PROBE: If set then device_add() has finished enough * initialization that probe could be called. + * @DEV_FLAG_CAN_MATCH: The device has matched with a driver at least once= or it + * is in a bus (like AMBA) which can't check for matching drivers + * until other devices probe successfully. */ enum struct_device_flags { DEV_FLAG_READY_TO_PROBE =3D 0, + DEV_FLAG_CAN_MATCH =3D 1, =20 DEV_FLAG_COUNT }; @@ -555,9 +559,6 @@ enum struct_device_flags { * @state_synced: The hardware state of this device has been synced to mat= ch * the software state of this device by calling the driver/bus * sync_state() callback. - * @can_match: The device has matched with a driver at least once or it is= in - * a bus (like AMBA) which can't check for matching drivers until - * other devices probe successfully. * @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 @@ -676,7 +677,6 @@ struct device { bool offline:1; bool of_node_reused:1; bool state_synced:1; - bool can_match: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) @@ -718,6 +718,7 @@ static inline bool dev_test_and_set_##accessor_name(str= uct device *dev) \ } =20 __create_dev_flag_accessors(ready_to_probe, DEV_FLAG_READY_TO_PROBE); +__create_dev_flag_accessors(can_match, DEV_FLAG_CAN_MATCH); =20 /** * struct device_link - Device link representation. --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dl1-f46.google.com (mail-dl1-f46.google.com [74.125.82.46]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF528186E58 for ; Sat, 4 Apr 2026 00:07:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.46 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261249; cv=none; b=FKUZw2Rd/uNRMJFFf3OlqYUBrFzZh1Dyxq+D+5g/dhg2jPRQaTH8hWdp1pHZxK5/d/Rf/c0CDw6Beq6V46XL/q+2VftcnmS+EixG2BX93YRpbtTNIzNfzG9PChFlrdOlOcxxoE40sWCjwkks4Bnwxz2tcdmxei7CVojHNvPhkW4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261249; c=relaxed/simple; bh=aZahSfnZH2LIxSJe6x6zdQFMTyLs4fu+wjkHHWUcL+8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PnEYTARqj8w4+kLnah0HEyvmA4lJxV3liEmOm8xzOXiH7wv2Ji7pbXROijrPgo7SedxPQ+BL4xndI02GlETv8Ls95ZU7ci4kXp0lK86wDGSgwOEXm6iwdBYcJZSpN9IjKrU4AicYr6t7fzrvOLm7oGZm6Wh1kaiR6/dxjO4NipQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=nsq71/x4; arc=none smtp.client-ip=74.125.82.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="nsq71/x4" Received: by mail-dl1-f46.google.com with SMTP id a92af1059eb24-128ebee22caso3568301c88.0 for ; Fri, 03 Apr 2026 17:07:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261247; x=1775866047; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jo4F8ZRupwn9qN0zyBWrlRKw8XW6T5nN42rVGGZxhtU=; b=nsq71/x4rPl7Blh+ehkdiUionp/NAh8Cy1oWqhrxlgM/vYd2ncJ5i3RPSS0N4AVaLY FQM+PXeCsMNLolHRa6SKjLqLlGGP977x9DRoTjNhSb0foMzaGC8tCbiAH4EsqtKrPC/x 4Zz5+LU3cuNW52lUIRcvvsZL5sRMz9THEB3Xk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261247; x=1775866047; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=jo4F8ZRupwn9qN0zyBWrlRKw8XW6T5nN42rVGGZxhtU=; b=ZKseraAuxQcGSMJtDGEB5tflRCPqRbox/zmt2pf5to8X1IdlgllAsF34gn98Opt2kH rZt1OxEnGpSU4h+kulkjbm5jEGjQmaQAIOs7+zB2ckGQ3OdZDj74bKKDUHRUQV0TRdAM yUIouIh5ig1IVnnXuHPpq7tIxBWUyXszkILlZ6Gn9CVBP8cEiw8SNSqoONn1FSmHlvu5 zLikMSJ8eYh1QhAdN3cDfSM+8g76C/9v8UBr9CX9H7ouU9dZRJwQ4i/kednvHIoyUwA8 5yCd4MpfXUgzG7EKs54+fvhbNsbc1+rDuLSTDgNjYNZcOQWU2PWJJovG6P76K6op01Z4 y47A== X-Forwarded-Encrypted: i=1; AJvYcCUvSpOa85KfI8QAXOAtqRoJLqVqpABVbYmTabl2qg9PcMDPYo2cn5GK7tvpFJtA0d/MNqXuVF9+FfI3RZI=@vger.kernel.org X-Gm-Message-State: AOJu0Yy0oJFCXAKkKGOum8px/6SIX9DT6dxVV1XCUtrLE6qdtMI0twO0 i7edSE6OeN74dp9+VoPso6szZGzJduXPFVsVgvPdDlmZi2yD4kl2At9qPcGMB3O9Zg== X-Gm-Gg: AeBDieu82axlA70kAp/inB0M6JjUal/74SRqS3sQh0YvR7Tj9LlTpCveBb8Eddpc7On 4+ffqPd+jS2XuhQLLTtVc8tZTPPw0zxRUe1hz8FrkPptT7dGuZydj+4XQzRxlGf99iarra23fBI lACZfEUesSUkyRi0wp+eRi3nRf8IgVbMaTcl/JkeOqQJo5r/94lv3tdjPYdyjwFacowhQHXvDS+ TTEkzCdedAFNShvDluYl8MSW1jY88cb0cckAW1I9N0FYSZ3Is0DwYeKkNhKOsO6bf43Qr6IpC2I UZY0jRxZVPI6P+obJNT9w8Rb5lQWEB0vDTN/XRLbaGzpU/0wUkmbvdZY2uTdBFIrSU3kFwkRmLe 4D1sRYXYQdx9kuBN3i7iJLTKeDdBrYSXNRRj8Weu/jao7qHgPWy+OJxeSHDuWuWJGMRsghYdYCx vIPCbCXUdWVezI8oUAlTdtVCOHsnUrgYPGxd+/KJk3hL2WKCHVLBi+Lb6ZUfH+BisL6HRtHrWlI iKLjqYq3Vg= X-Received: by 2002:a05:7300:748b:b0:2c7:2c0b:f33b with SMTP id 5a478bee46e88-2cbfba8e8eamr2595200eec.20.1775261246987; Fri, 03 Apr 2026 17:07:26 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:26 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , driver-core@lists.linux.dev, iommu@lists.linux.dev, joro@8bytes.org, linux-kernel@vger.kernel.org, will@kernel.org Subject: [PATCH v4 3/9] driver core: Replace dev->dma_iommu with dev_dma_iommu() Date: Fri, 3 Apr 2026 17:04:57 -0700 Message-ID: <20260403170432.v4.3.Id20d5973cbff542fea290e13177e9423f5d81342@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In C, bitfields are not necessarily safe to modify from multiple threads without locking. Switch "dma_iommu" over to the "flags" field so modifications are safe. Cc: Leon Romanovsky Cc: Robin Murphy Cc: Christoph Hellwig Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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). NOTE: even though previously we only took up a bit if CONFIG_IOMMU_DMA, in this change I reserve the bit unconditionally. While we could get the "dynamic" behavior by changing the flags definition to be an "enum", it doesn't seem worth it at this point. This also allows us to move one "#ifdef" to an "if", getting better compile-time testing of both sides of the "if". Changes in v4: - Use accessor functions for flags Changes in v3: - New drivers/iommu/dma-iommu.c | 9 ++++++--- drivers/iommu/iommu.c | 5 ++--- include/linux/device.h | 9 ++++----- include/linux/iommu-dma.h | 3 ++- 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index 94d514169642..036994069b80 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -2112,18 +2112,21 @@ EXPORT_SYMBOL_GPL(dma_iova_destroy); =20 void iommu_setup_dma_ops(struct device *dev, struct iommu_domain *domain) { + bool dma_iommu; + if (dev_is_pci(dev)) dev->iommu->pci_32bit_workaround =3D !iommu_dma_forcedac; =20 - dev->dma_iommu =3D iommu_is_dma_domain(domain); - if (dev->dma_iommu && iommu_dma_init_domain(domain, dev)) + dma_iommu =3D iommu_is_dma_domain(domain); + dev_assign_dma_iommu(dev, dma_iommu); + if (dma_iommu && iommu_dma_init_domain(domain, dev)) goto out_err; =20 return; out_err: pr_warn("Failed to set up IOMMU for device %s; retaining platform DMA ops= \n", dev_name(dev)); - dev->dma_iommu =3D false; + dev_clear_dma_iommu(dev); } =20 static bool has_msi_cookie(const struct iommu_domain *domain) diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c index 50718ab810a4..8dc50a0eee85 100644 --- a/drivers/iommu/iommu.c +++ b/drivers/iommu/iommu.c @@ -589,9 +589,8 @@ static void iommu_deinit_device(struct device *dev) dev->iommu_group =3D NULL; module_put(ops->owner); dev_iommu_free(dev); -#ifdef CONFIG_IOMMU_DMA - dev->dma_iommu =3D false; -#endif + if (IS_ENABLED(CONFIG_IOMMU_DMA)) + dev_clear_dma_iommu(dev); } =20 static struct iommu_domain *pasid_array_entry_to_domain(void *entry) diff --git a/include/linux/device.h b/include/linux/device.h index 5e42261ba3aa..feb11ba1ba71 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -469,10 +469,13 @@ struct device_physical_location { * @DEV_FLAG_CAN_MATCH: The device has matched with a driver at least once= or it * is in a bus (like AMBA) which can't check for matching drivers * until other devices probe successfully. + * @DEV_FLAG_DMA_IOMMU: Device is using default IOMMU implementation for D= MA and + * doesn't rely on dma_ops structure. */ enum struct_device_flags { DEV_FLAG_READY_TO_PROBE =3D 0, DEV_FLAG_CAN_MATCH =3D 1, + DEV_FLAG_DMA_IOMMU =3D 2, =20 DEV_FLAG_COUNT }; @@ -567,8 +570,6 @@ enum struct_device_flags { * for dma allocations. This flag is managed by the dma ops * instance from ->dma_supported. * @dma_skip_sync: DMA sync operations can be skipped for coherent buffers. - * @dma_iommu: Device is using default IOMMU implementation for DMA and - * doesn't rely on dma_ops structure. * @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 @@ -688,9 +689,6 @@ struct device { #ifdef CONFIG_DMA_NEED_SYNC bool dma_skip_sync:1; #endif -#ifdef CONFIG_IOMMU_DMA - bool dma_iommu:1; -#endif =20 DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; @@ -719,6 +717,7 @@ static inline bool dev_test_and_set_##accessor_name(str= uct device *dev) \ =20 __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); =20 /** * struct device_link - Device link representation. diff --git a/include/linux/iommu-dma.h b/include/linux/iommu-dma.h index a92b3ff9b934..060f6e23ab3c 100644 --- a/include/linux/iommu-dma.h +++ b/include/linux/iommu-dma.h @@ -7,12 +7,13 @@ #ifndef _LINUX_IOMMU_DMA_H #define _LINUX_IOMMU_DMA_H =20 +#include #include =20 #ifdef CONFIG_IOMMU_DMA static inline bool use_dma_iommu(struct device *dev) { - return dev->dma_iommu; + return dev_dma_iommu(dev); } #else static inline bool use_dma_iommu(struct device *dev) --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dl1-f53.google.com (mail-dl1-f53.google.com [74.125.82.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 500F21531E8 for ; Sat, 4 Apr 2026 00:07:31 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261257; cv=none; b=UWd+QHnvaxJAXFkmAwUKAU6Aob7kKk9Vb7tBteixLBid0P5Z+cxEunj8VNtSjqnAmLsqhIx87XM2f9YR4Bbh67Hh0DgJh4BAlLtq+T47JDT0bojenEu2tpwtZkjq4yH59UrJlWCQLLD0JGhBnCa7noZ5HlhLk+/wW/zx/CtRLxQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261257; c=relaxed/simple; bh=KoRQwAoZXwBl8kOQW1MVyWt14NupWAYTSsNS21YFjro=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=L+F2yeL5P4xq1W7rD3PeFDYIkYtSi8tGulgC79Qx0P5COhdpei45GTmXWJdsLYmuN920+FI9SnOnOKeizwbfEfrCQ3OfC6vki1ShNAlh42QEsrQot37hsyKLxwu/QWVxQgYkU6Am0qiixa6l8y3LJ0UBej9GfNAZjMhCXnZyNC4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=izBU4lL2; arc=none smtp.client-ip=74.125.82.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="izBU4lL2" Received: by mail-dl1-f53.google.com with SMTP id a92af1059eb24-1279eced0b9so2748111c88.0 for ; Fri, 03 Apr 2026 17:07:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261250; x=1775866050; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=iaEmExAw4Fi7AHFQ4lJ7E/IDLxtvfEnb2vcxgfiheP4=; b=izBU4lL20viqbqn5vj3LCwlTCIGoWNKcNLw1415gFSqDZmqXehk14RgPW3wFyNs41h j91cwzLSq7qdgKIajs8SPhz9B6+L3Da0eofjQKbLAP4ExzxCnq+q7ICwxCaowcT7FBQn yzO7Jmmz5+dZDnlcYij6XcWWR1niytS4vQohw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261250; x=1775866050; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=iaEmExAw4Fi7AHFQ4lJ7E/IDLxtvfEnb2vcxgfiheP4=; b=l2qB1zNeozXQ+bMzHRH+Fc0y8NvZv3aDQq3+PJ5RwfI8RNDX6mdcytiIEWns+Ar938 PKpw91NGgXpAjDT9sZTIvyL5ajofTda7GDEBewL9iwZflLuXomsVVBjFGsbdXABHbhVP 3d5dgeo3ZKjq2byjDf+Wcy7ynSkIiOo4UzkF7WLMDsLUax2lOcBAmba85am3IkrxAHi3 VnWagBtJCpbecqTIkBeiUruT7pGQvrUdfGlHi6fNSpOynunLuKYVjkyai9YnqRm9sPgN 89DT1o0fTQDwW3OTJbABopcbMRApSjtNWuLVQviFCOivIZFX+UGm7qZVVLGxA6R+4BVl TCcA== X-Forwarded-Encrypted: i=1; AJvYcCVFpYheodUqEPwaK2X2iCgJThb9Vul3Dzet+OPjephvNtTUrfOZ4kFhDuzgTsyKnG0WAD0fsQDZw7Q0ZAM=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3C2+o4LZ2YuaZ9LUH/ARNZuPAFcNwdf/ox4CJ3bBVcF5dk8cK NBWmMuVrGmY9CXRPuDaCiICSewPYkNrB1rxp/ScgLgfagW/L85MmEcqR1CJdnbBEjA== X-Gm-Gg: AeBDievFE7zDwkjUU+n1RWtAeIG60mN2ZOdV3h8pai5FVTH3QYzSu62ErlKO6NrPARj TX0cbdnSP4j0jwvyruFTu1VUcUV7hsh3RzKtunnYDZUAc5fSpMWihdFDChj25TjeoYW6ptaogp1 37FGNvs5xSCwRi0UfjFdEPqbnlRGTJ8XFZ3p48IMn2o0Rjb+40m7ir+P9SbfItsF6qwamjMKhgc KnTyOAJAA8PAyRc+f3iI/8YaHHsYAoB7xiGwOasZznnD4N7P7F24sblD7Uns7HGy8JyddVMbQli m6X+Ewtgfocc/3aAVye0xEJk5rZ33Z9dvoP1Za63Buc7rMzZsLvRfjI5qm4An1bQoRp/pjcVFib yCRu/HdED1a6cdmvDhG51Oq2UY1cBSTIMwQRXUF3eJm/nSOYr8SuvqkTz9Wd9XHtG+Xa2T2+P7q 2AIWeHOEq3G5RpIYIgtDiktln+4EzL6W7HdmlYoHwtCyMryUTuHFaqUG37ehy6kHF0HsarrEJGm 5m2DWOZH7E= X-Received: by 2002:a05:7022:4a4:b0:128:d5bd:3572 with SMTP id a92af1059eb24-12bfb765439mr2140467c88.31.1775261250429; Fri, 03 Apr 2026 17:07:30 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:28 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , Andrew Morton , Jason Gunthorpe , driver-core@lists.linux.dev, iommu@lists.linux.dev, linux-kernel@vger.kernel.org, linux-mm@kvack.org, m.szyprowski@samsung.com Subject: [PATCH v4 4/9] driver core: Replace dev->dma_skip_sync with dev_dma_skip_sync() Date: Fri, 3 Apr 2026 17:04:58 -0700 Message-ID: <20260403170432.v4.4.Icf072aa4184dd86a88fa8ca195b09d1651984000@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In C, bitfields are not necessarily safe to modify from multiple threads without locking. Switch "dma_skip_sync" over to the "flags" field so modifications are safe. Cc: Alexander Lobakin Cc: Eric Dumazet Cc: Christoph Hellwig Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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). NOTE: even though previously we only took up a bit if CONFIG_DMA_NEED_SYNC, in this change I reserve the bit unconditionally. While we could get the "dynamic" behavior by changing the flags definition to be an "enum", it doesn't seem worth it at this point. Changes in v4: - Use accessor functions for flags Changes in v3: - New include/linux/device.h | 8 ++++---- include/linux/dma-map-ops.h | 4 ++-- include/linux/dma-mapping.h | 2 +- kernel/dma/mapping.c | 8 ++++---- mm/hmm.c | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/include/linux/device.h b/include/linux/device.h index feb11ba1ba71..fde0c72c3159 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -471,11 +471,14 @@ struct device_physical_location { * until other devices probe successfully. * @DEV_FLAG_DMA_IOMMU: Device is using default IOMMU implementation for D= MA and * doesn't rely on dma_ops structure. + * @DEV_FLAG_DMA_SKIP_SYNC: DMA sync operations can be skipped for coherent + * buffers. */ enum struct_device_flags { DEV_FLAG_READY_TO_PROBE =3D 0, DEV_FLAG_CAN_MATCH =3D 1, DEV_FLAG_DMA_IOMMU =3D 2, + DEV_FLAG_DMA_SKIP_SYNC =3D 3, =20 DEV_FLAG_COUNT }; @@ -569,7 +572,6 @@ enum struct_device_flags { * 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. - * @dma_skip_sync: DMA sync operations can be skipped for coherent buffers. * @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 @@ -686,9 +688,6 @@ struct device { #ifdef CONFIG_DMA_OPS_BYPASS bool dma_ops_bypass : 1; #endif -#ifdef CONFIG_DMA_NEED_SYNC - bool dma_skip_sync:1; -#endif =20 DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; @@ -718,6 +717,7 @@ static inline bool dev_test_and_set_##accessor_name(str= uct device *dev) \ __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); =20 /** * struct device_link - Device link representation. diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index 60b63756df82..edd7de60a957 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -245,8 +245,8 @@ static inline void dma_reset_need_sync(struct device *d= ev) { #ifdef CONFIG_DMA_NEED_SYNC /* Reset it only once so that the function can be called on hotpath */ - if (unlikely(dev->dma_skip_sync)) - dev->dma_skip_sync =3D false; + if (unlikely(dev_dma_skip_sync(dev))) + dev_clear_dma_skip_sync(dev); #endif } =20 diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h index 99ef042ecdb4..ef4feb2b37d8 100644 --- a/include/linux/dma-mapping.h +++ b/include/linux/dma-mapping.h @@ -419,7 +419,7 @@ bool __dma_need_sync(struct device *dev, dma_addr_t dma= _addr); static inline bool dma_dev_need_sync(const struct device *dev) { /* Always call DMA sync operations when debugging is enabled */ - return !dev->dma_skip_sync || IS_ENABLED(CONFIG_DMA_API_DEBUG); + return !dev_dma_skip_sync(dev) || IS_ENABLED(CONFIG_DMA_API_DEBUG); } =20 static inline void dma_sync_single_for_cpu(struct device *dev, dma_addr_t = addr, diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index 6d3dd0bd3a88..76fc65d1a8a4 100644 --- a/kernel/dma/mapping.c +++ b/kernel/dma/mapping.c @@ -467,7 +467,7 @@ bool dma_need_unmap(struct device *dev) { if (!dma_map_direct(dev, get_dma_ops(dev))) return true; - if (!dev->dma_skip_sync) + if (!dev_dma_skip_sync(dev)) return true; return IS_ENABLED(CONFIG_DMA_API_DEBUG); } @@ -483,16 +483,16 @@ static void dma_setup_need_sync(struct device *dev) * mapping, if any. During the device initialization, it's * enough to check only for the DMA coherence. */ - dev->dma_skip_sync =3D dev_is_dma_coherent(dev); + dev_assign_dma_skip_sync(dev, dev_is_dma_coherent(dev)); else if (!ops->sync_single_for_device && !ops->sync_single_for_cpu && !ops->sync_sg_for_device && !ops->sync_sg_for_cpu) /* * Synchronization is not possible when none of DMA sync ops * is set. */ - dev->dma_skip_sync =3D true; + dev_set_dma_skip_sync(dev); else - dev->dma_skip_sync =3D false; + dev_clear_dma_skip_sync(dev); } #else /* !CONFIG_DMA_NEED_SYNC */ static inline void dma_setup_need_sync(struct device *dev) { } diff --git a/mm/hmm.c b/mm/hmm.c index 5955f2f0c83d..c72c9ddfdb2f 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -709,7 +709,7 @@ int hmm_dma_map_alloc(struct device *dev, struct hmm_dm= a_map *map, * best approximation to ensure no swiotlb buffering happens. */ #ifdef CONFIG_DMA_NEED_SYNC - dma_need_sync =3D !dev->dma_skip_sync; + dma_need_sync =3D !dev_dma_skip_sync(dev); #endif /* CONFIG_DMA_NEED_SYNC */ if (dma_need_sync || dma_addressing_limited(dev)) return -EOPNOTSUPP; --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dy1-f173.google.com (mail-dy1-f173.google.com [74.125.82.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75D8D27713 for ; Sat, 4 Apr 2026 00:07:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261259; cv=none; b=LGRv7qlRm/gSuu/as5bGYNTmio65VvSlfGpYMm0oUsZve4jFi8jwE79U1v2udX8jxZ+DVnbDYXm8jiEa5m/pqcB7vUfJkaEWk1EaaJmAPNzdE32hI2ziiQwe7jo5cYWT6AOWIKfz+hOIFfIoKn7YUOiDZTA+6n6NTGWADHBP9O8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261259; c=relaxed/simple; bh=WYnONCXDXDti47RwGt2EPBGJDVoWzZZNYS486IRVgHI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=MFy/E3StGBqap0sf/s0qyhmunycCbRV9PcYEeUtCr1cBHAQVE2Ld7L2fm+Buz8GqNwpzZK1PCIpndmGUtB/EykLMlrLi6Geq45JlGbaP1mCwPydrAI3LPCwDZ/UTUCnPT1FyvlHFm63cP3WqjnqDO/dOgQO5bLyfGVjIqJPUABY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=PE6gC3GE; arc=none smtp.client-ip=74.125.82.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="PE6gC3GE" Received: by mail-dy1-f173.google.com with SMTP id 5a478bee46e88-2bdd40d3c61so2027971eec.1 for ; Fri, 03 Apr 2026 17:07:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261254; x=1775866054; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Bet9w8b/blm24LZki1Y+b44Iyovbn2Yvd3IPo+HAgFA=; b=PE6gC3GEwDFP0E5ps1y4aH4fSDL2CHTBBpEn/oICisZJiLc92T7b5BYcNhMahQBVN9 iLPwP3LmQv9zjW5cJ3JEKOut4Mw4TV9HfXsgST8ZHHhXgE+1BqTo5VbmMIVGdUeYWoKy VSpeU7aPu1UScxt3beYEJCSJ2OkxS05Ye/CDE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261254; x=1775866054; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=Bet9w8b/blm24LZki1Y+b44Iyovbn2Yvd3IPo+HAgFA=; b=VApZq9TS5mZQlWfsjYazszdxNw2r80yGzelKf8oVmZVl+CVuHGTtba+34uFl4SGkRL 2BW7sDeKMxw7JpvUq3y6H9EOrAiD3LE1bcvtz40+pdhTjw3kNcplbMpMLAVUMK4uga/A U4lQlDGgqxPhM8MVw4l2udS2Z1239hipb7qjntfKfpldopVTgCndoHtOwZzrDfCGWWSC UaPOOi+fMK9NVdvcU1PpCyvKzi82eh9LLMyBy1o7l7pLpYf+umcZ8r97zpFCrcT87F+M /O/2nmykeud9CMm51IWvKIaFikXo8Xox9pzRjtBsMEGnJZlwWzdBzfauVQlsPBxVMxQr cxJA== X-Forwarded-Encrypted: i=1; AJvYcCVXsaHZYhOt5q6xJd/ro2qQUlyNF9eu6B4l8m+LE2+pvnJ/xLyAdVwvQGC9scxL5k66tGnLS5bCt/Ay0Ls=@vger.kernel.org X-Gm-Message-State: AOJu0YzC54fAFksOnjxl6Iau2SYrgUYki2738sC9sW80M09sOKST9JbZ Uy3O/N9bft7HRly8pP0HFKSpY7+Eteho+xVWF3dwalkMTaVUtqZeumS1fjndBz/vbw== X-Gm-Gg: AeBDievy5V1PjEU18H9ZwYO6M9Tazwnb8Ul0sFDGnujwV0ZruOlwzZ1S/UF+M4mk8O/ U4hAvAJTu/BoQa65CYCITicIcy8W9XRYrbbB/jsM6lRZcZ7yHbpIDG4CNW2DrdI86SqevqKKC1b rvSwjGQGXvF/cMDohQqK3j2xFyLQ5FLsa6wlI41n5H99qARBIeIQkj/+JQGvR6Gj0sb7J06qJKW 9p6g5tzVsYOK3+zNxKda/Le+mQw4Il5L9foGqhbLR0A0DQ9xWqpXuAMofboxRMywwJNhoQTGs3v kcghan29sou68KHGqhlFO0Ju/gLe/ia2WBZ56ZvOHK6TkGw2X6J0gtxF4dBZVYFjZ2a6KLPBJXX nqhsmTQqUegynPoYwZo6LYIo2ov7nLVuj0bGI9/TD/rFvactRiwgIYPT3U6kRBCA9juohYBwkFT OmoDlxlvEkX0U7amcSJBNrUOUaAuPm2KJj7r+ciAeLPef8+yFtNLRqgloMb9qFDLW86NdEyhUDm 52mPaoQEh5xF1jy4jbOkQ== X-Received: by 2002:a05:7300:d05:b0:2be:10a6:647e with SMTP id 5a478bee46e88-2cbfc16e113mr2496039eec.19.1775261253576; Fri, 03 Apr 2026 17:07:33 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:31 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , chleroy@kernel.org, driver-core@lists.linux.dev, gbatra@linux.ibm.com, iommu@lists.linux.dev, jgg@ziepe.ca, linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, m.szyprowski@samsung.com, maddy@linux.ibm.com, mpe@ellerman.id.au, npiggin@gmail.com Subject: [PATCH v4 5/9] driver core: Replace dev->dma_ops_bypass with dev_dma_ops_bypass() Date: Fri, 3 Apr 2026 17:04:59 -0700 Message-ID: <20260403170432.v4.5.If62b84471ef2c85e7ad250f0468867d6dba965ab@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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). NOTE: even though previously we only took up a bit if CONFIG_DMA_OPS_BYPASS, in this change I reserve the bit unconditionally. While we could get the "dynamic" behavior by changing the flags definition to be an "enum", it doesn't seem worth it at this point. This also allows us to move one "#ifdef" to an "if", getting better compile-time testing of both sides of the "if". Changes in v4: - Use accessor functions for flags Changes in v3: - New arch/powerpc/kernel/dma-iommu.c | 8 ++++---- include/linux/device.h | 15 +++++++-------- 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-iomm= u.c index 73e10bd4d56d..6d1899b38c3d 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) + if (dev_dma_ops_bypass(dev)) return true; =20 return false; @@ -75,7 +75,7 @@ bool arch_dma_alloc_direct(struct device *dev) =20 bool arch_dma_free_direct(struct device *dev, dma_addr_t dma_handle) { - if (!dev->dma_ops_bypass) + if (!dev_dma_ops_bypass(dev)) return false; =20 return is_direct_handle(dev, dma_handle); @@ -164,7 +164,7 @@ int dma_iommu_dma_supported(struct device *dev, u64 mas= k) * 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 =3D 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 mas= k) } =20 dev_dbg(dev, "iommu: not 64-bit, using default ops\n"); - dev->dma_ops_bypass =3D false; + dev_clear_dma_ops_bypass(dev); return 1; } =20 diff --git a/include/linux/device.h b/include/linux/device.h index fde0c72c3159..2ce89e3cfab9 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -473,12 +473,18 @@ 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. */ enum struct_device_flags { DEV_FLAG_READY_TO_PROBE =3D 0, DEV_FLAG_CAN_MATCH =3D 1, DEV_FLAG_DMA_IOMMU =3D 2, DEV_FLAG_DMA_SKIP_SYNC =3D 3, + DEV_FLAG_DMA_OPS_BYPASS =3D 4, =20 DEV_FLAG_COUNT }; @@ -567,11 +573,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 @@ -685,9 +686,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 =20 DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; @@ -718,6 +716,7 @@ __create_dev_flag_accessors(ready_to_probe, DEV_FLAG_RE= ADY_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); =20 /** * struct device_link - Device link representation. diff --git a/kernel/dma/mapping.c b/kernel/dma/mapping.c index 76fc65d1a8a4..30bf8455730a 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; =20 -#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) >=3D dma_direct_get_required_mask(dev); -#endif return false; } =20 --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dy1-f171.google.com (mail-dy1-f171.google.com [74.125.82.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6462A35893 for ; Sat, 4 Apr 2026 00:07:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261260; cv=none; b=szTdbmLNebM/gmL6QPSAVwiJ+k34N31r0U0Nn8+CQIt/4C4jkfkq3uzFzNBcWJ12FpVZF51po6VoQ/t6S1gxQviVCr2MzgRfKG21/GZDlL0tEQYMcGRwU3ly/zom8oqlQnzy7MyUzCNvbGtzpLCCz9BQwFY5+qNJZRkG8DD6LUU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261260; c=relaxed/simple; bh=TgyyhRKZN/WoCmiVaktIxTAO95/iAlKYAoCl7YuTmec=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=SWRS/MD2QGo9v96k1vlwn2VeTdX/5jm9Z2+Y540ddUaVK+xtOOQoMtVmi4L0/mlRL8pF4jskw8WtI6VirB+Mw851zZE9bjluMsXlbbV0k2YZcm1lUBjj9wlRyqXuoETDO2FBBLu9+U4CSKE9M/FMGqleRTgqKwCAYNytKakyVXY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=Baz6KrFB; arc=none smtp.client-ip=74.125.82.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="Baz6KrFB" Received: by mail-dy1-f171.google.com with SMTP id 5a478bee46e88-2c4db6bca03so1216196eec.1 for ; Fri, 03 Apr 2026 17:07:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261256; x=1775866056; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=SRammz33zgALoDB0EK8vTnIXAeS5Kg+fXRfCOEnRqe0=; b=Baz6KrFBwpKCE6FNYRtQLl+tUiUQgU1Chm9/iaa6/9TgQeCHNlUk0jlau0okN83PfE Rw/uDBbFXkyepKo1kShbTx4PHq68NZhklDS6iE/XcP67hHbsGDxmZ0faxNkFjPT6sQ4P j9iUEwSAysP+Z42ht8NdE6sX/1N26h+kd22G8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261256; x=1775866056; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=SRammz33zgALoDB0EK8vTnIXAeS5Kg+fXRfCOEnRqe0=; b=J1Orr3GUmd5ZureYyB4uQLUP+TPzc5MvDwC7Hw8SiKxAnPINXh/TyS+wWAjXklIkWb HRB1+Q+prAKJkFwV59dRQd4D5RQvoePfV0hJotpLTaKb8T125dynZewp+565UfSq4DuC 3EDQbOjF48H0kol7dBK7AXwCZ/UPt1YsNc7e1WUxcbmBBnE+mGlgCXYC4SnZnamf+bYK VHLABqXiRKoGdX+7+/YQdvVaE9XCEOfMTqOsw/rWNh+ylIuB/37N4JhJHG4rjWiqyLxB B/eP9G1spONfi5oFxk6WMiFJVSKSTeOHaKq+IYv1TIe5Hw5J9CzRcdOghrdBEYFFa0Pa JJ1g== X-Forwarded-Encrypted: i=1; AJvYcCVSOuFDkik+eKEZKlbjjFk8Eou1uava4QSOzCPIpihZctJSlolHySIsuZx0OifItpIJ4fpZg1P/EsPxltw=@vger.kernel.org X-Gm-Message-State: AOJu0YxDDX2Wv77T1rvtRoW4zrbOAZ/KFoRwrg/IzmrcOsAaTchiwInC Miw/hXfQFv5J3dlpgxOAwb1w6iZoP0X2YQ9ULkrvZvPNjCg8CAKv49HWq/SlGoDLFw== X-Gm-Gg: AeBDietADVrdr1oWUcYfU9ZnPaZ4VScpfOyQVFTprBwy7H3kVBLiW9OfBaHz8vgiU4M WpVazZQ2wDLjc4LdaAs56CDIUYm9NicobPMjhVAwVp519Vo4F0PtpZ9WjUQWlQF+FInkpYI2aSI n2jKsBiJn5vthPlKw3dNQFTaImTnuxl6BRoFUtY1LFAh8jvIJhP3lPJDmHPhetAeiuiNDtQ/JPI yuKuwQM6xRqFzSisRwmobAgqEU9bqxziQKqi9flAh1jeEeyrBnBN+FLgHdu/9dmC33qyHDgHbrZ aRMy+unI++yOptij85YKXHs1NFNoiclI0c0b6RmbC9xILqGjV6Me0W5kW18vKZGEpeLHugYOOkb juH4Y5TFcPclVNZfFfruSJdvLI2GfJ1Y/mi2YEm8fQTSOoGARv1LrXyrLYiT8KM2+jPvBZ/I7on XsOubSFAnHTeiDbAzY5GdSa2BzSRRfRDXfbaaScqrDjWgjIAFGAme1qQkZA8apuBj8mHw1S/xj+ Im2/m8Fw7s= X-Received: by 2002:a05:7300:fd05:b0:2c1:67e1:61a9 with SMTP id 5a478bee46e88-2cbfba8de38mr2116743eec.13.1775261256542; Fri, 03 Apr 2026 17:07:36 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:34 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v4 6/9] driver core: Replace dev->state_synced with dev_state_synced() Date: Fri, 3 Apr 2026 17:05:00 -0700 Message-ID: <20260403170432.v4.6.Idb4818e1159fef104c7756bfd6e7ba8f374bebcd@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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 v4: - Use accessor functions for flags Changes in v3: - New drivers/base/core.c | 8 ++++---- drivers/base/dd.c | 8 +++----- include/linux/device.h | 9 +++++---- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 8acf7f684417..0986051a6f14 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1123,7 +1123,7 @@ static void __device_links_queue_sync_state(struct de= vice *dev, =20 if (!dev_has_sync_state(dev)) return; - if (dev->state_synced) + if (dev_state_synced(dev)) return; =20 list_for_each_entry(link, &dev->links.consumers, s_node) { @@ -1138,7 +1138,7 @@ static void __device_links_queue_sync_state(struct de= vice *dev, * than once. This can happen if new consumers get added to the device * and probed before the list is flushed. */ - dev->state_synced =3D true; + dev_set_state_synced(dev); =20 if (WARN_ON(!list_empty(&dev->links.defer_sync))) return; @@ -1779,7 +1779,7 @@ static int fw_devlink_dev_sync_state(struct device *d= ev, void *data) struct device *sup =3D link->supplier; =20 if (!device_link_test(link, DL_FLAG_MANAGED) || - link->status =3D=3D DL_STATE_ACTIVE || sup->state_synced || + link->status =3D=3D DL_STATE_ACTIVE || dev_state_synced(sup) || !dev_has_sync_state(sup)) return 0; =20 @@ -1793,7 +1793,7 @@ static int fw_devlink_dev_sync_state(struct device *d= ev, void *data) return 0; =20 dev_warn(sup, "Timed out. Forcing sync_state()\n"); - sup->state_synced =3D true; + dev_set_state_synced(sup); get_device(sup); list_add_tail(&sup->links.defer_sync, data); =20 diff --git a/drivers/base/dd.c b/drivers/base/dd.c index c7c0851ae073..e1132690652f 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; =20 device_lock(dev); - if (!dev->state_synced) { - dev->state_synced =3D true; + if (!dev_test_and_set_state_synced(dev)) dev_sync_state(dev); - } else { + else ret =3D -EINVAL; - } device_unlock(dev); =20 return ret ? ret : count; @@ -598,7 +596,7 @@ static ssize_t state_synced_show(struct device *dev, bool val; =20 device_lock(dev); - val =3D dev->state_synced; + val =3D dev_state_synced(dev); device_unlock(dev); =20 return sysfs_emit(buf, "%u\n", val); diff --git a/include/linux/device.h b/include/linux/device.h index 2ce89e3cfab9..a1d59ff9702c 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -478,6 +478,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 sync= ed 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 =3D 0, @@ -485,6 +488,7 @@ enum struct_device_flags { DEV_FLAG_DMA_IOMMU =3D 2, DEV_FLAG_DMA_SKIP_SYNC =3D 3, DEV_FLAG_DMA_OPS_BYPASS =3D 4, + DEV_FLAG_STATE_SYNCED =3D 5, =20 DEV_FLAG_COUNT }; @@ -568,9 +572,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 mat= ch - * 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. @@ -680,7 +681,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) @@ -717,6 +717,7 @@ __create_dev_flag_accessors(can_match, DEV_FLAG_CAN_MAT= CH); __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); +__create_dev_flag_accessors(state_synced, DEV_FLAG_STATE_SYNCED); =20 /** * struct device_link - Device link representation. --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dl1-f52.google.com (mail-dl1-f52.google.com [74.125.82.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9ED16DDC3 for ; Sat, 4 Apr 2026 00:07:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261262; cv=none; b=ShpcSWytGynrMUXMSQzb2fKg517l53Bib5G3II0PRvU9riHrAz6dXh0Wb+N9ACvFl7/6FxL/ajzpki9G1BHO0ZsRjsJBw2Esi5CmIN7V6NsMJQF8RNPyuZfCE6LafFSBgiuIY6tU/T/tgc7DFpS6u9ccpZK9w0/+bezXVmbvfP0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261262; c=relaxed/simple; bh=pgtEOoXk5qYTTG7hDMtZ8J76x8eZHoBKGHYOR2BacFI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tEc4RoxY1dRu+fEMFBvEb5iS2zOdyb4bwMqOqGRL3Cvoq2Lb0fpZFuMUI9O8yWGmh3R1qjkjeo5+QoE32mEqrvfPatMX6lzBoA5M0ECYBAW5DlM95CrCnkrlYQqosOthfqjPRIzzcnhdSiwb9wmd5FDDtaW0Y1goFXgTlGzbeCo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=ev3xjZ5P; arc=none smtp.client-ip=74.125.82.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="ev3xjZ5P" Received: by mail-dl1-f52.google.com with SMTP id a92af1059eb24-12c0433a4b9so10108c88.1 for ; Fri, 03 Apr 2026 17:07:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261260; x=1775866060; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pcmabhgoUijh3Cpj42DFAN00fMUT4ppReLQYE5Q7FAg=; b=ev3xjZ5PnP16m9+POxKLwsiGjTfabEEGhUywjzqdTGG3gvymLWPpCpCl/eyLp7OI3W 5lqdyiajsK9XLX5OP0Z4eq/YyJBsgy2nxLDkQP3veXH/7+Wmc2txbwQXD1JRmnYDK/wB swTAL0zYReTHO83wHsekBADUJVydSWaNa2DTE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261260; x=1775866060; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=pcmabhgoUijh3Cpj42DFAN00fMUT4ppReLQYE5Q7FAg=; b=kyNJsKD9H7t06NMT94TnhGBDBbdWXRdoVdpu4u4cB8CNFJGs75zgeUZgcpePecUhms EC5NtOpd3cAF7RDeSLeD0jyC7sEVEq38aywq9n35H8Dssw3Qc6AToByZj76j7beyzUIN gyrQ3n9IamkHppp7EV4zfaWvUPPNC7u0u3oES9ij6pAf/imnsN0HZU0wOmc6r0ykwIoP rkd61ae0ndXELYKb6GE3gaEs5oZpSy64/mYUneMpy0yUqqRwBJ4SPv/SRnd3Ays6weeK pj+093RiS4pTKoqpTtVGhHruPLF8vIhsi+xIXKFWuAmnoOIBvWh+5lTm8acTFBXsN+8B 40Vw== X-Forwarded-Encrypted: i=1; AJvYcCUxalfWBvb/6DZD0ptJDgFdTJlLh2IvmtwT6Yh2/6pO5//1X5zJKagHYKOrP+GTnf1zj2B+FrJNqbcX1n0=@vger.kernel.org X-Gm-Message-State: AOJu0YzEErncXHRrFehznZrkzl0X2RjboJtK/RLnCZcap168B+ii/EJY bpjBfb4unuzHzSYXJvh6CzThhIe73eZ0jYEWMRAJnbX+nWEaLeGutPbjXm1zEeKK6A== X-Gm-Gg: ATEYQzx4uAHc5qt51bLuDps7JUy1T6a/yit6F07wHddCx/INv7iWMFFAewTs0uXLxcT 6OjxwUNEb0hbQLBTqxsUmd/mUHQ+BKxmfWwSnjSevypMFSMoKyALxPtgh8iFnRSXhopQ1IzPrHz ZorJyHxrsaZw+mop16eAHDK49/jZhkNq0t/ll3ZyGEjQvmcVMssPI/ZwrdVmb9vACFj4klzkcj4 H5qIy2S+yMKej6nx1Ou2Gu173NzvZEZwR0eg7J97YutkcMw0VW80Q2S3uQw2mbgX2A+inWwHWXa seB3HeujEB/YfSjniNu6+uf9X2qciIdzgA1/g1vJWO4Y8Vw6qP94fYpx0rwJNoaOSJ1MRCkwtib bCA8rwfmQARD825sC7/orMnF5RR9EFPW1slg0Dk72aX9QDacpg+m0vqICMgArGhISCRxwowJFta kEZsBLCHY5TLPCHIQjkNu7YWOKdf22DIhNMGYMvEw5B2KjGRInPSw86iOVmiwYGswcQ6eaQuGUv P0OEL0Zrlo= X-Received: by 2002:a05:7022:ec17:b0:123:3488:899f with SMTP id a92af1059eb24-12bfb776e08mr1990633c88.32.1775261259525; Fri, 03 Apr 2026 17:07:39 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:38 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , Frank.Li@kernel.org, alex@ghiti.fr, andre.przywara@arm.com, andrew@lunn.ch, aou@eecs.berkeley.edu, catalin.marinas@arm.com, dmaengine@vger.kernel.org, driver-core@lists.linux.dev, gregory.clement@bootlin.com, iommu@lists.linux.dev, jgg@ziepe.ca, kees@kernel.org, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-mips@vger.kernel.org, linux-riscv@lists.infradead.org, linux-snps-arc@lists.infradead.org, linux@armlinux.org.uk, m.szyprowski@samsung.com, palmer@dabbelt.com, peter.ujfalusi@gmail.com, pjw@kernel.org, sebastian.hesselbarth@gmail.com, tsbogend@alpha.franken.de, vgupta@kernel.org, vkoul@kernel.org, will@kernel.org, willy@infradead.org Subject: [PATCH v4 7/9] driver core: Replace dev->dma_coherent with dev_dma_coherent() Date: Fri, 3 Apr 2026 17:05:01 -0700 Message-ID: <20260403170432.v4.7.If839f6dde98979fce177f70c6c74689a1904ee76@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In C, bitfields are not necessarily safe to modify from multiple threads without locking. Switch "dma_coherent" over to the "flags" field so modifications are safe. Cc: Christoph Hellwig Signed-off-by: Douglas Anderson Acked-by: Vinod Koul Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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). NOTE: even though previously we only took up a bit if CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE, CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU, or CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL, in this change I reserve the bit unconditionally. While we could get the "dynamic" behavior by changing the flags definition to be an "enum", it doesn't seem worth it at this point. Changes in v4: - Use accessor functions for flags Changes in v3: - New arch/arc/mm/dma.c | 4 ++-- arch/arm/mach-highbank/highbank.c | 2 +- arch/arm/mach-mvebu/coherency.c | 2 +- arch/arm/mm/dma-mapping-nommu.c | 4 ++-- arch/arm/mm/dma-mapping.c | 28 ++++++++++++++-------------- arch/arm64/mm/dma-mapping.c | 2 +- arch/mips/mm/dma-noncoherent.c | 2 +- arch/riscv/mm/dma-noncoherent.c | 2 +- drivers/base/core.c | 2 +- drivers/dma/ti/k3-udma-glue.c | 6 +++--- drivers/dma/ti/k3-udma.c | 6 +++--- include/linux/device.h | 11 ++++------- include/linux/dma-map-ops.h | 2 +- 13 files changed, 35 insertions(+), 38 deletions(-) diff --git a/arch/arc/mm/dma.c b/arch/arc/mm/dma.c index 6b85e94f3275..9b9adb02b4c5 100644 --- a/arch/arc/mm/dma.c +++ b/arch/arc/mm/dma.c @@ -98,8 +98,8 @@ void arch_setup_dma_ops(struct device *dev, bool coherent) * DMA buffers. */ if (is_isa_arcv2() && ioc_enable && coherent) - dev->dma_coherent =3D true; + dev_set_dma_coherent(dev); =20 dev_info(dev, "use %scoherent DMA ops\n", - dev->dma_coherent ? "" : "non"); + dev_dma_coherent(dev) ? "" : "non"); } diff --git a/arch/arm/mach-highbank/highbank.c b/arch/arm/mach-highbank/hig= hbank.c index 47335c7dadf8..8b7d0929dac4 100644 --- a/arch/arm/mach-highbank/highbank.c +++ b/arch/arm/mach-highbank/highbank.c @@ -98,7 +98,7 @@ static int highbank_platform_notifier(struct notifier_blo= ck *nb, if (of_property_read_bool(dev->of_node, "dma-coherent")) { val =3D readl(sregs_base + reg); writel(val | 0xff01, sregs_base + reg); - dev->dma_coherent =3D true; + dev_set_dma_coherent(dev); } =20 return NOTIFY_OK; diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherenc= y.c index fa2c1e1aeb96..7234d487ff39 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -95,7 +95,7 @@ static int mvebu_hwcc_notifier(struct notifier_block *nb, =20 if (event !=3D BUS_NOTIFY_ADD_DEVICE) return NOTIFY_DONE; - dev->dma_coherent =3D true; + dev_set_dma_coherent(dev); =20 return NOTIFY_OK; } diff --git a/arch/arm/mm/dma-mapping-nommu.c b/arch/arm/mm/dma-mapping-nomm= u.c index fecac107fd0d..c6a70686507b 100644 --- a/arch/arm/mm/dma-mapping-nommu.c +++ b/arch/arm/mm/dma-mapping-nommu.c @@ -42,11 +42,11 @@ void arch_setup_dma_ops(struct device *dev, bool cohere= nt) * enough to check if MPU is in use or not since in absence of * MPU system memory map is used. */ - dev->dma_coherent =3D cacheid ? coherent : true; + dev_assign_dma_coherent(dev, cacheid ? coherent : true); } else { /* * Assume coherent DMA in case MMU/MPU has not been set up. */ - dev->dma_coherent =3D (get_cr() & CR_M) ? coherent : true; + dev_assign_dma_coherent(dev, (get_cr() & CR_M) ? coherent : true); } } diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index f304037d1c34..f9bc53b60f99 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c @@ -1076,7 +1076,7 @@ static void *arm_iommu_alloc_attrs(struct device *dev= , size_t size, pgprot_t prot =3D __get_dma_pgprot(attrs, PAGE_KERNEL); struct page **pages; void *addr =3D NULL; - int coherent_flag =3D dev->dma_coherent ? COHERENT : NORMAL; + int coherent_flag =3D dev_dma_coherent(dev) ? COHERENT : NORMAL; =20 *handle =3D DMA_MAPPING_ERROR; size =3D PAGE_ALIGN(size); @@ -1124,7 +1124,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, s= truct vm_area_struct *vma, if (vma->vm_pgoff >=3D nr_pages) return -ENXIO; =20 - if (!dev->dma_coherent) + if (!dev_dma_coherent(dev)) vma->vm_page_prot =3D __get_dma_pgprot(attrs, vma->vm_page_prot); =20 err =3D vm_map_pages(vma, pages, nr_pages); @@ -1141,7 +1141,7 @@ static int arm_iommu_mmap_attrs(struct device *dev, s= truct vm_area_struct *vma, static void arm_iommu_free_attrs(struct device *dev, size_t size, void *cp= u_addr, dma_addr_t handle, unsigned long attrs) { - int coherent_flag =3D dev->dma_coherent ? COHERENT : NORMAL; + int coherent_flag =3D dev_dma_coherent(dev) ? COHERENT : NORMAL; struct page **pages; size =3D PAGE_ALIGN(size); =20 @@ -1202,7 +1202,7 @@ static int __map_sg_chunk(struct device *dev, struct = scatterlist *sg, phys_addr_t phys =3D page_to_phys(sg_page(s)); unsigned int len =3D PAGE_ALIGN(s->offset + s->length); =20 - if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + if (!dev_dma_coherent(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) arch_sync_dma_for_device(sg_phys(s), s->length, dir); =20 prot =3D __dma_info_to_prot(dir, attrs); @@ -1304,7 +1304,7 @@ static void arm_iommu_unmap_sg(struct device *dev, if (sg_dma_len(s)) __iommu_remove_mapping(dev, sg_dma_address(s), sg_dma_len(s)); - if (!dev->dma_coherent && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) + if (!dev_dma_coherent(dev) && !(attrs & DMA_ATTR_SKIP_CPU_SYNC)) arch_sync_dma_for_cpu(sg_phys(s), s->length, dir); } } @@ -1323,7 +1323,7 @@ static void arm_iommu_sync_sg_for_cpu(struct device *= dev, struct scatterlist *s; int i; =20 - if (dev->dma_coherent) + if (dev_dma_coherent(dev)) return; =20 for_each_sg(sg, s, nents, i) @@ -1345,7 +1345,7 @@ static void arm_iommu_sync_sg_for_device(struct devic= e *dev, struct scatterlist *s; int i; =20 - if (dev->dma_coherent) + if (dev_dma_coherent(dev)) return; =20 for_each_sg(sg, s, nents, i) @@ -1371,7 +1371,7 @@ static dma_addr_t arm_iommu_map_phys(struct device *d= ev, phys_addr_t phys, dma_addr_t dma_addr; int ret, prot; =20 - if (!dev->dma_coherent && + if (!dev_dma_coherent(dev) && !(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) arch_sync_dma_for_device(phys, size, dir); =20 @@ -1412,7 +1412,7 @@ static void arm_iommu_unmap_phys(struct device *dev, = dma_addr_t handle, if (!iova) return; =20 - if (!dev->dma_coherent && + if (!dev_dma_coherent(dev) && !(attrs & (DMA_ATTR_SKIP_CPU_SYNC | DMA_ATTR_MMIO))) { phys_addr_t phys =3D iommu_iova_to_phys(mapping->domain, iova); =20 @@ -1431,7 +1431,7 @@ static void arm_iommu_sync_single_for_cpu(struct devi= ce *dev, unsigned int offset =3D handle & ~PAGE_MASK; phys_addr_t phys; =20 - if (dev->dma_coherent || !iova) + if (dev_dma_coherent(dev) || !iova) return; =20 phys =3D iommu_iova_to_phys(mapping->domain, iova); @@ -1446,7 +1446,7 @@ static void arm_iommu_sync_single_for_device(struct d= evice *dev, unsigned int offset =3D handle & ~PAGE_MASK; phys_addr_t phys; =20 - if (dev->dma_coherent || !iova) + if (dev_dma_coherent(dev) || !iova) return; =20 phys =3D iommu_iova_to_phys(mapping->domain, iova); @@ -1701,13 +1701,13 @@ static void arm_teardown_iommu_dma_ops(struct devic= e *dev) { } void arch_setup_dma_ops(struct device *dev, bool coherent) { /* - * Due to legacy code that sets the ->dma_coherent flag from a bus - * notifier we can't just assign coherent to the ->dma_coherent flag + * Due to legacy code that sets the dma_coherent flag from a bus + * notifier we can't just assign coherent to the dma_coherent flag * here, but instead have to make sure we only set but never clear it * for now. */ if (coherent) - dev->dma_coherent =3D true; + dev_set_dma_coherent(dev); =20 /* * Don't override the dma_ops if they have already been set. Ideally diff --git a/arch/arm64/mm/dma-mapping.c b/arch/arm64/mm/dma-mapping.c index b2b5792b2caa..dc1fce939451 100644 --- a/arch/arm64/mm/dma-mapping.c +++ b/arch/arm64/mm/dma-mapping.c @@ -48,7 +48,7 @@ void arch_setup_dma_ops(struct device *dev, bool coherent) dev_driver_string(dev), dev_name(dev), ARCH_DMA_MINALIGN, cls); =20 - dev->dma_coherent =3D coherent; + dev_assign_dma_coherent(dev, coherent); =20 xen_setup_dma_ops(dev); } diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index ab4f2a75a7d0..30ef3e247eb7 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -139,6 +139,6 @@ void arch_sync_dma_for_cpu(phys_addr_t paddr, size_t si= ze, #ifdef CONFIG_ARCH_HAS_SETUP_DMA_OPS void arch_setup_dma_ops(struct device *dev, bool coherent) { - dev->dma_coherent =3D coherent; + dev_assign_dma_coherent(dev, coherent); } #endif diff --git a/arch/riscv/mm/dma-noncoherent.c b/arch/riscv/mm/dma-noncoheren= t.c index cb89d7e0ba88..a1ec2d71d1c9 100644 --- a/arch/riscv/mm/dma-noncoherent.c +++ b/arch/riscv/mm/dma-noncoherent.c @@ -140,7 +140,7 @@ void arch_setup_dma_ops(struct device *dev, bool cohere= nt) "%s %s: device non-coherent but no non-coherent operations supported", dev_driver_string(dev), dev_name(dev)); =20 - dev->dma_coherent =3D coherent; + dev_assign_dma_coherent(dev, coherent); } =20 void riscv_noncoherent_supported(void) diff --git a/drivers/base/core.c b/drivers/base/core.c index 0986051a6f14..531f02a5469a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3173,7 +3173,7 @@ void device_initialize(struct device *dev) #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) - dev->dma_coherent =3D dma_default_coherent; + dev_assign_dma_coherent(dev, dma_default_coherent); #endif swiotlb_dev_init(dev); } diff --git a/drivers/dma/ti/k3-udma-glue.c b/drivers/dma/ti/k3-udma-glue.c index f87d244cc2d6..686dc140293e 100644 --- a/drivers/dma/ti/k3-udma-glue.c +++ b/drivers/dma/ti/k3-udma-glue.c @@ -312,7 +312,7 @@ k3_udma_glue_request_tx_chn_common(struct device *dev, =20 if (xudma_is_pktdma(tx_chn->common.udmax)) { /* prepare the channel device as coherent */ - tx_chn->common.chan_dev.dma_coherent =3D true; + dev_set_dma_coherent(&tx_chn->common.chan_dev); dma_coerce_mask_and_coherent(&tx_chn->common.chan_dev, DMA_BIT_MASK(48)); } @@ -1003,7 +1003,7 @@ k3_udma_glue_request_rx_chn_priv(struct device *dev, = const char *name, =20 if (xudma_is_pktdma(rx_chn->common.udmax)) { /* prepare the channel device as coherent */ - rx_chn->common.chan_dev.dma_coherent =3D true; + dev_set_dma_coherent(&rx_chn->common.chan_dev); dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev, DMA_BIT_MASK(48)); } @@ -1104,7 +1104,7 @@ k3_udma_glue_request_remote_rx_chn_common(struct k3_u= dma_glue_rx_channel *rx_chn =20 if (xudma_is_pktdma(rx_chn->common.udmax)) { /* prepare the channel device as coherent */ - rx_chn->common.chan_dev.dma_coherent =3D true; + dev_set_dma_coherent(&rx_chn->common.chan_dev); dma_coerce_mask_and_coherent(&rx_chn->common.chan_dev, DMA_BIT_MASK(48)); rx_chn->single_fdq =3D false; diff --git a/drivers/dma/ti/k3-udma.c b/drivers/dma/ti/k3-udma.c index c964ebfcf3b6..1cf158eb7bdb 100644 --- a/drivers/dma/ti/k3-udma.c +++ b/drivers/dma/ti/k3-udma.c @@ -428,18 +428,18 @@ static void k3_configure_chan_coherency(struct dma_ch= an *chan, u32 asel) /* No special handling for the channel */ chan->dev->chan_dma_dev =3D false; =20 - chan_dev->dma_coherent =3D false; + dev_clear_dma_coherent(chan_dev); chan_dev->dma_parms =3D NULL; } else if (asel =3D=3D 14 || asel =3D=3D 15) { chan->dev->chan_dma_dev =3D true; =20 - chan_dev->dma_coherent =3D true; + dev_set_dma_coherent(chan_dev); dma_coerce_mask_and_coherent(chan_dev, DMA_BIT_MASK(48)); chan_dev->dma_parms =3D chan_dev->parent->dma_parms; } else { dev_warn(chan->device->dev, "Invalid ASEL value: %u\n", asel); =20 - chan_dev->dma_coherent =3D false; + dev_clear_dma_coherent(chan_dev); chan_dev->dma_parms =3D NULL; } } diff --git a/include/linux/device.h b/include/linux/device.h index a1d59ff9702c..fca986cef2ed 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -481,6 +481,8 @@ struct device_physical_location { * @DEV_FLAG_STATE_SYNCED: The hardware state of this device has been sync= ed to * match the software state of this device by calling the * driver/bus sync_state() callback. + * @DEV_FLAG_DMA_COHERENT: This particular device is dma coherent, even if= the + * architecture supports non-coherent devices. */ enum struct_device_flags { DEV_FLAG_READY_TO_PROBE =3D 0, @@ -489,6 +491,7 @@ enum struct_device_flags { DEV_FLAG_DMA_SKIP_SYNC =3D 3, DEV_FLAG_DMA_OPS_BYPASS =3D 4, DEV_FLAG_STATE_SYNCED =3D 5, + DEV_FLAG_DMA_COHERENT =3D 6, =20 DEV_FLAG_COUNT }; @@ -572,8 +575,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. - * @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. * * At the lowest level, every device in a Linux system is represented by an @@ -681,11 +682,6 @@ struct device { bool offline_disabled:1; bool offline:1; bool of_node_reused: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) - bool dma_coherent:1; -#endif =20 DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; @@ -718,6 +714,7 @@ __create_dev_flag_accessors(dma_iommu, DEV_FLAG_DMA_IOM= MU); __create_dev_flag_accessors(dma_skip_sync, DEV_FLAG_DMA_SKIP_SYNC); __create_dev_flag_accessors(dma_ops_bypass, DEV_FLAG_DMA_OPS_BYPASS); __create_dev_flag_accessors(state_synced, DEV_FLAG_STATE_SYNCED); +__create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT); =20 /** * struct device_link - Device link representation. diff --git a/include/linux/dma-map-ops.h b/include/linux/dma-map-ops.h index edd7de60a957..44dd9035b4fe 100644 --- a/include/linux/dma-map-ops.h +++ b/include/linux/dma-map-ops.h @@ -230,7 +230,7 @@ int dma_direct_set_offset(struct device *dev, phys_addr= _t cpu_start, extern bool dma_default_coherent; static inline bool dev_is_dma_coherent(struct device *dev) { - return dev->dma_coherent; + return dev_dma_coherent(dev); } #else #define dma_default_coherent true --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dy1-f180.google.com (mail-dy1-f180.google.com [74.125.82.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 32D3DDDCD for ; Sat, 4 Apr 2026 00:07:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.180 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261265; cv=none; b=coYyJj7E0/lAlAemwV+wNiKA5tfXbowj/KxdDTk/y96ZL9nbd6KELxfyOtRkh+bzTuKv1eyTRPhg5j5FsF5NvQQxBSkvaRKcgIWcdj/wrSLaAnZmUWDuTds12QjfLwombZ7lymV6gOgk5mY2qRGpZH7lV5eBXX1CkGDgCMJ9be8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261265; c=relaxed/simple; bh=d23SS4JYDl51gvVRVxBmRbh490gs/+zf7Nk228iDvk8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YJ6+SFe52pTj0AlF+1s2sRzfUiiKj+9bNNINnYlEF8PS0D8VgzujNFohTxKVAhzwwZ1fU/m5x/Vrdjs0cN1oontOBnQbdLujYVLvL1R2DagoZHtZdwVywxgp7KIE2dGbhqHFIr4Ttwois9OfffsSOrjtHiCqp9RgyCH6ria5zJ8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=hMxqXADh; arc=none smtp.client-ip=74.125.82.180 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="hMxqXADh" Received: by mail-dy1-f180.google.com with SMTP id 5a478bee46e88-2c54c68db4dso4526378eec.0 for ; Fri, 03 Apr 2026 17:07:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261262; x=1775866062; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=P2v/+uE3FItR13RHlHLOGT8kS+I6Lrtj4w+A1WuT72k=; b=hMxqXADhxHEB8PpGdPLT3E9BO7OEHrvpWlZgyRi1Z2P4yHLA/qTd/aCjzL1Dc6fFZB konlEU2Rq7JWysWGyGFiBmz0kHvfShFp2gkJPzuPGYtBJ5wUHk5GvMiN8CNOWZUFhHjm bnHr67qxcR3dgctlQitioXagTk5MeQd9NKn30= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261262; x=1775866062; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=P2v/+uE3FItR13RHlHLOGT8kS+I6Lrtj4w+A1WuT72k=; b=s5ndkW1aVC5w6I4jKyTaCZnOLaT0XtKHZAJ2e4B78LcnM40dXxLOBojjZaVPy9wilq 4+2jFye5uZ/JRh42umewVJCLIJnDLit25ElKXcfxZwoBcJFEPkGKc6AQqcTbWDDSZ77M SxHdX9YQ6BDbqoHipxN6oVxpbZ4BWonO5mDVqZSje7Lvhtq79fPRf+SEcayfxAeF7fXk rcyLOGDxRVYhUPICM9UGGbKF3W6TKBblDHe7ZxtERB1VL//IuYPfjznzGzz93HR+eziJ xYsjyKc7X+g+mtK1sfuLtOKhsRGuD9fnKfxhTbYxl9IuBxg5xqxzFfDjbs7RqVg+YOTE lIAA== X-Forwarded-Encrypted: i=1; AJvYcCU0mwx8JL4aacibxCBSfAnke6PdKK5EPpzHTk4P86JM2R6QSlIz9sakuTsLwEuYfda/Wefyy1MuDNHrGI4=@vger.kernel.org X-Gm-Message-State: AOJu0YxrwIhecYseLNSBjgVlSPtqwpfARZdSOqLULm+XXe/Dk9dDS7pG f7YgxAmbMshnsFPrRX2uyiTs1qfi3OWRd9mhhNrlUfSnqedVuXjp7fIYy/MjRCskJg== X-Gm-Gg: AeBDievyOx4TgIjqwZVHtYlvWvm4xNhNlzDq3gcINV6Cg3zCNImYt/bLFJLqO5d7Hlj 8xpo1La2GZ4qNDf9ilMTXF/m2TNpDJv4FSkrxuE6jQv9b3XLY6F3nqV4iQruQr3Sb8cLqqYjihW 2E9RJk/Xlkd6XjRM7eUhzHh7HPxMcMzipQ2w6qt5lPFCAjXTzOCbXbGCVC7VtFLdBRBh04okWhU 2AuboTuSIJ+Wzoich15eLFtR09lBMhdaw9c14So4HFS/f8PmanxQls7Tfpq4eZ5EyQYAVClzv8H SX7qFR1hafvMORtnR7ag2c1yKE2fBOMblGEO8Z8oTDgpEEIka7gJ6nTEw5HVZJaHgfPPgkfyrtb ojSHEvlZd1sn8olH2NAVFP/EQ3s95hFf9nM6HgTC06kk6YfHyA8HhF+q74QV2piJgc07ipjAxOd 2Kr4KdKihMeXvsUimIJppPtgzH5BXmW4M9P06Ya/CJB5UdkuFRc/w0NBGweQVXQB9iZvQFzB3XE vb3wA6UpzM= X-Received: by 2002:a05:7300:b54b:b0:2c5:347:e628 with SMTP id 5a478bee46e88-2cbfbf77d5bmr2583156eec.21.1775261262312; Fri, 03 Apr 2026 17:07:42 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:41 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , Mark Brown , alexander.stein@ew.tq-group.com, andrew@codeconstruct.com.au, andrew@lunn.ch, andriy.shevchenko@linux.intel.com, bhelgaas@google.com, brgl@kernel.org, davem@davemloft.net, devicetree@vger.kernel.org, driver-core@lists.linux.dev, hkallweit1@gmail.com, jirislaby@kernel.org, joel@jms.id.au, kees@kernel.org, kuba@kernel.org, lgirdwood@gmail.com, linux-arm-kernel@lists.infradead.org, linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux@armlinux.org.uk, mani@kernel.org, netdev@vger.kernel.org, pabeni@redhat.com, robh@kernel.org Subject: [PATCH v4 8/9] driver core: Replace dev->of_node_reused with dev_of_node_reused() Date: Fri, 3 Apr 2026 17:05:02 -0700 Message-ID: <20260403170432.v4.8.I806b8636cd3724f6cd1f5e199318ab8694472d90@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In C, bitfields are not necessarily safe to modify from multiple threads without locking. Switch "of_node_reused" over to the "flags" field so modifications are safe. Cc: Johan Hovold Acked-by: Mark Brown Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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 v4: - Use accessor functions for flags Changes in v3: - New drivers/base/core.c | 2 +- drivers/base/pinctrl.c | 2 +- drivers/base/platform.c | 2 +- drivers/net/pcs/pcs-xpcs-plat.c | 2 +- drivers/of/device.c | 6 +++--- drivers/pci/of.c | 2 +- drivers/pci/pwrctrl/core.c | 2 +- drivers/regulator/bq257xx-regulator.c | 2 +- drivers/regulator/rk808-regulator.c | 2 +- drivers/tty/serial/serial_base_bus.c | 2 +- drivers/usb/gadget/udc/aspeed-vhub/dev.c | 2 +- include/linux/device.h | 7 ++++--- 12 files changed, 17 insertions(+), 16 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 531f02a5469a..f12f3b53b4d0 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -5281,7 +5281,7 @@ void device_set_of_node_from_dev(struct device *dev, = const struct device *dev2) { of_node_put(dev->of_node); dev->of_node =3D of_node_get(dev2->of_node); - dev->of_node_reused =3D true; + dev_set_of_node_reused(dev); } EXPORT_SYMBOL_GPL(device_set_of_node_from_dev); =20 diff --git a/drivers/base/pinctrl.c b/drivers/base/pinctrl.c index 6e250272c843..0bbc83231234 100644 --- a/drivers/base/pinctrl.c +++ b/drivers/base/pinctrl.c @@ -24,7 +24,7 @@ int pinctrl_bind_pins(struct device *dev) { int ret; =20 - if (dev->of_node_reused) + if (dev_of_node_reused(dev)) return 0; =20 dev->pins =3D devm_kzalloc(dev, sizeof(*(dev->pins)), GFP_KERNEL); diff --git a/drivers/base/platform.c b/drivers/base/platform.c index d44591d52e36..199e6fb25770 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -856,7 +856,7 @@ struct platform_device *platform_device_register_full( pdev->dev.parent =3D pdevinfo->parent; pdev->dev.fwnode =3D pdevinfo->fwnode; pdev->dev.of_node =3D of_node_get(to_of_node(pdev->dev.fwnode)); - pdev->dev.of_node_reused =3D pdevinfo->of_node_reused; + dev_assign_of_node_reused(&pdev->dev, pdevinfo->of_node_reused); =20 if (pdevinfo->dma_mask) { pdev->platform_dma_mask =3D pdevinfo->dma_mask; diff --git a/drivers/net/pcs/pcs-xpcs-plat.c b/drivers/net/pcs/pcs-xpcs-pla= t.c index b8c48f9effbf..f4b1b8246ce9 100644 --- a/drivers/net/pcs/pcs-xpcs-plat.c +++ b/drivers/net/pcs/pcs-xpcs-plat.c @@ -349,7 +349,7 @@ static int xpcs_plat_init_dev(struct dw_xpcs_plat *pxpc= s) * up later. Make sure DD-core is aware of the OF-node being re-used. */ device_set_node(&mdiodev->dev, fwnode_handle_get(dev_fwnode(dev))); - mdiodev->dev.of_node_reused =3D true; + dev_set_of_node_reused(&mdiodev->dev); =20 /* Pass the data further so the DW XPCS driver core could use it */ mdiodev->dev.platform_data =3D (void *)device_get_match_data(dev); diff --git a/drivers/of/device.c b/drivers/of/device.c index f7e75e527667..be4e1584e0af 100644 --- a/drivers/of/device.c +++ b/drivers/of/device.c @@ -26,7 +26,7 @@ const struct of_device_id *of_match_device(const struct of_device_id *matc= hes, const struct device *dev) { - if (!matches || !dev->of_node || dev->of_node_reused) + if (!matches || !dev->of_node || dev_of_node_reused(dev)) return NULL; return of_match_node(matches, dev->of_node); } @@ -192,7 +192,7 @@ ssize_t of_device_modalias(struct device *dev, char *st= r, ssize_t len) { ssize_t sl; =20 - if (!dev || !dev->of_node || dev->of_node_reused) + if (!dev || !dev->of_node || dev_of_node_reused(dev)) return -ENODEV; =20 sl =3D of_modalias(dev->of_node, str, len - 2); @@ -254,7 +254,7 @@ int of_device_uevent_modalias(const struct device *dev,= struct kobj_uevent_env * { int sl; =20 - if ((!dev) || (!dev->of_node) || dev->of_node_reused) + if ((!dev) || (!dev->of_node) || dev_of_node_reused(dev)) return -ENODEV; =20 /* Devicetree modalias is tricky, we add it in 2 steps */ diff --git a/drivers/pci/of.c b/drivers/pci/of.c index 9f8eb5df279e..1f9b669abdb0 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -38,7 +38,7 @@ int pci_set_of_node(struct pci_dev *dev) struct device *pdev __free(put_device) =3D bus_find_device_by_of_node(&platform_bus_type, node); if (pdev) - dev->bus->dev.of_node_reused =3D true; + dev_set_of_node_reused(&dev->bus->dev); =20 device_set_node(&dev->dev, of_fwnode_handle(no_free_ptr(node))); return 0; diff --git a/drivers/pci/pwrctrl/core.c b/drivers/pci/pwrctrl/core.c index 7754baed67f2..72963a92362a 100644 --- a/drivers/pci/pwrctrl/core.c +++ b/drivers/pci/pwrctrl/core.c @@ -39,7 +39,7 @@ static int pci_pwrctrl_notify(struct notifier_block *nb, = unsigned long action, * If we got here then the PCI device is the second after the * power control platform device. Mark its OF node as reused. */ - dev->of_node_reused =3D true; + dev_set_of_node_reused(dev); break; } =20 diff --git a/drivers/regulator/bq257xx-regulator.c b/drivers/regulator/bq25= 7xx-regulator.c index dab8f1ab4450..40e0f1a7ae81 100644 --- a/drivers/regulator/bq257xx-regulator.c +++ b/drivers/regulator/bq257xx-regulator.c @@ -143,7 +143,7 @@ static int bq257xx_regulator_probe(struct platform_devi= ce *pdev) struct regulator_config cfg =3D {}; =20 pdev->dev.of_node =3D pdev->dev.parent->of_node; - pdev->dev.of_node_reused =3D true; + dev_set_of_node_reused(&pdev->dev); =20 pdata =3D devm_kzalloc(&pdev->dev, sizeof(struct bq257xx_reg_data), GFP_K= ERNEL); if (!pdata) diff --git a/drivers/regulator/rk808-regulator.c b/drivers/regulator/rk808-= regulator.c index e66408f23bb6..8297d31cde9f 100644 --- a/drivers/regulator/rk808-regulator.c +++ b/drivers/regulator/rk808-regulator.c @@ -2115,7 +2115,7 @@ static int rk808_regulator_probe(struct platform_devi= ce *pdev) int ret, i, nregulators; =20 pdev->dev.of_node =3D pdev->dev.parent->of_node; - pdev->dev.of_node_reused =3D true; + dev_set_of_node_reused(&pdev->dev); =20 regmap =3D dev_get_regmap(pdev->dev.parent, NULL); if (!regmap) diff --git a/drivers/tty/serial/serial_base_bus.c b/drivers/tty/serial/seri= al_base_bus.c index a12935f6b992..5f23284a8778 100644 --- a/drivers/tty/serial/serial_base_bus.c +++ b/drivers/tty/serial/serial_base_bus.c @@ -74,7 +74,7 @@ static int serial_base_device_init(struct uart_port *port, dev->parent =3D parent_dev; dev->bus =3D &serial_base_bus_type; dev->release =3D release; - dev->of_node_reused =3D true; + dev_set_of_node_reused(dev); =20 device_set_node(dev, fwnode_handle_get(dev_fwnode(parent_dev))); =20 diff --git a/drivers/usb/gadget/udc/aspeed-vhub/dev.c b/drivers/usb/gadget/= udc/aspeed-vhub/dev.c index 2ecd049dacc2..8b9449d16324 100644 --- a/drivers/usb/gadget/udc/aspeed-vhub/dev.c +++ b/drivers/usb/gadget/udc/aspeed-vhub/dev.c @@ -593,7 +593,7 @@ int ast_vhub_init_dev(struct ast_vhub *vhub, unsigned i= nt idx) d->gadget.max_speed =3D USB_SPEED_HIGH; d->gadget.speed =3D USB_SPEED_UNKNOWN; d->gadget.dev.of_node =3D vhub->pdev->dev.of_node; - d->gadget.dev.of_node_reused =3D true; + dev_set_of_node_reused(&d->gadget.dev); =20 rc =3D usb_add_gadget_udc(d->port_dev, &d->gadget); if (rc !=3D 0) diff --git a/include/linux/device.h b/include/linux/device.h index fca986cef2ed..8132aab17e04 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -483,6 +483,8 @@ struct device_physical_location { * driver/bus sync_state() callback. * @DEV_FLAG_DMA_COHERENT: This particular device is dma coherent, even if= the * architecture supports non-coherent devices. + * @DEV_FLAG_OF_NODE_REUSED: Set if the device-tree node is shared with an + * ancestor device. */ enum struct_device_flags { DEV_FLAG_READY_TO_PROBE =3D 0, @@ -492,6 +494,7 @@ enum struct_device_flags { DEV_FLAG_DMA_OPS_BYPASS =3D 4, DEV_FLAG_STATE_SYNCED =3D 5, DEV_FLAG_DMA_COHERENT =3D 6, + DEV_FLAG_OF_NODE_REUSED =3D 7, =20 DEV_FLAG_COUNT }; @@ -573,8 +576,6 @@ enum struct_device_flags { * * @offline_disabled: If set, the device is permanently online. * @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. * @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 @@ -681,7 +682,6 @@ struct device { =20 bool offline_disabled:1; bool offline:1; - bool of_node_reused:1; =20 DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; @@ -715,6 +715,7 @@ __create_dev_flag_accessors(dma_skip_sync, DEV_FLAG_DMA= _SKIP_SYNC); __create_dev_flag_accessors(dma_ops_bypass, DEV_FLAG_DMA_OPS_BYPASS); __create_dev_flag_accessors(state_synced, DEV_FLAG_STATE_SYNCED); __create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT); +__create_dev_flag_accessors(of_node_reused, DEV_FLAG_OF_NODE_REUSED); =20 /** * struct device_link - Device link representation. --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 17:33:45 2026 Received: from mail-dy1-f169.google.com (mail-dy1-f169.google.com [74.125.82.169]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B1BA5199FB0 for ; Sat, 4 Apr 2026 00:07:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.169 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261268; cv=none; b=ajJmc224mTUrsJDS0T1GTaHOskTpQXIQH+c2oI81kw/cLWdBp64bRtAXjFeBeiUz754rVN+OH0flmUQJsJIyZrOP2zVxR9zGhjirYddkew4+1pAu7E4XkEiMOBBujyUJBzjDTOEA+r0lilsb1TJnQzso/5kNe3AHHiv/M93YJ9o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775261268; c=relaxed/simple; bh=o+VlMAnQQaP1SWDlc4XFND6M5h5/jJtCq+7R5B9vAq8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=GoMUwZz837xgqHs4GPPcYVVOt8eMRvugqL4TiEhveZjjUckKrwuUZLp7WsbJKgNlT2clTwIfxqsCRyzeHNrDrH2yWIA7KhTP9d4mz0moTf0BvDnc8JjLCEMJB4l0GCJuXpdm6W1zoOe0iVUb+30c8qUJbHnb23nv6sqvYHCwMBk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org; spf=pass smtp.mailfrom=chromium.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b=TG9sgBH3; arc=none smtp.client-ip=74.125.82.169 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=chromium.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=chromium.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=chromium.org header.i=@chromium.org header.b="TG9sgBH3" Received: by mail-dy1-f169.google.com with SMTP id 5a478bee46e88-2cbdd9852aaso1681532eec.0 for ; Fri, 03 Apr 2026 17:07:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775261266; x=1775866066; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=5WbWNOKgJimgI9xjyvoHzw2TjM6jyvThEk+IUd6YUTg=; b=TG9sgBH3FGbXqx4NpgO/yjO3Uw7l9avqXSEpVc8xWEKFedXVFEx3GEs6VHOKsDxfoq Id4HBT8gdrw7aX9v6oKSMa4HjMMQgzWq/iJELUm8DZ9D+jsWEs3tiaw5G3GZ8tBRckTA UGcGWRntC+nw3fuojSzrVGfpvR9xGYCm8CkE8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775261266; x=1775866066; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=5WbWNOKgJimgI9xjyvoHzw2TjM6jyvThEk+IUd6YUTg=; b=qWKZthXcVKUyvAX/CWGOOC43eM+ErQN452QKdVStBsb3KN71oj/FwGB66p882lmfJ9 Iv19KJUtvVOoPYogTNMtx1TZwR1ZaVDr5QiTC/W5PzOxQb6z6F/99r95NczCPWocwvdv w7Vvd+lZBa0HbfTA2mNGuInqOTrcRSEAQyoj9obM53U3rZUmU8dY6OVUwqSXRoOBaukN 71mof0I2A7+jgBgWfsV5LAlNDTitLdN959X47vtg4QDVTeTSmpjGjq72tJL1sqMeJ7iU JOqbYKlV4eu340VSyGuF+Ea/iPJFxTiHNNWskBEVAcmawWhJUkf455qElXrkO/k/iwHF op6w== X-Forwarded-Encrypted: i=1; AJvYcCXrmuSKGyPqjR9weFfZd96cjY8cijW1syfwCG8VbNhZX3krdUp0dh61iwruXfpV7nDufI2C2dt3F+2ffpg=@vger.kernel.org X-Gm-Message-State: AOJu0YwuSqdwXXDFD6s5h209RtMrhx5cwlM3rLWVychnHofAR9DpfDUo W0EIlMjkQezgo41ktkiaRA3F+RLnq7svovSkyIJQ76XHsSW1oPRgNsR0+/jSRIpUgg== X-Gm-Gg: AeBDiesKFtD4W8oRCWnVGwKnOi9DaReXGntkDQb/tKT+e9BE0rZG59/2/dJq60xPW41 VbxxGHuzEgWEtmWhvv5XKSad3D9xkGwwU2o3muOymBWSoBHKbqON3EopuqxugEehVBOe87LkG3W tl8XA0Yg/BPIqQysLMmeA5nNdqA7MVk1F9wYOtNHLbiv2Fn19y2ForN6K5Kek+LgAjPQ7GRGtGa TKjo9uvIx8KHzgyIrjZbkxqCz/r/tiMZIAKzKWKNc/QA1+IAQkZIcVqnO5lfmXIzMl/uXwdJwZN oiQYPNhKbDz7Y2oejB2EMz/gGXo8Z876ux+3hN2BOTlD/Mg87T5341DFT0h9VHR6OTGOFW6ylCT 7IhlDpJTPAJdUCIJ8Kvpy9oJ22jkpk5k4P657sho9BFoho8LGSayXZuWr0GiJzEId6J0qbvSITv G3NCkXBZo0Pd/jG5pKZcD13t2ozfaoJy/J17uXMSm7i0uevQ9EINKIRvg5Jv5Kfwx0SK9yHzCqh STIJeB/RS1znv++2ujzRA== X-Received: by 2002:a05:7300:dc88:b0:2b7:b7e7:9025 with SMTP id 5a478bee46e88-2cbfcb5580fmr2229803eec.31.1775261265791; Fri, 03 Apr 2026 17:07:45 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:a8b6:55b2:3eb6:2c0e]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca79e1d93bsm6520716eec.12.2026.04.03.17.07.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 03 Apr 2026 17:07:44 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Saravana Kannan , Christoph Hellwig , Eric Dumazet , Johan Hovold , Leon Romanovsky , Alexander Lobakin , Alexey Kardashevskiy , Robin Murphy , Douglas Anderson , Mark Brown , ardb@kernel.org, catalin.marinas@arm.com, chleroy@kernel.org, david@kernel.org, driver-core@lists.linux.dev, kees@kernel.org, kevin.brodsky@arm.com, lenb@kernel.org, linux-acpi@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-cxl@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linuxppc-dev@lists.ozlabs.org, maddy@linux.ibm.com, maz@kernel.org, miko.lenczewski@arm.com, mpe@ellerman.id.au, npiggin@gmail.com, osalvador@suse.de, oupton@kernel.org, peterz@infradead.org, tglx@kernel.org, will@kernel.org, yangyicong@hisilicon.com, yeoreum.yun@arm.com Subject: [PATCH v4 9/9] driver core: Replace dev->offline + ->offline_disabled with accessors Date: Fri, 3 Apr 2026 17:05:03 -0700 Message-ID: <20260403170432.v4.9.I897d478b4a9361d79cd5073207c1062fd4d0d0e4@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260404000644.522677-1-dianders@chromium.org> References: <20260404000644.522677-1-dianders@chromium.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" In C, bitfields are not necessarily safe to modify from multiple threads without locking. Switch "offline" and "offline_disabled" over to the "flags" field so modifications are safe. Cc: Rafael J. Wysocki Acked-by: Mark Brown Signed-off-by: Douglas Anderson Reviewed-by: Danilo Krummrich Reviewed-by: Rafael J. Wysocki (Intel) --- 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 v4: - Use accessor functions for flags Changes in v3: - New arch/arm64/kernel/cpufeature.c | 2 +- .../powerpc/platforms/pseries/hotplug-memory.c | 4 ++-- drivers/acpi/scan.c | 2 +- drivers/base/core.c | 18 +++++++++--------- drivers/base/cpu.c | 4 ++-- drivers/base/memory.c | 2 +- include/linux/device.h | 12 ++++++------ kernel/cpu.c | 4 ++-- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 32c2dbcc0c64..c832aa565dc2 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -4042,7 +4042,7 @@ static int enable_mismatched_32bit_el0(unsigned int c= pu) */ lucky_winner =3D cpu_32bit ? cpu : cpumask_any_and(cpu_32bit_el0_mask, cpu_active_mask); - get_cpu_device(lucky_winner)->offline_disabled =3D true; + dev_set_offline_disabled(get_cpu_device(lucky_winner)); setup_elf_hwcaps(compat_elf_hwcaps); elf_hwcap_fixup(); pr_info("Asymmetric 32-bit EL0 support detected on CPU %u; CPU hot-unplug= disabled on CPU %u\n", diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc= /platforms/pseries/hotplug-memory.c index b2f14db59034..75f85a5da981 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -213,9 +213,9 @@ static int dlpar_change_lmb_state(struct drmem_lmb *lmb= , bool online) return -EINVAL; } =20 - if (online && mem_block->dev.offline) + if (online && dev_offline(&mem_block->dev)) rc =3D device_online(&mem_block->dev); - else if (!online && !mem_block->dev.offline) + else if (!online && !dev_offline(&mem_block->dev)) rc =3D device_offline(&mem_block->dev); else rc =3D 0; diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index e8cdbdb46fdb..1353adbcc234 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -122,7 +122,7 @@ bool acpi_scan_is_offline(struct acpi_device *adev, boo= l uevent) mutex_lock_nested(&adev->physical_node_lock, SINGLE_DEPTH_NESTING); =20 list_for_each_entry(pn, &adev->physical_node_list, node) - if (device_supports_offline(pn->dev) && !pn->dev->offline) { + if (device_supports_offline(pn->dev) && !dev_offline(pn->dev)) { if (uevent) kobject_uevent_env(&pn->dev->kobj, KOBJ_CHANGE, envp); =20 diff --git a/drivers/base/core.c b/drivers/base/core.c index f12f3b53b4d0..79c85dbcffad 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -2788,7 +2788,7 @@ static ssize_t online_show(struct device *dev, struct= device_attribute *attr, bool val; =20 device_lock(dev); - val =3D !dev->offline; + val =3D !dev_offline(dev); device_unlock(dev); return sysfs_emit(buf, "%u\n", val); } @@ -2913,7 +2913,7 @@ static int device_add_attrs(struct device *dev) if (error) goto err_remove_type_groups; =20 - if (device_supports_offline(dev) && !dev->offline_disabled) { + if (device_supports_offline(dev) && !dev_offline_disabled(dev)) { error =3D device_create_file(dev, &dev_attr_online); if (error) goto err_remove_dev_groups; @@ -4178,7 +4178,7 @@ static int device_check_offline(struct device *dev, v= oid *not_used) if (ret) return ret; =20 - return device_supports_offline(dev) && !dev->offline ? -EBUSY : 0; + return device_supports_offline(dev) && !dev_offline(dev) ? -EBUSY : 0; } =20 /** @@ -4196,7 +4196,7 @@ int device_offline(struct device *dev) { int ret; =20 - if (dev->offline_disabled) + if (dev_offline_disabled(dev)) return -EPERM; =20 ret =3D device_for_each_child(dev, NULL, device_check_offline); @@ -4205,13 +4205,13 @@ int device_offline(struct device *dev) =20 device_lock(dev); if (device_supports_offline(dev)) { - if (dev->offline) { + if (dev_offline(dev)) { ret =3D 1; } else { ret =3D dev->bus->offline(dev); if (!ret) { kobject_uevent(&dev->kobj, KOBJ_OFFLINE); - dev->offline =3D true; + dev_set_offline(dev); } } } @@ -4236,11 +4236,11 @@ int device_online(struct device *dev) =20 device_lock(dev); if (device_supports_offline(dev)) { - if (dev->offline) { + if (dev_offline(dev)) { ret =3D dev->bus->online(dev); if (!ret) { kobject_uevent(&dev->kobj, KOBJ_ONLINE); - dev->offline =3D false; + dev_clear_offline(dev); } } else { ret =3D 1; @@ -4714,7 +4714,7 @@ static int device_attrs_change_owner(struct device *d= ev, kuid_t kuid, if (error) return error; =20 - if (device_supports_offline(dev) && !dev->offline_disabled) { + if (device_supports_offline(dev) && !dev_offline_disabled(dev)) { /* Change online device attributes of @dev to @kuid/@kgid. */ error =3D sysfs_file_change_owner(kobj, dev_attr_online.attr.name, kuid, kgid); diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 875abdc9942e..19d288a3c80c 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -422,8 +422,8 @@ int register_cpu(struct cpu *cpu, int num) cpu->dev.id =3D num; cpu->dev.bus =3D &cpu_subsys; cpu->dev.release =3D cpu_device_release; - cpu->dev.offline_disabled =3D !cpu->hotpluggable; - cpu->dev.offline =3D !cpu_online(num); + dev_assign_offline_disabled(&cpu->dev, !cpu->hotpluggable); + dev_assign_offline(&cpu->dev, !cpu_online(num)); cpu->dev.of_node =3D of_get_cpu_node(num, NULL); cpu->dev.groups =3D common_cpu_attr_groups; if (cpu->hotpluggable) diff --git a/drivers/base/memory.c b/drivers/base/memory.c index a3091924918b..5005654f44fa 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -697,7 +697,7 @@ static int __add_memory_block(struct memory_block *memo= ry) memory->dev.id =3D memory->start_section_nr / sections_per_block; memory->dev.release =3D memory_block_release; memory->dev.groups =3D memory_memblk_attr_groups; - memory->dev.offline =3D memory->state =3D=3D MEM_OFFLINE; + dev_assign_offline(&memory->dev, memory->state =3D=3D MEM_OFFLINE); =20 ret =3D device_register(&memory->dev); if (ret) { diff --git a/include/linux/device.h b/include/linux/device.h index 8132aab17e04..65fc6c566cc6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -485,6 +485,8 @@ struct device_physical_location { * architecture supports non-coherent devices. * @DEV_FLAG_OF_NODE_REUSED: Set if the device-tree node is shared with an * ancestor device. + * @DEV_FLAG_OFFLINE_DISABLED: If set, the device is permanently online. + * @DEV_FLAG_OFFLINE: Set after successful invocation of bus type's .offli= ne(). */ enum struct_device_flags { DEV_FLAG_READY_TO_PROBE =3D 0, @@ -495,6 +497,8 @@ enum struct_device_flags { DEV_FLAG_STATE_SYNCED =3D 5, DEV_FLAG_DMA_COHERENT =3D 6, DEV_FLAG_OF_NODE_REUSED =3D 7, + DEV_FLAG_OFFLINE_DISABLED =3D 8, + DEV_FLAG_OFFLINE =3D 9, =20 DEV_FLAG_COUNT }; @@ -573,9 +577,6 @@ enum struct_device_flags { * @removable: Whether the device can be removed from the system. This * should be set by the subsystem / bus driver that discovered * the device. - * - * @offline_disabled: If set, the device is permanently online. - * @offline: Set after successful invocation of bus type's .offline(). * @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 @@ -680,9 +681,6 @@ struct device { =20 enum device_removable removable; =20 - bool offline_disabled:1; - bool offline:1; - DECLARE_BITMAP(flags, DEV_FLAG_COUNT); }; =20 @@ -716,6 +714,8 @@ __create_dev_flag_accessors(dma_ops_bypass, DEV_FLAG_DM= A_OPS_BYPASS); __create_dev_flag_accessors(state_synced, DEV_FLAG_STATE_SYNCED); __create_dev_flag_accessors(dma_coherent, DEV_FLAG_DMA_COHERENT); __create_dev_flag_accessors(of_node_reused, DEV_FLAG_OF_NODE_REUSED); +__create_dev_flag_accessors(offline_disabled, DEV_FLAG_OFFLINE_DISABLED); +__create_dev_flag_accessors(offline, DEV_FLAG_OFFLINE); =20 /** * struct device_link - Device link representation. diff --git a/kernel/cpu.c b/kernel/cpu.c index bc4f7a9ba64e..f975bb34915b 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c @@ -2639,7 +2639,7 @@ static void cpuhp_offline_cpu_device(unsigned int cpu) { struct device *dev =3D get_cpu_device(cpu); =20 - dev->offline =3D true; + dev_set_offline(dev); /* Tell user space about the state change */ kobject_uevent(&dev->kobj, KOBJ_OFFLINE); } @@ -2648,7 +2648,7 @@ static void cpuhp_online_cpu_device(unsigned int cpu) { struct device *dev =3D get_cpu_device(cpu); =20 - dev->offline =3D false; + dev_clear_offline(dev); /* Tell user space about the state change */ kobject_uevent(&dev->kobj, KOBJ_ONLINE); } --=20 2.53.0.1213.gd9a14994de-goog