From nobody Sun Jun 14 12:44:34 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 6D2453A16BD for ; Mon, 6 Apr 2026 23:25:26 +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=1775517928; cv=none; b=VCrs6tUJU0l4qX1yAucpIvR7mIsamG/i1uLfOA6249hjeniLO1Qs1wmzZDdz6Wd4eijl53FP2UWOFQKsFVgstQCdhW98r7rYt2v0CPGB2wIoYFWHH1ysDq6H0g4gTaNs48zMCeDjE2wS4LeL83JjeuHu65RMHEiD659pqfU9OHM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517928; c=relaxed/simple; bh=Bd5A2KPcpF/ATs/sqB6YpZ/gPr8U0uw26sL49f0AJw0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CIIzNqoBa6MiGobFFDXqtcFYD5mZ2Tu+pYFnB8c7YhGKmUxlJGAiFbTCqYMjjbuoOEAdddkBhsvT0HPQ8928S1adZlQ8E2Yc37jECvAuZYsNV+shVqQQDO3jeSg0giFG19+PvFc7e/5/jZz6ILRqneLvbCJAavVuSb+IRfIP4jw= 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=TSaNQTNf; 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="TSaNQTNf" Received: by mail-dy1-f181.google.com with SMTP id 5a478bee46e88-2c7d8bbad06so9857138eec.1 for ; Mon, 06 Apr 2026 16:25:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517925; x=1776122725; 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=0eXa4n/+d4pw2xx1veNnhho16xTcm7K/bpDU8BI1Eto=; b=TSaNQTNfkHbe6BNp+lcHa4Q5AhqdAhFPYkf0RDjS2ssE6UxtriVI3BG5OPZPnL0j8A pUnE7ELwHUf5qkV2Y/FPdZQ1XqXKdtGa9B1DF350xrAdKTCbx8R3ClQBcWcIbamI9cQF hu3uBg7pqMzFUnjrv1Jpw9msdrA85WTrdcwZw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517925; x=1776122725; 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=0eXa4n/+d4pw2xx1veNnhho16xTcm7K/bpDU8BI1Eto=; b=YL+yDcV2doJ+nPQIZgUmg+P39q7fL2ripu6STbtwHzrGW3Bfi54KuusL1+x2rcV8nc k63EDx0Z+QxzXDcF9FtQ6tPi86FYu4kSC0wmUbKBGjkbk61xb03VMMvgkmyWeOsOBnFf EoDXBuYvsTfYIbqd4PKopo99zHYZ2k8DNsOYf+GgDYPakxxdHdyHQU7FMhPO87ldY3G1 yF8asCFvhZcoI19bKDxgvZ/dkmp51J0uQe+igZ2s71TmFQKOrsNP1VZZFfH/gFdy0jDh I6Gu19hjJkdVWls2DeWzh9TVT/fHEMN0yO/SJrRFejlLdp1gO7E62zT8y3WjWd1KYLIR 7+GQ== X-Forwarded-Encrypted: i=1; AJvYcCW83MzOzWWz0Nl3CNS6/nAt6W6LEOygCCyRAZqCqaAYlDeBDKT9iG8LbitXCNcZnuOEsqlmyXJreoIuew0=@vger.kernel.org X-Gm-Message-State: AOJu0YwQPv0w3jsDlXbDhuf4IWyuU9/GxefhzWPwUGN5n45MoF3sbCQl pJqixd1VJeUgrG0e4oVkKlF4lhXshN6wuS80aGsAWIkLztJJVN7rACV4t9XjodH+iw== X-Gm-Gg: AeBDieuLMskld+KNRw05RX7UC5dNDjDc0FRoIHXhWuR4TisJmcyCUD/pIAEe9nG3slt Sc2PVwsLE/wbqAcIJsz/ISXZTGJfniYzJo2Ju6Eq7LtHoDD7DkxlOd6febh4oIxaRFk8CqaNyt8 smyyrfGpo/5peOGYFNpNbwhxmKe6yxm+iLv+kc/qn2IlvucK86Za/iGAhQRecp1G/7lWYJBa1o5 x8/cvX2zfX0yrPoVzm6KA09H18AjxbAjVWPU+KpMiwoRbwhy3aLXpx3woJa0WeymiiQ9eMU76+U VuMO6Dikeepv7GAdlRHSDfFrTWNbZsNMPzPHzzfUh/iiJY0DYKXedr23j7qSwZFHvW6wKeDKAPR MC+TKL3zY+uJYfAlq+RdNfBaO0d5sI4MxKRzJ3Fzam1iOvAFaMyErSAJhgWrpH74inoSKBJz4Nz hsksN43rr4glVEo3CapuRvDqcj+iDxScAppVTjDGmeEFJ5MWTAfDvIbsqCd6c6YfMQNbwf+fzsc vYYLo7W9w== X-Received: by 2002:a05:7300:f190:b0:2c4:7bb:5c94 with SMTP id 5a478bee46e88-2cbf9fe6e54mr8139561eec.11.1775517925444; Mon, 06 Apr 2026 16:25:25 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:24 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , Douglas Anderson , stable@vger.kernel.org, driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v5 1/9] driver core: Don't let a device probe until it's ready Date: Mon, 6 Apr 2026 16:22:54 -0700 Message-ID: <20260406162231.v5.1.Id750b0fbcc94f23ed04b7aecabcead688d0d8c17@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 worrying about corrupting nearby bits (and means threads changing other bit won't corrupt us). [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) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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/ v4: https://lore.kernel.org/r/20260404000644.522677-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 v5: - ready_to_prove =3D> ready_to_probe typo - device_lock() while calling dev_set_ready_to_probe() - Add comment before "can_match =3D true" from Danilo. - undef __create_dev_flag_accessors 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 | 15 ++++++++++++++ drivers/base/dd.c | 20 +++++++++++++++++++ include/linux/device.h | 44 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 09b98f02f559..984d6bfbd6e4 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -3688,6 +3688,21 @@ 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_probe" 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. + */ + device_lock(dev); + dev_set_ready_to_probe(dev); + device_unlock(dev); + bus_probe_device(dev); =20 /* diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 37c7e54e0e4c..ec7ef9c5d62e 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -848,6 +848,26 @@ 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"); + + /* + * Set can_match =3D true after calling dev_ready_to_probe(), so + * driver_deferred_probe_add() won't actually add the device to the + * deferred probe list when dev_ready_to_probe() returns false. + * + * When dev_ready_to_probe() returns false, it means that device_add() + * will do another probe() attempt for us. + */ 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..f27ed6eb87a9 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,36 @@ 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); + +#undef __create_dev_flag_accessors + /** * 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 12:44:34 2026 Received: from mail-dy1-f170.google.com (mail-dy1-f170.google.com [74.125.82.170]) (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 B7C493A2566 for ; Mon, 6 Apr 2026 23:25:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517930; cv=none; b=MERVocoE2owHy3mB43N/MvPo014zEaeTrVW/ENFdht2jSHrcav2uzBsBy2WykbTFGVXBZfYRWt5YEWQ1BZuB0DFEp2bC/sORH2G81iZ2eQLixqoexkMxF20BTzKRFbJvITD8vDUfu9gAVty/iNd9eavYMgKfXBVNdyy6B79GJjI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517930; c=relaxed/simple; bh=JpoNAGDaJKJ9hL00/1zW3OpQzxxaUbzvYD001zjveU4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CqExP2VBRLsxbY/olMIjeOKhPsELOzuumpcG4KmkaAQQMI/f4MAqpySJK1+jM0W1okd9RgsoTphTD7QNpMgM2B7pdiEvNS0WLlSrZC+Hshz+aGZO2yl+DxIOW5pUWRJAA1Fl2+789Lj2LnLS0ugtYTOBozkVCItUtBoRHiZDFzM= 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=XSDQUBHy; arc=none smtp.client-ip=74.125.82.170 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="XSDQUBHy" Received: by mail-dy1-f170.google.com with SMTP id 5a478bee46e88-2b4520f6b32so4885262eec.0 for ; Mon, 06 Apr 2026 16:25:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517928; x=1776122728; 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=CaJt/QytLmx9cc7EXwGuHstK77fL+3uwr/3WBtDIoI0=; b=XSDQUBHyIP1Dw1zfgvRINr+HuIFZAOPO8xQYLs3H6iPTHXdqTW+mClnzG3dYf+t9XF WBUHSYeJD7OpOCsYxrq2V8TFI+jkdmiFR45t0heWWRN7oRmWoCiTzkNxQjpGam5mnfOC +HmPiTckaHbnH1ErLF2haYo6kC/vL06iadyxY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517928; x=1776122728; 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=CaJt/QytLmx9cc7EXwGuHstK77fL+3uwr/3WBtDIoI0=; b=OGavIy8sPae6eF/XKq38Soj+2jhVoGtRo7A22+d3zqwCXbsErtOhHnVKgbc8qtbLXH ZiYtfTcn/SHvlq+1TDiZ/xZFnfWke/75wMqBZCemqlekWJS4+ujSKyvBODyKcWhSehvr wCg0kwwV+3hIbl3MigsBf4wa356IRNop+10nfHYs4c4Aomr3DauRwoBZzPfhPb8m035c rz+7zbSeCr9/D2f0l2go7Gmp4Tt3Sh6zngzzmbcd9wwzTuodNAqMQ5o6JLJMvlT+bzPy vGDOhtp2p1xeln4XTeGNSs2F0kJ5XNdfpr1f/Q12mGTxqF+lLMVnTwlqohX3wrA5NsgN Qxdw== X-Forwarded-Encrypted: i=1; AJvYcCUYe3LHgWU07rlaKJ/fRp1k/R15yEa0h2n6OMZyfQjy8Uq2pSK6u+4MU44b0Gw7sRlgRxNChqiB7aNeCwQ=@vger.kernel.org X-Gm-Message-State: AOJu0YwfiH4vBffxUc+onHPfnMkJpJFbJrahFelxoHqHbQ9qCYnLLhPk 913SQJJ/zX236WKbuhrLG1pQgF+E3joQ9UXfxeU8b8i1RHzxV/b1+4HCArTqXwr/X/s2X4MUI8H 2BekaGooN X-Gm-Gg: AeBDiev9aP1NRyJ88I16RZ/Vk0INdHxkj5Hej/IRxTeNATRQCoS7WFlLkW/JIPJ2Wak hAXH+FJqTplE257lZXAOrhuwfFgv16wPZozWV4W2d2qWi3DNBdLjoQMYGsQ8q6qFCYdNq/oNjWA YIBhuQPReytVfzhyOEB5Bpcmn4kYPbqEbF8Wtn1CHuIXYK6doytoBXxru3nYmGEyKR4557G65fp ipbO6gzETdMxBJ9LmX06fWFoFx4ogDRcramjDsah0o9W3HhtRtRxY6PjWn2ftIQFlRQz2uzCSKL OxDLKfGtZc92zR4q88/PqWSGSva783odco2Gg7WxN0+rsX1ps7MPKIsA422Bqv7g4yE3Dw43c4b vtEf4Kz1huPF9+2hod/b9jfsV18Ygo9L21C1hPXUliJnWs5BxLUEsM8gJ6ARdseBUBm9OMSG56s PT5X6Le/NmZYOuCCTS3SBzK9z8Lj1b1oPyNa6TrJWMT/ebj3JMtCzXyHS8eFXN8vJwhwOjV8nx1 HF/V5SYGDYoR38/mGip X-Received: by 2002:a05:7300:a287:b0:2c0:f424:b545 with SMTP id 5a478bee46e88-2cbfa5bdfb3mr7483451eec.15.1775517927810; Mon, 06 Apr 2026 16:25:27 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:26 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , Douglas Anderson , driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v5 2/9] driver core: Replace dev->can_match with dev_can_match() Date: Mon, 6 Apr 2026 16:22:55 -0700 Message-ID: <20260406162231.v5.2.I54b3ae6311ff34ad30227659d91bb109911a4aea@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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). (no changes since v4) Changes in v4: - Use accessor functions for flags Changes in v3: - New drivers/base/core.c | 10 +++++----- drivers/base/dd.c | 10 +++++----- include/linux/device.h | 9 +++++---- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 984d6bfbd6e4..db5aec9e6a2b 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; @@ -3710,7 +3710,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 ec7ef9c5d62e..70fa0b13e74f 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); @@ -861,14 +861,14 @@ static int __driver_probe_device(const struct device_= driver *drv, struct device return dev_err_probe(dev, -EPROBE_DEFER, "Device not ready to probe\n"); =20 /* - * Set can_match =3D true after calling dev_ready_to_probe(), so + * Call dev_set_can_match() after calling dev_ready_to_probe(), so * driver_deferred_probe_add() won't actually add the device to the * deferred probe list when dev_ready_to_probe() returns false. * * When dev_ready_to_probe() returns false, it means that device_add() * will do another probe() attempt for us. */ - 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 @@ -1014,7 +1014,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 @@ -1266,7 +1266,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 f27ed6eb87a9..38f4316b3cde 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 #undef __create_dev_flag_accessors =20 --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 12:44:34 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 C1A5239D6E1 for ; Mon, 6 Apr 2026 23:25:31 +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=1775517933; cv=none; b=jCp1vuyxcZXNfDgFxLkYyymknpmJ7j62i8rgJfO4UBGWqhxKX9mbpcsaMJnvtE9qqCWSLSc8a0pgTNsw7bLzDzXA0wpeZ6cg4op8YnmROaPamoPFw/bptVSgWSoD3p9AzNeE074nnuMcgCk1nAhC/2Ir1tkuKVmJivxzBPnAhgE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517933; c=relaxed/simple; bh=mJC4O1w2J/M3FPcvGJMNtUaUKMlSqjDOXiDV5TBZZbk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=LRBrnjJ+Tro3GOOArOfwK1Wwbdcuf+V7jxLtrnLaTUf0lIU+ZeXo25deXdV4DdNkkwT+5XXxThifdI69cTs8Dhoz5kLUNPGkPtbsQwyvCHuiLPiXbFaXsfJjP1FH7LEC7AfUiGfU+WxT1I1HFfpkM6NDUGkBOQQ+lsIEWozeNt8= 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=XUkl0Yll; 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="XUkl0Yll" Received: by mail-dy1-f181.google.com with SMTP id 5a478bee46e88-2ba9c484e5eso4156639eec.1 for ; Mon, 06 Apr 2026 16:25:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517931; x=1776122731; 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=QNJDAfopkqTSKFek9BA2OkT2NzzRFpZlW9wrOT8gPH0=; b=XUkl0YlltA7lSsCw+0VE5gPi3T/f32+20ug39ZB77mRBLAeaeTibI0M/wU6I8UHZMn os9YS3TadPLGSem42pR5bq3Yj3j1+Lpx+AOIpC3qwKCtQu38i2IDtZ3rhVr+bXNSESGp xUUh8ZiW+Pgvtb6azKaIyTH2Q/OG/ZBJFi1Rs= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517931; x=1776122731; 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=QNJDAfopkqTSKFek9BA2OkT2NzzRFpZlW9wrOT8gPH0=; b=arWmm9pIIttCHM3/NlPdK7383ZKPUU7ZbLMXQji8HtCIjhvwIQJeliz8FOhMkbSEL5 Ykq4xPTBSfo5IcbwtBCPTP18EHs95FuPFrHqgcdKNPFR9rl+Djze6XxbZpNa/9r8/I7f FvH9ZZt9Ovvu9gLBye7Z3a1iJPXwCkF+Jyh9ciTteEbutiR+1bB4JSAIEPI2B6IO9bX4 HZ68R3yLfuDoTTdnzR96Wbywv9Mtshj6AZew6yqCFbQSNpO5jUzd+a6kTQVS93sc85Dx iBejV2AUV13TvNvganwEkCYvWnO78TSuzNcl9zNfVXy3qIVwPR0wtlXMk9aG4HKgkB0m 1iJg== X-Forwarded-Encrypted: i=1; AJvYcCXU8ApQNSv1BGqafeBIqE9GozUQ7R0lS/Jv5taFNhKR3+JGRgN3EcQBOdegoN7KsNOtossaplQ61xsWWXc=@vger.kernel.org X-Gm-Message-State: AOJu0Yw/oMAg4vZshEieqq0Iv9VSuO2rX9ifq2RuE8+Fh0UcU3otOFW8 z9jf9Ysl+LeWrqBsk5SjQu1Lhs6qXvHWnA01ND9UA+OkOfZqWZFUSDU6yBPcKc2LRw== X-Gm-Gg: AeBDievN2jyC8QexQ0yXCHe0xvxEOuVKSLx7XZqmPqfMDvuVDA4Xlvja+dP/U/zCEca Gs0CRLp5DWgIqDRFszJ+w/5oZ47beq+On9LWc+o9q0bjnhBey3A9T0BxjhKxQzKX4T2PphJkwA8 yqmsI08e4+yaEhkARstVeCrjZxhCKx52lAdG/RoadIwjVWNnaZ1grIhs1rDqGusumPY3ht9xDWd xJBxxJof1I8QBUMoC9M6r9+3c3ZskiAC8y2ZoPwQYnCElcLKne+BbzRobzUMg7OUu16WO8U4srG 5Q5v+zqfO8AosPhena2KMDcynFRBJqgYoqatE/VpqC8reCbRU/aSb2r0NBkgYC7wkDqBg/WKely rwji3CXDFIkgoUzdcHSzVTyJheD2CYAMfVwi/KJlt/j03CO4VXF1eobVrVFfOqpdWXFoaJY12CJ dRqbzs8IuumEhMVz2N4E/Sk7hrgMDLw2gBn6TQfBtre5hiPqTJ5OO+tN8l41HNFveuGExIddmam 47sRsTcjg== X-Received: by 2002:a05:7300:fd05:b0:2c0:d46d:cfc2 with SMTP id 5a478bee46e88-2cbfbe7d5e0mr6829547eec.23.1775517931001; Mon, 06 Apr 2026 16:25:31 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:29 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , Douglas Anderson , driver-core@lists.linux.dev, iommu@lists.linux.dev, joro@8bytes.org, linux-kernel@vger.kernel.org, will@kernel.org Subject: [PATCH v5 3/9] driver core: Replace dev->dma_iommu with dev_dma_iommu() Date: Mon, 6 Apr 2026 16:22:56 -0700 Message-ID: <20260406162231.v5.3.Id20d5973cbff542fea290e13177e9423f5d81342@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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 unnumbered "enum", Greg has requested that the numbers be stable. This also allows us to move one "#ifdef" to an "if", getting better compile-time testing of both sides of the "if". (no changes since v4) 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 38f4316b3cde..620306e8380a 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 #undef __create_dev_flag_accessors =20 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 12:44:34 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 8CCDB3A1E6C for ; Mon, 6 Apr 2026 23:25:34 +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=1775517936; cv=none; b=WGzL04Xvt2MwSbBD4iZJO9T4+PFi+YtPnRLeHGv8ziEfPtC+1mOHoL3/cWSYAZYJKgjaginyy2ziXoXbfsZ3ZJsTkeJ6KAcuQecFCQjuC89o6XExTDjOfCl1ukyyGXKYUD6Km4HkBWZaELxW5Wbd/FUjSqjjiFaYtWVFY1YDnBY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517936; c=relaxed/simple; bh=PJB68tvUBxAGfM8D7po7gDr2ii1Rk0JRq8vNSQIvxbY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=HpOUPz/d2aouE5Oyub6qTvQzAWhysLwWd9oNlTuEtbHM+qgREyC0imr4DSg4UgWTb9CtafWnPe5D48nQbWvBRWdJ8Zv6Ek7sMh/4qX0uLNcfbROD5A8HFoRmpK3J8RprEoUW8mwoJhwwOMMatTJR01yE4fjqt44a8H8gVf72iFk= 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=PyYVjyqi; 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="PyYVjyqi" Received: by mail-dy1-f181.google.com with SMTP id 5a478bee46e88-2ba895adfeaso4769171eec.0 for ; Mon, 06 Apr 2026 16:25:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517934; x=1776122734; 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=QDRSd3siXPnUjKK6z9y9zPLL94slqZupXaMexT4yHSg=; b=PyYVjyqiuwMXq36gLrToILTpzB/0HzdwznAue9aJrTdGfPThrNvWZzLWQGE1oR3DqI f3jwE6E1TZAm6Nl1GlL5vOm+uOdNEMRKxA/1M9U7gK40dssA4Vu5c3uwk7nvdoGwZ2HS CLc62ovU9BJe4Yv71R8nYJF5fkaw9DLrmcL34= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517934; x=1776122734; 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=QDRSd3siXPnUjKK6z9y9zPLL94slqZupXaMexT4yHSg=; b=ZHLKR7LaSdyY6JXb6cZ1MTazQ7d7bERZ+aa/pOdY3+zGtUg0q6QRZeHlpa8cq7jiVH OTvUJ2Bw6s3O1uLGhg6puekRmc5gq+JYqqKU4bFC8CW+ZaKECPcA0F/pbMfpRiZc9ElU CxTuLYK3Gjx7TAFT3+jvFa4q/tx04SPTR/dw9HZ3I5EUIBUauKTO9w8gNgvbrzXGyP0e zMXAggv+k+LTj8XWaBf6n0ieANnWYJNGdhbNcphVOXeORq6v2x6qs3Txqrj4XG16ED6X u83+EIXBUoVm4X4Jlo8F3XlFXMHCP9zp7mhruZ1TuEqp/9e0dqdyMCUgES1RhPQdnjsR NZKA== X-Forwarded-Encrypted: i=1; AJvYcCWg8r+V5PcUAPzLamNKbDPeRdimc/P2WwI03CV9aM3N01FoJUvqFsFc67srSXsa3+5u4DXRZcwO9YvFm4I=@vger.kernel.org X-Gm-Message-State: AOJu0YzSlZ+86fvTfiGUl1RKueVPm8x/5r1ec7g0XFRZKEXiHIWIJm3T 7SGmjdC/jhA0E2YGpD0JJ480CxrhT3kEIygT0V/Vq5r0XXRDe1zZkye0+B+pWAyHRg== X-Gm-Gg: AeBDies9d10uWkB1QOiy6CQCTEjMd3n9G6jQKx0uZerb/uivRHZs3YGogqJJyKVz/OV sMhHhC4rm5fqyYYNFKG/zqJdqbYg8k7ZOCf+/b7hsUAe1kqlPdZcfX1FQ4c6smX46n4IfHNjwgm 0ExYm/wYj1WD+JWOkI1brfEgeIhDrcfWAEMEBYQXxYDHWbW1jRRDd+mJs1JLmmLpxhsqA1d8Gsv A9KW9n6SPSiRhfu6u7mDQU2Ww/DE3vZYmLjWN9Dv2I+4SaWfcQQ9evrDdGWkreQyTmcqMfOcAxG ZJ/PLVirIUXqWvZLAnYFw6O1h8WFZTxpOQ24JJwfgv381Hd12spGyR2zgLDShvpLi/6oIJE+Oby 4hwKNt82C3p9z5m0bxomBZ/a5WPs+8C88fPUKKJuNFUWJfYQrKBvE2r3xOILQpUZs3rVJA2MoYr obATHOuIs3rCUTN/J9ZpvNBZ/PS57HZpBSUSL51boVY6kvlrvH/kLwtXfFVVnL1e0CQVFJZkveM gH2Kc6Ogw== X-Received: by 2002:a05:693c:2c93:b0:2ca:9b08:e7d2 with SMTP id 5a478bee46e88-2cbfb4a8218mr6499235eec.22.1775517933588; Mon, 06 Apr 2026 16:25:33 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:32 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , 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 v5 4/9] driver core: Replace dev->dma_skip_sync with dev_dma_skip_sync() Date: Mon, 6 Apr 2026 16:22:57 -0700 Message-ID: <20260406162231.v5.4.Icf072aa4184dd86a88fa8ca195b09d1651984000@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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 unnumbered "enum", Greg has requested that the numbers be stable. (no changes since v4) 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 620306e8380a..c38593cf2583 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 #undef __create_dev_flag_accessors =20 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 12:44:34 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 565F83A2541 for ; Mon, 6 Apr 2026 23:25: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=1775517938; cv=none; b=F2Wn0sL4JE542WslflKmn//IVgB+8HrRit1z+6BHXlJbZLBE8NP3uT6Lt1HYtj6y4HRYNQoXPzdJUHU2heFXMLf12VAmxGc5V0bDVnzQVENoMoOaD0Y1ryS2LrilEe2CvJ4iFo/R7RiHASi8yUzl+J1IolhDGOoRFUiR7AVtlIw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517938; c=relaxed/simple; bh=5LVNiArQZYUSI+ZEaYqr74aA326eok+3E4kn/jEWtrU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=PrkFBZn9/fqT0jpETJLfaaKq0VByQLbN0k5d53fxQTMaKlLPYpo+BWc5j5rzPBuiXjw2jT1def6M/aBOwUcSPnNveg3ShnGhqYpYJ6Edd8LgMHJMKCuWODKUJJunLdDl2Y1RoGEfP7pJ5+Zl7KLJo29/C8sNgYDUVO+5ddiZGAk= 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=ayxiZYE8; 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="ayxiZYE8" Received: by mail-dy1-f171.google.com with SMTP id 5a478bee46e88-2cc4c693d59so7789079eec.1 for ; Mon, 06 Apr 2026 16:25:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517936; x=1776122736; 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=QLh8ZGhB5dU98LppXST8xiQJL4Zgmni3hu9P++EXxzM=; b=ayxiZYE8prcgTrXn4YaZL9JwWiWPDr9EdZuFlwZjSQb1kSZu3vOMMi1JvIlkuPoLz9 2nCwkw6hhc8GuQ5GVszq5BYuGb520tWmRBBc9Bbx2Hk1l46b/k3i1qkZr2zB6Fnvu4f7 lCZK1pQEkREjpU3IxSFcA3zdBhbgxF7HpcmXA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517936; x=1776122736; 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=QLh8ZGhB5dU98LppXST8xiQJL4Zgmni3hu9P++EXxzM=; b=QAzXnCxdyTtT1iWhGmzlHaB8BsSBEkI8p4YBUZs/ypKo8suVwIXS5vaeEKdv9TiF/x NdWyB0DJ7sN9vJ8UmL3yFTNTq8TPBrifRH88DqDveUoWVRyHmSOU14TVyRnCeoAbrZ4Y snorO7JkswiRigEikhmTJu54vLm0o+AAQXa9Ywy0PMAj3zZ8Td2gh7pJDtB8AMKzDmYa yPucNDRFrN5hwZjVksP/OG6OeFmzM4M9p/2sNFS/Ct6uQWZ0KGsvvGq6pghRP4U57KGy rFXMAj3xG6/OScg2JBNMBanV1NIPOlG9zpNEdNW03Dv1r6i8zkaSlMSx7tyGqCsSdRw4 kijg== X-Forwarded-Encrypted: i=1; AJvYcCWfI47X9BSDl/1YpSfPi1NrbalEUbKbfjFGRVK7sFebUCgVF1okKqNKcxG9Io6WIfBRO4cZRgNS1JYg1dg=@vger.kernel.org X-Gm-Message-State: AOJu0YzAj4kEjsOK32vgO799mXS1XqRiOw6DKxHMqJJpW+YLp9UKFpcJ K4ExNgtk30AtkOWriJUOB78iObbllza16p+4XDrmD6vnCgb3O9mrQyjUiTl+AUayRw== X-Gm-Gg: AeBDieuvRs5gDO3ugnBEADxEPih8K+EeOMwkJMnRouuozzkvQkVkzpBJYOZI9mbjOTc 0vKK3tpqqn6jGVoKFRO4IbGsrpkYodj1hWOs80/9nxhUeM04iENTXrNj6ZW8l5F8kD51LTQL47G 96KDf2k1QquPxfiJq1QqVgNtoa9Su654Ue4omdczRlAx4o/A/183y28xk18Ra3iFCz+aRRcqQBf 7ZXVLuiLKMLRNFbc+OaPSxUH3x2gZ+vcfqxWkDXjsUssdmQa+L/CAmkaOSuEvzsTL4ykEWOjqOp 8zHlfoYD4RLvO8KrMfonsQakLBaYWCgCmPGVB5vbR43WP4Ni6M+wrQm730/dHZQUOb1lROXKC+A eyHnDkxdocESmPf+ZAGwicy1jerABT9JIBEhd8cGP/8cWWdhgmSy/4RHaTykjbjk8/FPvwIMNxn M5vI+kXfaPE9tT4s3YXeAbkQw9PnLofpVWIojaIV5jAMGJTddG0ALL44KAF3sTl04r+HitPxcL+ IOrA6eb6g== X-Received: by 2002:a05:7300:f190:b0:2c4:ec89:be0 with SMTP id 5a478bee46e88-2cbf9fe1d36mr7655035eec.9.1775517936536; Mon, 06 Apr 2026 16:25:36 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:35 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , 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 v5 5/9] driver core: Replace dev->dma_ops_bypass with dev_dma_ops_bypass() Date: Mon, 6 Apr 2026 16:22:58 -0700 Message-ID: <20260406162231.v5.5.If62b84471ef2c85e7ad250f0468867d6dba965ab@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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 unnumbered "enum", Greg has requested that the numbers be stable. This also allows us to move one "#ifdef" to an "if", getting better compile-time testing of both sides of the "if". (no changes since v4) 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 c38593cf2583..1c43ff695e83 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 #undef __create_dev_flag_accessors =20 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 12:44:34 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 45E403A2561 for ; Mon, 6 Apr 2026 23:25:40 +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=1775517941; cv=none; b=ohbIJPWj+r7q6m1TjXUNdknCy52E9IYRdtwzsQP+TssptHKHzq/iWtXTodh2od3LYdgk/NdxI7BuAsJ/Ah39exT9hPCX/juXscIa8baFBh28B5BsSf+a5TjNwyUOhWCyu8Yd5YmRWibw0VR//IBBADZMmpLK/slO6NenF65xfzY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517941; c=relaxed/simple; bh=cp1k4PYAVtmRCQrxYc1pt9qs6gRNOi0JlUXRBqpNf+A=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I/lSfmY/X+7WzXjE9x7k21K7OdJE9vE83GfBqWyD4EI3UOrIjJhAy4nxuDflUZRP/ZKWf0ykHNFJUKUfZTFrD0ufH8HXEwIWeAKUv/IbOppVq6GeSVJooxfkxuZuUgVgI1fVycFXQMqGhP/Ion1O4Nv21c2Gkb8vVZts+w1BtdY= 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=TyLP7DwP; 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="TyLP7DwP" Received: by mail-dy1-f169.google.com with SMTP id 5a478bee46e88-2ba895adfeaso4769222eec.0 for ; Mon, 06 Apr 2026 16:25:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517939; x=1776122739; 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=KZmSYewuETJxw2Oo6JV9qDD2uOkf0pMYDKKz9xaL9LQ=; b=TyLP7DwPdKBH7swDIBqdCXN9pV3q0caYRx6gofj7PAL7Tqv3NMIgrN5Ur8LTDJZrFy QSNqJWb7+s1/TFifxBB4GZfqkvmxffTK0+8CL4dutHnKztzfvNf3jhjwabZanjKzviWa j2T4tVYUSvEZ9dF2ZIHRoIDWGDUV9LwAHNeIw= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517939; x=1776122739; 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=KZmSYewuETJxw2Oo6JV9qDD2uOkf0pMYDKKz9xaL9LQ=; b=VBmvcuGC5FLdqq1kvHYeNrB1Yz+oWlovm3tKteL+UHbVhFiB05ZjnZzhoOBXBicrlA We1PKgVQQ9x5LeADJhbpIyTe3mrkefaGY5ohH46ZMN3INoNx5mbKh7VtirwKTGpJYBP5 JTVzzzuwNp3EFWJY/DRMkGZJfMk+f58jOy/aR9E033i83gbcfvWubBjaoYNl9SVNwWEm 0sUKJ7amjkurAgY6oXVzg/tWeFJvrFmTSpVET7/ohp39v1QZvYVJRuTRl3E+ZLEkIwvr hLXF6kML2eR8ryDJl1AWBM9oK6qUVO1xF5CrKIgYYn5dlzMFJHmKPNgktb69mguv6Iuy QuHg== X-Forwarded-Encrypted: i=1; AJvYcCVPfjtG8cGyckMa0odTZZAP4mfaG6ttwfD9klU3Xy1aQb5Syn4VAAO7TcfPunqWd63sHmlKvry6MM132rY=@vger.kernel.org X-Gm-Message-State: AOJu0YxKWiytLXKP+AI+0vXH7++Vj0vE3hkQrtBXk1B1E7jFtlrUWFHX NSlILkovGnFO7BG1JBK/oHWokdW5FnIfmzjA/bNZNa3+eGyP+FCYE0+oZ1D/DXyIuQ== X-Gm-Gg: AeBDieuLnawDeIXPt/WQoisnDlirjVv45e4kN6jtiuEQCwNTfqhvLFLa3d548WmJW2B yRKifD5mNlSBlAUFvfxohMQD68BAn/fNfEuO2bninIxmlZJyWhBB0gO2XTsY3qyAHZGmZJ93l+n rty6p1Qhv3BQ70gc9Oj5uaAtR4MI64ELs7Ll6WeSimFevAagqnzPD4f5JBhXF0gRmFAPlwTgF/Z Hp6ETDw3IkG3S3zK5NX7i+niX/X3JCikbpp3U1ewbnRjr3DlIO8mSUrEUcD5kBcl2j6H61rINAS 0O2UgNGWBCQjUE1yMboWAUpOgM+DAMy7PTgGIoKwpYlYjCdgZ4smRNH9O0eeJpumAD9BARzgRRp vP9wCpwZfBvp8oNDbt22zjm+lT2vXPoY7Lv+rZiP/cJhQRyP8YD2jYSfg23gRqxN4BGylv4Tkkn IMX28Bl6AfQb5inrYbxcXZmJqkGradl4mjzc9gttuYCFiGFJblBBXR8ttALaolOzOxHN38b1EBc gXWDgz3/g== X-Received: by 2002:a05:7300:214d:b0:2c4:c4ef:48f7 with SMTP id 5a478bee46e88-2cbf9afd2e8mr7475964eec.11.1775517939476; Mon, 06 Apr 2026 16:25:39 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:37 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , Douglas Anderson , driver-core@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH v5 6/9] driver core: Replace dev->state_synced with dev_state_synced() Date: Mon, 6 Apr 2026 16:22:59 -0700 Message-ID: <20260406162231.v5.6.Idb4818e1159fef104c7756bfd6e7ba8f374bebcd@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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). (no changes since v4) 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 db5aec9e6a2b..e94749092345 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 70fa0b13e74f..067a06edd6bc 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 1c43ff695e83..b7a8b902efb3 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 #undef __create_dev_flag_accessors =20 --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 12:44:34 2026 Received: from mail-dy1-f182.google.com (mail-dy1-f182.google.com [74.125.82.182]) (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 467373A4501 for ; Mon, 6 Apr 2026 23:25:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.182 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517946; cv=none; b=rfNU2PKbU05UlkoKAPZc9jV/8D2vDPY2lSUimd4qONLIftDgG2Bs33EgCEVCiZaLTDp2eadC79uvK4s7UgJEDFEc51bHRzUURp3XVvphq/4H6hbhze/45fGGKxbmf8ac8KUXCod5O5SNQkdOMn1gmHcwBWEIOa6g4c315LXjmyQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517946; c=relaxed/simple; bh=WAk3CbC0UCD7Z2dahJaOEqxHzONEBbmkQeRy9YA3MaM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=ddsea7PLo98Sc0q3PR/GBVPFoCjeMfyIlZdxqfLNOxYh506WUF9MlTg83bi2J5DFgFpQskgZJe6b0WtqXCQZimIEvi80GrumYi14pPFqs9UPHMsd2SghM9GRSbeO/cUN/qogo+X7WnXVKAGHCjAQV5LeoqFAKQay2NTKScWX3Sw= 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=ePzKf5w8; arc=none smtp.client-ip=74.125.82.182 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="ePzKf5w8" Received: by mail-dy1-f182.google.com with SMTP id 5a478bee46e88-2bdcf5970cdso3113287eec.0 for ; Mon, 06 Apr 2026 16:25:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517943; x=1776122743; 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=qFmDYcnnDgWKdH7Fx1pvQvOvhn076UMYFbFndXl8P/A=; b=ePzKf5w81yqM7EVF1K5T2ATgEnpdFaj9qeJGNty7kbDCwRJTfCMtdjZ4F2VsZM8z47 8EhfA9BPXlKdzSSzwAG0s8ITVfxlHW3lnOEMEbrRS4qBriB3PQobNPk0ShzsbDcegvP4 BTmCEWs3VyiDihKo0142o06idYEjtjG6sD61U= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517943; x=1776122743; 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=qFmDYcnnDgWKdH7Fx1pvQvOvhn076UMYFbFndXl8P/A=; b=kicSfo7JprmH4UfDioL1eGLv1Sm7vYbfeS7+e1SNZ008pe5sGaKLrUsuG9R9TjYLmw G+5CXqN8ADDGjOsDNNYivz1ei5hP7Artk/hGirh+NEnhRjiFDW4IdHFfP6vHlAByCdSo QBAwxleEjGK9oz+dTfeSjiA3OJnuqe2dodr5DB4QVWRaMhgVE05JzPpVDq0e53E3GEKM HeX5Qit76cOAPbZPB48vfJtqRfV0Lie43keSdiVufuLDJwyptQZ0tcf5FP791B84oCDm 0bWol6zOU9P5wt4B+wAVCoS/1JyQzwL3sHuIqgvpSjS6dM5skVt1PgZrKMKa9jW/XMoO Vy6g== X-Forwarded-Encrypted: i=1; AJvYcCXX3ezJ/iqs3R8cvC7vVy6D9EFLHaBFUWlggFC4U1JBH/SUxRDiH5IcTSLo8VKnaXh3aVGvTJETx7K2y8I=@vger.kernel.org X-Gm-Message-State: AOJu0YxY7K9vfFV2L/mk8J01ZjCanHNWxOPZq2QDv7Rhg7y4zwyRp7ov r9DDBwlg0ly4aVXTTFmAaR6Jj1lS3H8g9cHxK9+NKwVXANSvVyqlaPzC4D9+C6vQ2g== X-Gm-Gg: AeBDiestyVAoXib7RSPDVF3nisxl9PiGd90kKQihNEg54fhxXIGiLWrdbttZrYRln0S d6noZq6JCbYTNoIKX4k17V4GunNQyayNG62eMsBVQmx8exOkBy3PVOv5af7wlRrI7TVBSn/8+/W Wa5FEaA2yHn9cOvtxlhqganXlOHxStYiiun1Y9eQVwdS8u7NSCfodljZahbbAiMA02ZviTjh1i3 AEkzy/lQPGukSxsgQxq9mgrteCNVHUC/BocO+AlBih/LS9KSqzjiqsjYRY/pPT5cyLICYsAkiZb fq7QiwgK3UU9jOW5uyuxG3x3ACws0A4niUqzDhEwcagR0EGJ601jF7xGf76wRX+reIRC7XIQIax 5Cq4U3sldJRUyFclWOULL9ZGefhbgwCnUsZ8q4ivLUzlKkC15Y9ht8R29pq5j6bhpq1rxHOfaCX QwjYYLbykswpcwO4TZDAISQ0LAeSZGb136wllSUD8zz69HYUfQbbgf9HcwTs1UcrwzNZgrMJBHa M9D6g+8scBy/E1nZ/vN X-Received: by 2002:a05:693c:300c:b0:2be:acac:af7f with SMTP id 5a478bee46e88-2cad6ab1abfmr6524179eec.7.1775517943447; Mon, 06 Apr 2026 16:25:43 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:41 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , Douglas Anderson , Vinod Koul , 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, will@kernel.org, willy@infradead.org Subject: [PATCH v5 7/9] driver core: Replace dev->dma_coherent with dev_dma_coherent() Date: Mon, 6 Apr 2026 16:23:00 -0700 Message-ID: <20260406162231.v5.7.If839f6dde98979fce177f70c6c74689a1904ee76@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Acked-by: Vinod Koul Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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 unnumbered "enum", Greg has requested that the numbers be stable. (no changes since v4) 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 e94749092345..8a83d7c93361 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 b7a8b902efb3..5b0fb6ad4c72 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 #undef __create_dev_flag_accessors =20 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 12:44:34 2026 Received: from mail-dy1-f170.google.com (mail-dy1-f170.google.com [74.125.82.170]) (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 BB75239FCB3 for ; Mon, 6 Apr 2026 23:25:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517949; cv=none; b=uN/710i6nhadEaE1IFqiQsPMkZRKa2aQUwH/vR7ixirfvXRRaVMAPtwBfYy/EvxaIETjFT4W106fdY+7D3raXIKOP6tqIHJ4JkGEWMlV/beUNeQopJ9zIdusCk9CDGdVG3ohOs0EYIhPkDSZOsB5RYUHqZlHww7HtBlAdAcEqek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517949; c=relaxed/simple; bh=kgo7+tn7FqDsnpfbKnuGSr61urHWHNTfJ40eKm7zWco=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=dDfAQeOkFO95/KO8IIk+Enx2bYBuqfdANU/0l1lj4u4wG0m2pjissqk03pyC5FF0rcV07cLhJcADXJ5dAEIEBu/UVQ1mdT69lDUD5zgpQX2FAF3BXifT1KtHeHkxo10WqXuHCF6L5MUx4J5+j1MEnJvZRqSXTfy/tIQqpg9fhMs= 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=SMQiZSS3; arc=none smtp.client-ip=74.125.82.170 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="SMQiZSS3" Received: by mail-dy1-f170.google.com with SMTP id 5a478bee46e88-2ba9c484e5eso4156995eec.1 for ; Mon, 06 Apr 2026 16:25:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517947; x=1776122747; 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=ZXh4AAlJDAdDMt/mfgmqe7SUyEdUcOFGra/HATmG4Zg=; b=SMQiZSS3ht5byTaZIo0i2plCJcpewj70ZfE/ar/JOrwvnURW91fPF/25aif3jiZdK+ XGWnScxkRjSOqArNPwNHAV2DE9ozZsQicDtkRvm9T3Ub78Pq+3q+4UMHfXq1S9X/GklN 3BJMz8Y8W+E64rSy8qeNYneBQ0MVppXnXO6/0= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517947; x=1776122747; 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=ZXh4AAlJDAdDMt/mfgmqe7SUyEdUcOFGra/HATmG4Zg=; b=ToFrA5sOo289I0klmp9KNNFBoJtFgpuzcr7MQip1pJgCJ9pTGi+acmfYz9nyfimNUU DTIUUxvVUh9YZj/B1B62SIAUff9G8ypPSSdBpre1nT/lbqCQRrd+mvkDNbadqJvJCqwR CqQfAf2UmKOt4Sr1Z5uoxqpzsAdQxdvcUglsHFVHs4OUfhIt8ORGs0SOS9tDsbRAqNia RXmMBQhIvkr6Sn78JgWZkdTF9+Bpk8uKX7lQjX3JB23iXIy6ecYMT42ngAIUXM8BqQhU CtQ9QCi7TIhmHeSk0dhnSvvKtBByJZOZARrZWpsCLnpPVbj052giT5WeWTFJ+RuKzNpJ VbeQ== X-Forwarded-Encrypted: i=1; AJvYcCXzFjisurlcudMcNJUUXDG6EIAZoTc6TJppRRS3ZQH4pqbw2Izq1ug2IBas8UOtd0muNLNzrBF9ob0Sc5Y=@vger.kernel.org X-Gm-Message-State: AOJu0YweXyYQfOQBvroJixSGoC7c+lTpVHLtl4m709ybVAgNMRWk7L0n ZX0BwOC8dHcz17QuTiXw54sw1TirLc5840n0ZeO10XY9RFA0WfgFsi8YUT4Q+vsOGg== X-Gm-Gg: AeBDievXtWkrozgYnAUwc+asNz6jb/tw/x3YeoVLSszMSrEeOGWi1wBbqdssWU3mSo4 RVUKqXZsGvpxDui42OMe6WmN3WOVPg4oe9kCcvfd0jQTVaPif0APHCZLhnAjXyZEjjhZJ4AOXkq 846yOgsCA3sv8NuZHIXual2YQRxqlAtazqY1sOzYV4iJgN5mfg8cxv5DyXxw8hk3kNh9dGF4VlE sDICmB8TRtst/uAQxwTNvUu0IDJqqqKlMws5yBnbcU1++47k8Nl6LjOaoEGQukXNhh0d+l1fKNO BlPd1STi4qgl9LFwCGmLq5HmRw6jpz7qPK+Di4TzupK3yMxLsbbqwEb7PFJlNezKm5VtWFk2e4h Y+pl6PLeWf4Red15ViUnIySIrUeUZfOOP4f8OmoUGFk6Yq77s0HGNDt8cbKu/xnxfEz7AwYRpEW 5bfbZXfR7+WaUxvE0RxEtnJZ3yFNxjM2raltsPK++gP+/dTl35Jq47B2P5tlKpkfRHV23GQOyU+ Z4jUGHyaw== X-Received: by 2002:a05:7300:d509:b0:2c7:2cac:8123 with SMTP id 5a478bee46e88-2cbf99ec1d3mr6819121eec.4.1775517946892; Mon, 06 Apr 2026 16:25:46 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:45 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , Douglas Anderson , Mark Brown , alexander.stein@ew.tq-group.com, andrew@codeconstruct.com.au, andrew@lunn.ch, andriy.shevchenko@linux.intel.com, astewart@tektelic.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 v5 8/9] driver core: Replace dev->of_node_reused with dev_of_node_reused() Date: Mon, 6 Apr 2026 16:23:01 -0700 Message-ID: <20260406162231.v5.8.I806b8636cd3724f6cd1f5e199318ab8694472d90@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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). (no changes since v4) 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 8a83d7c93361..30825bf83234 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -5283,7 +5283,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 5b0fb6ad4c72..a79865a212e9 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 #undef __create_dev_flag_accessors =20 --=20 2.53.0.1213.gd9a14994de-goog From nobody Sun Jun 14 12:44:34 2026 Received: from mail-dy1-f178.google.com (mail-dy1-f178.google.com [74.125.82.178]) (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 4A1C93A4F4B for ; Mon, 6 Apr 2026 23:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517953; cv=none; b=ZsJc91nuFdth5lXzUy6449gMI8/uJWja7qpxRRg836x53n1oNKP5p3PKuA3i+ppGG5jk2oIGDbw9+OgMJKcqE23Q0r+1zByHfaW0q698qEbXWBKoVk25l7Rxq+fC3CAac3lHsYm1f3jP+UGPvftdkUgsKeckCumf9I3NPs5zZyc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1775517953; c=relaxed/simple; bh=b0I8qj0Ipl7MKqQaQMaR84eJuyVB/V4JrKcK0+yi68c=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=o4HWHSjqLnXiIqfDYEl78R+vYIsPTKZNAq9x89kX8VzF4iAnHysTts5HMIrCCShFNR0pMHUSjC+quYu6V0QOyCdTrsnP9MWaCkkKl+y3zLALz4MGUqtqXT48XNTS5/XH2mxvX7PpanxSYlJMGcfKyiEFpuVslVeUeDoGzlHjN8w= 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=jwMpNmnv; arc=none smtp.client-ip=74.125.82.178 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="jwMpNmnv" Received: by mail-dy1-f178.google.com with SMTP id 5a478bee46e88-2c7d8bbad06so9857499eec.1 for ; Mon, 06 Apr 2026 16:25:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; t=1775517950; x=1776122750; 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=+7fxdjSi9+RKgdFwjeRu5DfLfM5rFKPeYpJSBLh/9No=; b=jwMpNmnvKHQkOH0sPXaFax4g/QyYMGxzx+jlyrBE/baPvzc8LMuGi8hcttyDqnxNCR Tpg2uEqtqROaOg8yJaR+yzaE/hDxNws3VqZkeCC2NdCP0vdQ4gWRsX0e/3avxcmx5id4 dHV/WNnvMJ9inBlJcP7RL3SbQ4yraJqFHjvpc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775517950; x=1776122750; 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=+7fxdjSi9+RKgdFwjeRu5DfLfM5rFKPeYpJSBLh/9No=; b=CqjhkecxRkFuhhn0yZ6CyuLCAhAr0LCrbMVODYufw+y2HbOTHUwWGVbMoxnR9w+iSz Mi2kpfAy9EG276nJl0FauJObqAih66fhQ2N6QP9DyCg8/Qzqy5/uVX8RNgnv90QoqHm1 0B/NZwBPOyfqN4iRdVeAnEqv3zDGBEMno8ovIx2Je1DVpz0ewAgmj4bARIAcdSlzBtTV PfYZ6KSM6XOA0BdIYbdAtSn59cA3vAzGYOdQ5FyYIpOgyhiayPCQrKllfm27viCanXEu PX3Nw5+vOBC4H6SWhfJTHZBqFAhg6RzjN2mXH23PoB4igWggVnDOd+LoXouZ032gRtmJ +llg== X-Forwarded-Encrypted: i=1; AJvYcCW6DNJGCKR1rEK4FDLITOyt6haCofW7+iTxDpASwnxLCQayvfcSziK+CIjxjukNa5NB/Nton7um4DXOn68=@vger.kernel.org X-Gm-Message-State: AOJu0Yx3Im2M8TTofdyrS5GS7F5MdbblVelbQoEbaBIUsThbH4blHnsZ O8J6mc+i81QuBguDyfCBGoU0sJ7FbzCDy6GG/zCPaWoSn48K5h0b4wCjvBj8q2C7uA== X-Gm-Gg: AeBDietyvvwW6qrSKGcet6cnjqFlAS35Gw1l8PPxKZbgIDiLuE9okUukUxvyF7WCRmK XvHVsbM3KzwurfJC0x5QlqkxyfDWpMiQWuomzNWAaTktAMi6RDWD30OcWZVTbi7H29gdKJvWak9 E7ywq5xE9pQjWEyvamMaS2CRRxOwK5LhqKQrmOdS1txOa2xirN3WFCQ/knB16CMfJsjnjf7KEK0 ot2JACrhQemhsd7bCiAOyEYj/jTbj+wGABIqSclxUeuHWsoXIMQYg4ne1g593IkjC4alYHXhW7T k+qXE26nC3t/+cyyYusu3MtObp8haeTkg835A6gjrt9If5iclIrLQ2CrXuo/xgHUhyWbs/GK3WO 63W5brM6JaE9vO//pU8iWwgH/qQoo4IyqHcKUojPeTNmE+R9FJXn4YJKghe8MYqXJLq3a+Y7GqV C8mY95rbzV7XPyYCHmsG6/kC8XFI9dmFIgFqcBb6fwnhEkLAQ+lijbH0m9MwmKtNnBz0cpa7ZAa iWyrNNTWQ== X-Received: by 2002:a05:7301:434b:b0:2c8:6361:ab38 with SMTP id 5a478bee46e88-2cbfa5c1258mr7548017eec.15.1775517950390; Mon, 06 Apr 2026 16:25:50 -0700 (PDT) Received: from dianders.sjc.corp.google.com ([2a00:79e0:2e7c:8:c071:3b78:5a5:824a]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-2ca760b0518sm14730975eec.0.2026.04.06.16.25.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 06 Apr 2026 16:25:49 -0700 (PDT) From: Douglas Anderson To: Greg Kroah-Hartman , "Rafael J . Wysocki" , Danilo Krummrich , Alan Stern Cc: Alexey Kardashevskiy , Johan Hovold , Eric Dumazet , Leon Romanovsky , Christoph Hellwig , Robin Murphy , maz@kernel.org, Alexander Lobakin , Saravana Kannan , 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, 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 v5 9/9] driver core: Replace dev->offline + ->offline_disabled with accessors Date: Mon, 6 Apr 2026 16:23:02 -0700 Message-ID: <20260406162231.v5.9.I897d478b4a9361d79cd5073207c1062fd4d0d0e4@changeid> X-Mailer: git-send-email 2.53.0.1213.gd9a14994de-goog In-Reply-To: <20260406232444.3117516-1-dianders@chromium.org> References: <20260406232444.3117516-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 Reviewed-by: Rafael J. Wysocki (Intel) Reviewed-by: Danilo Krummrich Signed-off-by: Douglas Anderson Acked-by: Marek Szyprowski --- 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). (no changes since v4) 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 30825bf83234..4f293aed879a 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; @@ -4180,7 +4180,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 /** @@ -4198,7 +4198,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); @@ -4207,13 +4207,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); } } } @@ -4238,11 +4238,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; @@ -4716,7 +4716,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 a79865a212e9..d695f7537112 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 #undef __create_dev_flag_accessors =20 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