From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 663343A0B08; Wed, 7 Jan 2026 16:40:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767804028; cv=none; b=kPEJHBKt37hRI6/C79A5/VI9XvSNYHo8SvT81NFpIVt+zPpj+eqo4/wgmkd5esS1bwQ/KYQL5HBFjG8ZvG8e8RlWvfC0scUtEoRdJsCMMs2cZMgNH4YpTNykUa1e3kp1U3qpbrVtfAZl1hMWt1PLL0vRcusTWPSYvhbgou2oZBk= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767804028; c=relaxed/simple; bh=z3POv5J4x+meLVYbsQCf7mB/6gWPZ96vXCB8Job/Vvs=; h=Mime-Version:Content-Type:Date:Message-Id:Subject:Cc:To:From: References:In-Reply-To; b=axs/PjgMijKadLf9YG8M733ZFbJO7ro6viyxvbIiZfGtXbWNO+Dxo+M3gLpSoD7FvrxrzLOdGz5HiVrlCqra6wDgLZ8n6OkMwZXxuOvGBJQPpts+XmgxcfhQFaH7IlGMBPsh6AzGPztHLIEB4LVe7+yVyi98OxNQMGA5OYJ230o= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=eWRXAf6v; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="eWRXAf6v" Received: by smtp.kernel.org (Postfix) with ESMTPSA id A99E7C4CEF1; Wed, 7 Jan 2026 16:40:22 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1767804026; bh=z3POv5J4x+meLVYbsQCf7mB/6gWPZ96vXCB8Job/Vvs=; h=Date:Subject:Cc:To:From:References:In-Reply-To:From; b=eWRXAf6v4PEvZFPNQ9MSIq4mhg/lKsxd/ojHLmtL2/9VcVDlrbVbiA6snO1GiXnbT /iNW0LDo1Dz0qk+FFbvfyzNtvX+elFdZITVNrrTvhKVyf/LVuWfqkhsfVQnnYPtiU0 Vnb4F482tZaEa6J/nyNruw4kS+S4lRntIo1DLkfvW7STpDVoBqQARyTGc7zWnmdrb1 o7+QJUM2BvERsQ9+vZbgeOxEiE1VL1Uyg3meBjb3sebKBGMokS+eLWqd2MIVUC4D0C r/1djN+F3ERXtW3oDP2zqj/ApnebxGZ4HqbnDJX7zrf/gMIL7w8/WtL7SVbyuy07tb ptDO8D4095e0A== Precedence: bulk X-Mailing-List: rust-for-linux@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 Date: Wed, 07 Jan 2026 17:40:20 +0100 Message-Id: Subject: Re: [PATCH 0/6] Address race condition with Device::drvdata() Cc: , , , , , , , , , , , , , , , , , , , , To: "Alice Ryhl" From: "Danilo Krummrich" References: <20260107103511.570525-1-dakr@kernel.org> In-Reply-To: On Wed Jan 7, 2026 at 4:51 PM CET, Alice Ryhl wrote: > If a &Device lets you access a given value, then we must not > destroy that value until after the last &Device has expired. > > A &Device lets you access the driver private data. And a > &Device lets you access the contents of a Devres. > > Thus, the last &Device must expire before we destroy driver > private data or values inside of Devres. Etc. Yes, the last &Device must expire before we destroy the device priva= te data. This is exactly what is achieved by this patch. The device private da= ta is destroyed after all devres callbacks have been processed, which guarantees = that there can't be any contexts left that provide a &Device. As for the values inside of a Devres, this is exactly what I refer to in= my paragraph above talking about the unsoundness of the devres cleanup orderin= g in Rust. I also mention that I'm already working on a solution and it is in fact pre= tty close to the solution you propose below, i.e. a generic mechanism to suppor= t multiple devres domains (which I also see advantages for in C code). As mentioned, this will also help with getting the required synchronize_rcu= () calls down to exactly one per device unbind. Technically, we could utilize such a devres domain for dropping the device private data, but there is no need to have a separate domain just for this,= we already have a distinct place for dropping and freeing the device private d= ata after the device has been fully unbound, which is much simpler than a separ= ate devres domain. Now, you may argue we don't need a separate devres domain, and that we coul= d use the non-early devres domain. However, this would have the following implica= tion: In the destructor of the device private data, drivers could still try to us= e device resources stored in the device private data through try_access(), wh= ich may or may not succeed depending on whether the corresponding Devres containers are part of the device private data initializer or whether they = have been allocated separately. Or in other words it would leave room for drivers to abuse this behavior. Therefore, the desired order is: 1. Driver::unbind() (A place for drivers to tear down the device; registrations are up - unless explicitly revoked by the driver (this i= s a semantic choice) - and device resources are accessible.) 2. devm_early_* (Drop all devres guarded registrations.) 3. No more &Device left. 4. devm_* (Drop all device resources.) 5. No more device resources left. 6. Drop and free device private data. (try_access() will never succeed in= the destructor of the device private data. - Danilo