From nobody Fri Oct 10 09:39:03 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 58729247296 for ; Fri, 13 Jun 2025 23:28:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857294; cv=none; b=eDRvZNawOU2MPmSbUlC6PdJTmYKjsGyw98ZrsSRFs0zbGpgXeleDvPMZLzmAj8wnbwDC6+asCjK5sw103RV7hSnpmjmkB9rlmtuiONc++tYp0BPEgUhlVdh2q9j82a4tv4x5nMQW6wdv8poBZilEdiE+a4tgPJ3qmw8hSpagfJ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857294; c=relaxed/simple; bh=6xwBQ8XFSwXpWFSAxeZ7Jy8x94+usvMvfj6eVa6OR6M=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=KFPJYfjheW7f99HDGalqDTKDeTfr7Zwl7u7ZeDAYpPWRFgVe5IhuPf3pEkb9qSpMjJbwH2lH2ine0Qf9rOjEbUGhAKf6mcROafgnvHpfc2UZpC2YgYRP3Xrq+ODx9HBeKokt/xvZgrZbuBxS3aTVx7nEGyCz6B5cjkAsAjeUWQk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=OjEjPeQd; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="OjEjPeQd" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749857292; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Sd5OvAnSvV+D6OhpTlfHjUIhs7V1jSP69SJuBda5Kmc=; b=OjEjPeQdX3s7iPkwdOm74a90Zd4kGva6jAG09fAOZvRBoRhIQ2wrLhrgVzjt1/3+6OLg2v YRzwx0gsAFdPJh30WrNvnP1uUhkDste7coCFF+eybgBrB55m22uW7zdvyJeLKMcWZlKhTt p2Cz/FwnJ2PiXcRNjbGzrK6finJOxyc= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-614-sb4txEUMNx2eJP1DD2mfXQ-1; Fri, 13 Jun 2025 19:28:08 -0400 X-MC-Unique: sb4txEUMNx2eJP1DD2mfXQ-1 X-Mimecast-MFC-AGG-ID: sb4txEUMNx2eJP1DD2mfXQ_1749857286 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id EA41F1956089; Fri, 13 Jun 2025 23:28:05 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.64.52]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7E9EE180045B; Fri, 13 Jun 2025 23:28:01 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, Andreas Hindborg , linux-kernel@vger.kernel.org Cc: Boqun Feng , FUJITA Tomonori , Frederic Weisbecker , Thomas Gleixner , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Miguel Ojeda , Alex Gaynor , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v5 1/7] rust: hrtimer: Document the return value for HrTimerHandle::cancel() Date: Fri, 13 Jun 2025 19:22:22 -0400 Message-ID: <20250613232754.451450-2-lyude@redhat.com> In-Reply-To: <20250613232754.451450-1-lyude@redhat.com> References: <20250613232754.451450-1-lyude@redhat.com> 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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Just a drive-by fix I noticed: we don't actually document what the return value from cancel() does, so do that. Signed-off-by: Lyude Paul Reviewed-by: Andreas Hindborg --- V4: * Reword to "Returns `true` if the timer was running." Signed-off-by: Lyude Paul --- rust/kernel/time/hrtimer.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index 3980a7c5f7dbe..294f257ef5c5a 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -324,6 +324,8 @@ pub unsafe trait HrTimerHandle { /// Note that the timer might be started by a concurrent start operati= on. If /// so, the timer might not be in the **stopped** state when this func= tion /// returns. + /// + /// Returns `true` if the timer was running. fn cancel(&mut self) -> bool; } =20 --=20 2.49.0 From nobody Fri Oct 10 09:39:03 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 DF95928F519 for ; Fri, 13 Jun 2025 23:28:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857304; cv=none; b=l2md86R6105FXRLz3vzdoFkFWVKWyUod1y4JG/63AdNUWBRf2WCwzbEY0l+EayQGNrK0CZ5NV/k0N1/BiFQ5UgzzG6mq1sfacE/HXXcY0qrKTT8jKLufQc2yy/9+nPeCpXMCJ44UwnJV58gztvzu4Z6j8oqeJk2yJ0Ye8O8HH2k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857304; c=relaxed/simple; bh=fdl1OKzYQAE7YT3Kp4/5yTLNL/7t/hg+IwN0mfuOAYo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bULPlHAMkGOUNdA2SqeihqutqwH2gvXXEXlT9g/Qm/7BlQZhSYbHtCfkTNdEUFY7d491+ulYUILlq1QfIYa/mzR9xgDOiFiayBstNMb5NebIKuVEgRcweGu9yRbRUNOwSfwx7khh2qJGL9G2rgo5jW9ZNesdf3Tbjv29Wd/6Jzo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=TJ/dc732; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="TJ/dc732" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749857302; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LKUkOIyLupZQGMWR7eWrjFQ6DyNfCG1TO+h5kHqEwoM=; b=TJ/dc732dpPSjSdeQ9xy8TFPsyPGTNLMrtj3W6dAQC+q7VAiTK3rFnbfPJ6VSnOwfc0eF4 QZTO3/FS6AWIXKXGWQ9AKBDzwDA/CQXfyQyDuvZfe7GvdQQLqM32HxV274EBPWHhfMvhwT ep2q8zGIaHAWo2KzAjt8mWXjBLQIP1o= Received: from mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-212-cJDLvDMNNaatmCaXij-9Vg-1; Fri, 13 Jun 2025 19:28:18 -0400 X-MC-Unique: cJDLvDMNNaatmCaXij-9Vg-1 X-Mimecast-MFC-AGG-ID: cJDLvDMNNaatmCaXij-9Vg_1749857291 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-08.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 46F6418002ED; Fri, 13 Jun 2025 23:28:11 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.64.52]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 53CDD180045B; Fri, 13 Jun 2025 23:28:06 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, Andreas Hindborg , linux-kernel@vger.kernel.org Cc: Boqun Feng , FUJITA Tomonori , Frederic Weisbecker , Thomas Gleixner , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Miguel Ojeda , Alex Gaynor , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v5 2/7] rust: hrtimer: Add HrTimerInstant Date: Fri, 13 Jun 2025 19:22:23 -0400 Message-ID: <20250613232754.451450-3-lyude@redhat.com> In-Reply-To: <20250613232754.451450-1-lyude@redhat.com> References: <20250613232754.451450-1-lyude@redhat.com> 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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Since we want to add HrTimer methods that can accept Instants, we will want to make sure that for each method we are using the correct Clocksource for the given HrTimer. This would get a bit overly-verbose, so add a simple HrTimerInstant type-alias to handle this for us. Signed-off-by: Lyude Paul Reviewed-by: Andreas Hindborg --- rust/kernel/time/hrtimer.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index 294f257ef5c5a..c775d7abdf5ce 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -72,6 +72,11 @@ use core::marker::PhantomData; use pin_init::PinInit; =20 +/// A type-alias to refer to the [`Instant`] for a given `T` from [`HrT= imer`]. +/// +/// Where `C` is the [`ClockSource`] of the [`HrTimer`]. +pub type HrTimerInstant =3D Instant<<>::TimerMode as= HrTimerMode>::Clock>; + /// A timer backed by a C `struct hrtimer`. /// /// # Invariants --=20 2.49.0 From nobody Fri Oct 10 09:39:03 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 3D57028ECF0 for ; Fri, 13 Jun 2025 23:28:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857301; cv=none; b=S8KD/1A8TOjyM/olny/OtvpKf/9O7DC5ywGe8aG09sIDENp2IWmU3YnKtpfsVPhBnHzm+tDPgmJzXJGZKkHjwIRD+Umri5CTX7ypEV3B+FyEHpf5ZUvdhuUDoQNlVuTdWDBmbgEH5Ft7snBTT/0Hm+3h5TT92WeHueqQUI22Nqw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857301; c=relaxed/simple; bh=8XiIjEW6y+FYCoQtlFbJR03Sv5z6zfVq8WvMhyt1wQs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=M3ovxY1zGe5wRMksy4y+k+CPuqjom4b+1df/HQRTU8HZ7pHbbPSe06gjKap5W35vh/yJN43sZ77Brxyfa39jp1C5kjoSxn0+/5TN6thw6Qw+60ji20zCrzoLQCMUJ3nA1tWOnDvdPLdacHlLLFQYsyL10J6IaQ3w2TRpz8s1wsQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=L50PUiA8; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="L50PUiA8" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749857299; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=CaLWenPoKrGEWobEA9tdmUNkYJSHZWMZCQooqzz26nY=; b=L50PUiA8PEqROdb0r20o5bDbPGXP6gUZP89U2b4+x+cFd/Gl94oaM1lcWlquk15uQKYToB pSqCKn5wQYAR90isMx0un5Xamx0MYOFlTMTa2PLIuLjikvd0CPLheX8Rn24OeW1HdGQgWJ Z2GuepRPsyoFHw7LSUX/ZJ69yGzUeSs= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-447-XjnabceyPtqWcpf3NGiW_g-1; Fri, 13 Jun 2025 19:28:17 -0400 X-MC-Unique: XjnabceyPtqWcpf3NGiW_g-1 X-Mimecast-MFC-AGG-ID: XjnabceyPtqWcpf3NGiW_g_1749857295 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BEF501800281; Fri, 13 Jun 2025 23:28:15 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.64.52]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 9ECE5180035C; Fri, 13 Jun 2025 23:28:11 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, Andreas Hindborg , linux-kernel@vger.kernel.org Cc: Boqun Feng , FUJITA Tomonori , Frederic Weisbecker , Thomas Gleixner , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Miguel Ojeda , Alex Gaynor , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v5 3/7] rust: hrtimer: Add HrTimer::raw_forward() and forward() Date: Fri, 13 Jun 2025 19:22:24 -0400 Message-ID: <20250613232754.451450-4-lyude@redhat.com> In-Reply-To: <20250613232754.451450-1-lyude@redhat.com> References: <20250613232754.451450-1-lyude@redhat.com> 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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Within the hrtimer API there are quite a number of functions that can only be safely called from one of two contexts: * When we have exclusive access to the hrtimer and the timer is not active. * When we're within the hrtimer's callback context as it is being executed. This commit adds bindings for hrtimer_forward() for the first such context, along with HrTimer::raw_forward() for later use in implementing the hrtimer_forward() in the latter context. Signed-off-by: Lyude Paul --- V4: * Fix the safety contract for raw_forward() * Require Pin<&mut Self>, not &mut self * Drop incorrect UniquePin example * Rewrite documentation a bit (re: Andreas) Signed-off-by: Lyude Paul --- rust/kernel/time/hrtimer.rs | 48 +++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index c775d7abdf5ce..6fdd54e3328c5 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -168,6 +168,54 @@ pub(crate) unsafe fn raw_cancel(this: *const Self) -> = bool { // handled on the C side. unsafe { bindings::hrtimer_cancel(c_timer_ptr) !=3D 0 } } + + /// Forward the timer expiry for a given timer pointer. + /// + /// # Safety + /// + /// - `self_ptr` must point to a valid `Self`. + /// - The caller must either have exclusive access to the data pointed= at by `self_ptr`, or be + /// within the context of the timer callback. + #[inline] + unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimerInstant, int= erval: Delta) -> u64 + where + T: HasHrTimer, + { + // SAFETY: + // * The C API requirements for this function are fulfilled by our= safety contract. + // * `self_ptr` is guaranteed to point to a valid `Self` via our s= afety contract + unsafe { + bindings::hrtimer_forward( + Self::raw_get(self_ptr), + now.into_nanos(), + interval.into_nanos(), + ) + } + } + + /// Conditionally forward the timer. + /// + /// If the timer expires after `now`, this function does nothing and r= eturns 0. If the timer + /// expired at or before `now`, this function forwards the timer by `i= nterval` until the timer + /// expires after `now` and then returns the number of times the timer= was forwarded by + /// `interval`. + /// + /// This function is mainly useful for timer types which can provide e= xclusive access to the + /// timer when the timer is not running. For forwarding the timer from= within the timer callback + /// context, see [`HrTimerCallbackContext::forward()`]. + /// + /// Returns the number of overruns that occurred as a result of the ti= mer expiry change. + pub fn forward(self: Pin<&mut Self>, now: HrTimerInstant, interval:= Delta) -> u64 + where + T: HasHrTimer, + { + // SAFETY: + // - `raw_forward` does not move `self`. + // - Self is a mutable reference and thus always points to a valid= `HrTimer` + // - The only way that we could hold a mutable reference to `HrTim= er` is if we have + // exclusive access to it - fulfilling the requirements of the C= API. + unsafe { Self::raw_forward(self.get_unchecked_mut(), now, interval= ) } + } } =20 /// Implemented by pointer types that point to structs that contain a [`Hr= Timer`]. --=20 2.49.0 From nobody Fri Oct 10 09:39:03 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 7C2BC28ECF1 for ; Fri, 13 Jun 2025 23:28:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857318; cv=none; b=DAKeeg3Xhiv0TTqBEvYHZhhOttFesDimtYJqv1lwXw3gQEfnLGYXmysIFFGmEo2iEc7a4S22mMOJZRw4K0XGaK25f2pigW3UFEjxYAQIsKaQn+q41o6ZNKEk5TDOeZFtoTmSSiMdSXjTfj1QDIH2ntmjs9rVrLjcQePfh6s/oNw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857318; c=relaxed/simple; bh=eYKubFy57my06rXJeEpLbkh67mTkzxugpHfudvr90uU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=kC+MBV02R3P4mG84EXiasVLcCNDJbIXtfyQSWdBbav/RQJKJ5A6lQJlJjJzFBhWrE6e/AKb66nuno9Yd/Y4AneC8s6qFBgApsejgKyA8fH6t7Dd0UyzeH62pRZMhOm3pAANDi8JS0sYrdQ+t9z9CzcUjrLZPewlG2T3bl+VbZ2A= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=PE1hMfy6; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="PE1hMfy6" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749857315; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=etlQBXLO08PosKFgbiIpCySM3qmuebGti/OeZJnoaIM=; b=PE1hMfy6DHOMelg/5sTHjBgy3z5962j+SrxNv2lCIKveTCzps7uM1io3fOIX4cIg4UeLN3 OT0Ze3bbrmH5ck32v7So07vMozVIPxW7oV176QEugrbfTlNX+Etubwyyovp/66RxuFko02 YAaa/XqtUVLRT/0iS/7Aad0+TzyO3YY= Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-75-tGSaP_ubMFSZdRQdklPZAQ-1; Fri, 13 Jun 2025 19:28:30 -0400 X-MC-Unique: tGSaP_ubMFSZdRQdklPZAQ-1 X-Mimecast-MFC-AGG-ID: tGSaP_ubMFSZdRQdklPZAQ_1749857308 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 1CBFF1800284; Fri, 13 Jun 2025 23:28:28 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.64.52]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id CF7B3180035C; Fri, 13 Jun 2025 23:28:24 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, Andreas Hindborg , linux-kernel@vger.kernel.org Cc: Boqun Feng , FUJITA Tomonori , Frederic Weisbecker , Thomas Gleixner , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Miguel Ojeda , Alex Gaynor , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v5 4/7] rust: hrtimer: Add HrTimerCallbackContext and ::forward() Date: Fri, 13 Jun 2025 19:22:25 -0400 Message-ID: <20250613232754.451450-5-lyude@redhat.com> In-Reply-To: <20250613232754.451450-1-lyude@redhat.com> References: <20250613232754.451450-1-lyude@redhat.com> 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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" With Linux's hrtimer API, there's a number of methods that can only be called in two situations: * When we have exclusive access to the hrtimer and it is not currently active * When we're within the context of an hrtimer callback context This commit handles the second situation and implements hrtimer_forward() support in the context of a timer callback. We do this by introducing a HrTimerCallbackContext type which is provided to users during the RawHrTimerCallback::run() callback, and then add a forward() function to the type. Signed-off-by: Lyude Paul --- V2: * Improve SAFETY comments for HrTimerCallbackContext uses (I forgot to mention that we're within RawHrTimerCallback::run() * Split forward into forward() and raw_forward() since we're going to have two contexts that we can call forward() from now. * Clarify contexts in which certain hrtimer methods can be called. * Make sure that we use a mutable reference for forward() here - just in case :). * Rename interval to duration V3: * Rename duration -back- to interval (now that I actually have read hrtimer_forward's source, interval does make more sense than duration considering the fact we return the number of overruns that occurred according to the given interval). * Rewrite documentation a bit (re: Andreas) Signed-off-by: Lyude Paul --- rust/kernel/time/hrtimer.rs | 62 ++++++++++++++++++++++++++++- rust/kernel/time/hrtimer/arc.rs | 9 ++++- rust/kernel/time/hrtimer/pin.rs | 9 ++++- rust/kernel/time/hrtimer/pin_mut.rs | 12 ++++-- rust/kernel/time/hrtimer/tbox.rs | 9 ++++- 5 files changed, 93 insertions(+), 8 deletions(-) diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index 6fdd54e3328c5..4a8416fbd187d 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -69,7 +69,7 @@ =20 use super::{ClockSource, Delta, Instant}; use crate::{prelude::*, types::Opaque}; -use core::marker::PhantomData; +use core::{marker::PhantomData, ptr::NonNull}; use pin_init::PinInit; =20 /// A type-alias to refer to the [`Instant`] for a given `T` from [`HrT= imer`]. @@ -353,7 +353,10 @@ pub trait HrTimerCallback { type Pointer<'a>: RawHrTimerCallback; =20 /// Called by the timer logic when the timer fires. - fn run(this: as RawHrTimerCallback>::CallbackTarget= <'_>) -> HrTimerRestart + fn run( + this: as RawHrTimerCallback>::CallbackTarget<'_= >, + ctx: HrTimerCallbackContext<'_, T>, + ) -> HrTimerRestart where Self: Sized; } @@ -619,6 +622,61 @@ impl HrTimerMode for RelativePinnedHar= dMode { type Expires =3D Delta; } =20 +/// Privileged smart-pointer for a [`HrTimer`] callback context. +/// +/// Many [`HrTimer`] methods can only be called in two situations: +/// +/// * When the caller has exclusive access to the `HrTimer` and the `HrTim= er` is guaranteed not to +/// be running. +/// * From within the context of an `HrTimer`'s callback method. +/// +/// This type provides access to said methods from within a timer callback= context. +/// +/// # Invariants +/// +/// * The existence of this type means the caller is currently within the = callback for an +/// [`HrTimer`]. +/// * `self.0` always points to a live instance of [`HrTimer`]. +pub struct HrTimerCallbackContext<'a, T>(NonNull>, PhantomData<= &'a ()>); + +impl<'a, T> HrTimerCallbackContext<'a, T> { + /// Create a new [`HrTimerCallbackContext`]. + /// + /// # Safety + /// + /// This function relies on the caller being within the context of a t= imer callback, so it must + /// not be used anywhere except for within implementations of [`RawHrT= imerCallback::run`]. The + /// caller promises that `timer` points to a valid initialized instanc= e of + /// [`bindings::hrtimer`]. + pub(crate) unsafe fn from_raw(timer: *mut HrTimer) -> Self { + // SAFETY: The caller guarantees `timer` is a valid pointer to an = initialized + // `bindings::hrtimer` + Self(unsafe { NonNull::new_unchecked(timer) }, PhantomData) + } + + /// Conditionally forward the timer. + /// + /// If the timer expires after `now`, this function does nothing and r= eturns 0. If the timer + /// expired at or before `now`, this function forwards the timer by `i= nterval` until the timer + /// expires after `now` and then returns the number of times the timer= was forwarded by + /// `interval`. + /// + /// This function is mainly useful for timer types which can provide e= xclusive access to the + /// timer when the timer is not running. For forwarding the timer when= you have exclusive access + /// to the timer, see [`HrTimer::forward()`]. + /// + /// Returns the number of overruns that occurred as a result of the ti= mer expiry change. + pub fn forward(&mut self, now: HrTimerInstant, interval: Delta) -> = u64 + where + T: HasHrTimer, + { + // SAFETY: + // - We are guaranteed to be within the context of a timer callbac= k by our type invariants + // - By our type invariants, `self.0` always points to a valid `Hr= Timer` + unsafe { HrTimer::::raw_forward(self.0.as_ptr(), now, interval)= } + } +} + /// Use to implement the [`HasHrTimer`] trait. /// /// See [`module`] documentation for an example. diff --git a/rust/kernel/time/hrtimer/arc.rs b/rust/kernel/time/hrtimer/arc= .rs index ed490a7a89503..7be82bcb352ac 100644 --- a/rust/kernel/time/hrtimer/arc.rs +++ b/rust/kernel/time/hrtimer/arc.rs @@ -3,6 +3,7 @@ use super::HasHrTimer; use super::HrTimer; use super::HrTimerCallback; +use super::HrTimerCallbackContext; use super::HrTimerHandle; use super::HrTimerMode; use super::HrTimerPointer; @@ -99,6 +100,12 @@ impl RawHrTimerCallback for Arc // allocation from other `Arc` clones. let receiver =3D unsafe { ArcBorrow::from_raw(data_ptr) }; =20 - T::run(receiver).into_c() + // SAFETY: + // - By C API contract `timer_ptr` is the pointer that we passed w= hen queuing the timer, so + // it is a valid pointer to a `HrTimer` embedded in a `T`. + // - We are within `RawHrTimerCallback::run` + let context =3D unsafe { HrTimerCallbackContext::from_raw(timer_pt= r) }; + + T::run(receiver, context).into_c() } } diff --git a/rust/kernel/time/hrtimer/pin.rs b/rust/kernel/time/hrtimer/pin= .rs index 550aad28d987c..a8c6423f7dfd1 100644 --- a/rust/kernel/time/hrtimer/pin.rs +++ b/rust/kernel/time/hrtimer/pin.rs @@ -3,6 +3,7 @@ use super::HasHrTimer; use super::HrTimer; use super::HrTimerCallback; +use super::HrTimerCallbackContext; use super::HrTimerHandle; use super::HrTimerMode; use super::RawHrTimerCallback; @@ -103,6 +104,12 @@ impl<'a, T> RawHrTimerCallback for Pin<&'a T> // here. let receiver_pin =3D unsafe { Pin::new_unchecked(receiver_ref) }; =20 - T::run(receiver_pin).into_c() + // SAFETY: + // - By C API contract `timer_ptr` is the pointer that we passed w= hen queuing the timer, so + // it is a valid pointer to a `HrTimer` embedded in a `T`. + // - We are within `RawHrTimerCallback::run` + let context =3D unsafe { HrTimerCallbackContext::from_raw(timer_pt= r) }; + + T::run(receiver_pin, context).into_c() } } diff --git a/rust/kernel/time/hrtimer/pin_mut.rs b/rust/kernel/time/hrtimer= /pin_mut.rs index bacd3d5d972a3..8da720a0b78fd 100644 --- a/rust/kernel/time/hrtimer/pin_mut.rs +++ b/rust/kernel/time/hrtimer/pin_mut.rs @@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0 =20 use super::{ - HasHrTimer, HrTimer, HrTimerCallback, HrTimerHandle, HrTimerMode, RawH= rTimerCallback, - UnsafeHrTimerPointer, + HasHrTimer, HrTimer, HrTimerCallback, HrTimerCallbackContext, HrTimerH= andle, HrTimerMode, + RawHrTimerCallback, UnsafeHrTimerPointer, }; use core::{marker::PhantomData, pin::Pin, ptr::NonNull}; =20 @@ -107,6 +107,12 @@ impl<'a, T> RawHrTimerCallback for Pin<&'a mut T> // here. let receiver_pin =3D unsafe { Pin::new_unchecked(receiver_ref) }; =20 - T::run(receiver_pin).into_c() + // SAFETY: + // - By C API contract `timer_ptr` is the pointer that we passed w= hen queuing the timer, so + // it is a valid pointer to a `HrTimer` embedded in a `T`. + // - We are within `RawHrTimerCallback::run` + let context =3D unsafe { HrTimerCallbackContext::from_raw(timer_pt= r) }; + + T::run(receiver_pin, context).into_c() } } diff --git a/rust/kernel/time/hrtimer/tbox.rs b/rust/kernel/time/hrtimer/tb= ox.rs index ec08303315f28..aa1ee31a71953 100644 --- a/rust/kernel/time/hrtimer/tbox.rs +++ b/rust/kernel/time/hrtimer/tbox.rs @@ -3,6 +3,7 @@ use super::HasHrTimer; use super::HrTimer; use super::HrTimerCallback; +use super::HrTimerCallbackContext; use super::HrTimerHandle; use super::HrTimerMode; use super::HrTimerPointer; @@ -119,6 +120,12 @@ impl RawHrTimerCallback for Pin> // `data_ptr` exist. let data_mut_ref =3D unsafe { Pin::new_unchecked(&mut *data_ptr) }; =20 - T::run(data_mut_ref).into_c() + // SAFETY: + // - By C API contract `timer_ptr` is the pointer that we passed w= hen queuing the timer, so + // it is a valid pointer to a `HrTimer` embedded in a `T`. + // - We are within `RawHrTimerCallback::run` + let context =3D unsafe { HrTimerCallbackContext::from_raw(timer_pt= r) }; + + T::run(data_mut_ref, context).into_c() } } --=20 2.49.0 From nobody Fri Oct 10 09:39:03 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 3B1B228F514 for ; Fri, 13 Jun 2025 23:28:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857320; cv=none; b=dNzooOyJ/TMFcbSlx+r2Plh6mu8Q2WWVz2g01pbK1Pe/vEYBK5v66pPMXaUqEnE2sD1kTin55yE2DwE6Jd0xZt5TSfZkxaM6xOm0L/85X2uwXliSVp/uxfLmYJx0CYQuliWtJBxHMrbS0yHD9d0EiO7j0bhYimc7qLGMHmu3bpc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857320; c=relaxed/simple; bh=7RUxsgkmSiqHONpj1nEJ1Gf1e7ZN0xexa4L73K0zYI4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aioDDAKA1aR4RPoFwveAvG180CxZKwb5tf4osbLoAnxWD48544S3ABcAhHqEDh9pB0Os53mPU7/zrJZu3NUsiE6fi/UxEXceKoj0tlzz7YY6WVGUrkG9z8TDkvcJz3ZbCjPk0MNEKK7qrQOskqygG801mhZVo6rVdTEUxPW7xsU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=Pfzz9A64; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="Pfzz9A64" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749857317; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=FrTmBS+IzXJqE+9OXrlq6wyWinCr33fBbb4V8i19iNU=; b=Pfzz9A64FDTH3Nt7AhHvO1pc8B61QXQ09HKqeP7HnOGyU29qVI5pl5u2CxR7E08F1d8PK8 MxqD88TMxiEM0zLG5CPRiZBEfFleJajoQ31YU2BV+O3dl6SFGBfYpWqkszaQNIH77fgLd0 j2MLpVYCeNznR06r/IvceYj0GCaZk1c= Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-606-yhNBggBvNGSlVt-iwUNSyQ-1; Fri, 13 Jun 2025 19:28:34 -0400 X-MC-Unique: yhNBggBvNGSlVt-iwUNSyQ-1 X-Mimecast-MFC-AGG-ID: yhNBggBvNGSlVt-iwUNSyQ_1749857311 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 9F5C719560AA; Fri, 13 Jun 2025 23:28:31 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.64.52]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 7FA13180035C; Fri, 13 Jun 2025 23:28:28 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, Andreas Hindborg , linux-kernel@vger.kernel.org Cc: Boqun Feng , FUJITA Tomonori , Frederic Weisbecker , Thomas Gleixner , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Miguel Ojeda , Alex Gaynor , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v5 5/7] rust: time: Add Instant::from_nanos() Date: Fri, 13 Jun 2025 19:22:26 -0400 Message-ID: <20250613232754.451450-6-lyude@redhat.com> In-Reply-To: <20250613232754.451450-1-lyude@redhat.com> References: <20250613232754.451450-1-lyude@redhat.com> 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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" For implementing Rust bindings which can return a point in time. Signed-off-by: Lyude Paul --- V4: * Turn from_nanos() into an unsafe function in order to ensure that we uphold the invariants of Instant V5: * Add debug_assert!() to from_nanos Signed-off-by: Lyude Paul --- rust/kernel/time.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs index 70bd3be0facc0..eed77297d58a6 100644 --- a/rust/kernel/time.rs +++ b/rust/kernel/time.rs @@ -199,6 +199,28 @@ pub fn elapsed(&self) -> Delta { pub(crate) fn into_nanos(self) -> i64 { self.inner } + + /// Create an [`Instant`] from a time duration specified in nano secon= ds. + /// + /// # Panics + /// + /// On debug builds, this function will panic if `nanos` violates our = safety contract. + /// + /// # Safety + /// + /// The caller promises that `nanos` is in the range from 0 to `KTIME_= MAX`. + #[expect(unused)] + #[inline] + pub(crate) unsafe fn from_nanos(nanos: i64) -> Self { + debug_assert!(nanos >=3D 0); + + // INVARIANT: Our safety contract ensures that `nanos` is in the r= ange from 0 to + // `KTIME_MAX`. + Self { + inner: nanos as bindings::ktime_t, + _c: PhantomData, + } + } } =20 impl core::ops::Sub for Instant { --=20 2.49.0 From nobody Fri Oct 10 09:39:03 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (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 2224628EA72 for ; Fri, 13 Jun 2025 23:28:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.133.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857326; cv=none; b=cTbc5uY9rNlN60hbYCRQ9L7EGq2YpGzyM4uYrTgpYPM0VSuRwSt7DGZzotfBOmD/JQF3Cv+p8Aqa4Or12R1wg3jrFsK6GSJJhR7n3hti+oNNFjPm5OgrrFEvbm0qFe5KwryGFSbr5XZmaLYasQNBzPJgkUPKH4AYG1YR+H4WXbs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857326; c=relaxed/simple; bh=l/M1UVzH6GWd3CpAMU3Yz7OGvGlcaM3uAKFWiU0fTLg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=tQcvq1MWq0a/HkoKVrIPL+PL1yABZAYhazrIKWVpwRYqS4WgCCMy2F2sQOSsUOLnL+YNXTRCy7hjXNH+d5O0eYaxmauM4zcyOjiRxzXWIaQzzAgrmvwPf1Qx/QnHc47/Zx48zXVhBpcPZXvXCeSshgt1Zz0pT/NNYeOWDdgdeI4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=JRLXq+7y; arc=none smtp.client-ip=170.10.133.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="JRLXq+7y" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749857323; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QSufGI8KxAD3MnOJ3Xozd5Wl4+LtdDR1VBG6GTMimng=; b=JRLXq+7yVyRw+iq9YjO2U3eEmmKJiF+RS8jyzMfoNoxDOcRDtobsW7XI9lKj3tNjzr3Kfn Ox1X0JIFnFISyrvc8H+yghBbFxfcuHZSUjeKz2QM4AetUDbHHtFMOk1BueCKSNTM8RN9rG nXV2oDKITbX90NzMP/CEWCE33+Eyk2k= Received: from mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-654-aWHPd8MQPk6qTzo0SMQnUA-1; Fri, 13 Jun 2025 19:28:37 -0400 X-MC-Unique: aWHPd8MQPk6qTzo0SMQnUA-1 X-Mimecast-MFC-AGG-ID: aWHPd8MQPk6qTzo0SMQnUA_1749857315 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 508AE195608D; Fri, 13 Jun 2025 23:28:35 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.64.52]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 1A02218002B5; Fri, 13 Jun 2025 23:28:31 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, Andreas Hindborg , linux-kernel@vger.kernel.org Cc: Boqun Feng , FUJITA Tomonori , Frederic Weisbecker , Thomas Gleixner , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Miguel Ojeda , Alex Gaynor , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v5 6/7] rust: hrtimer: Add HrTimer::raw_cb_time() Date: Fri, 13 Jun 2025 19:22:27 -0400 Message-ID: <20250613232754.451450-7-lyude@redhat.com> In-Reply-To: <20250613232754.451450-1-lyude@redhat.com> References: <20250613232754.451450-1-lyude@redhat.com> 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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" This is a simple private unsafe wrapper for retrieving the current time according to the hrtimer_clock_base struct for a given timer. This will be used for implementing functions such as forward_now(), which rely on retrieving the current time from the hrtimer's clock base. Signed-off-by: Lyude Paul --- V2: - Convert safety comment to invariant comment in from_raw() - Add raw_clock_base() and implement clock_base() on HrTimer as well V4: - Drop HrTimerClockBase entirely, reword commit as this is now about adding raw_cb_time() Signed-off-by: Lyude Paul --- rust/kernel/time.rs | 1 - rust/kernel/time/hrtimer.rs | 27 +++++++++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs index eed77297d58a6..27ee78070d72e 100644 --- a/rust/kernel/time.rs +++ b/rust/kernel/time.rs @@ -209,7 +209,6 @@ pub(crate) fn into_nanos(self) -> i64 { /// # Safety /// /// The caller promises that `nanos` is in the range from 0 to `KTIME_= MAX`. - #[expect(unused)] #[inline] pub(crate) unsafe fn from_nanos(nanos: i64) -> Self { debug_assert!(nanos >=3D 0); diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index 4a8416fbd187d..79d86e1099a1e 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -193,6 +193,33 @@ unsafe fn raw_forward(self_ptr: *mut Self, now: HrTime= rInstant, interval: Del } } =20 + /// Retrieve the current time according to the `struct hrtimer_clock_b= ase` for `self_ptr`. + /// + /// # Safety + /// + /// - `self_ptr` must point to a valid `Self`. + /// - The caller must ensure that the `hrtimer_clock_base` cannot poss= ibly change in the context + /// this function is being called in. This means either exclusive ac= cess to `self_ptr` is + /// required, or we must be from within the timer callback context o= f `self_ptr`. + #[expect(unused)] + unsafe fn raw_cb_time(self_ptr: *const Self) -> HrTimerInstant + where + T: HasHrTimer, + { + // SAFETY: We're guaranteed `self_ptr` points to a valid `Self` by= our safety contract. + let clock_base =3D unsafe { (*Self::raw_get(self_ptr)).base }; + + // SAFETY: The C API guarantees that `get_time` is initialized to = a valid function pointer + // for as long as we expose hrtimers to users. + let get_time_fn =3D unsafe { (*clock_base).get_time.unwrap_uncheck= ed() }; + + // SAFETY: + // - get_time_fn() returns a ktime_t, so we're guaranteed its retu= rn value is between `0` + // and `KTIME_MAX`. + // - get_time_fn() itself has no special requirements. + unsafe { Instant::from_nanos(get_time_fn()) } + } + /// Conditionally forward the timer. /// /// If the timer expires after `now`, this function does nothing and r= eturns 0. If the timer --=20 2.49.0 From nobody Fri Oct 10 09:39:03 2025 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (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 3EE1028FA85 for ; Fri, 13 Jun 2025 23:28:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857327; cv=none; b=bShjcxpmC77wlqvAvjYz0S9AGzXktTibuWShTs4OVNJ98GFKlOZuU2Xao9ff2JqjAq6gSzJgOe1WF6AodBsIMA5+09nly3/YJ8YVAFtWBwlP9Wln1ZoIOYRtwHeDPk0/mguM/ow03+Bj5v3tp062YRXdjNfTanULjWCVPHgch6Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1749857327; c=relaxed/simple; bh=n9umnjaNSBSHX0GHX2P8zsGPIAl95NZy7G30H4N3fao=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=qQicsS2ukYPaQKvkc01AFxbGwqRzxNYnT3CLjZXmMw/Gg3AspENzZAxUCxyWOHjtyvcfihJ+AivOxrjVY4OH2HfR2Pv6HSPI+XQwD+HxRTPZ7ERxJquZb9LD0oer/zI8lLk/MSLZx6QK/xM3eaE61voykUh1SEgoxODi7dY2vqk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com; spf=pass smtp.mailfrom=redhat.com; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b=N5HvLscj; arc=none smtp.client-ip=170.10.129.124 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=redhat.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=redhat.com header.i=@redhat.com header.b="N5HvLscj" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1749857325; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vE7a8Rvyx3n5Nss6xlhGQkT2GVTsPwwys36P7pqKvnI=; b=N5HvLscj34efZp/ucvB45+PyLRUCeWyIn8HHhsp+pswXjxhYr1SeBK7OKp3U4kf0Wt9zpe rhIFs+OlfHPXYD5Bshhph1NHiNsBIehM2pVLqlDIbMtfg+GhJrt3T4IjJC7hsqfFm3i0MQ qCkBNt/SEDAMILLjeBf3Zy7CXprT2Kc= Received: from mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-557-HS3fditTOY6RYgI0mO9AuA-1; Fri, 13 Jun 2025 19:28:42 -0400 X-MC-Unique: HS3fditTOY6RYgI0mO9AuA-1 X-Mimecast-MFC-AGG-ID: HS3fditTOY6RYgI0mO9AuA_1749857320 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D386E195608E; Fri, 13 Jun 2025 23:28:39 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.64.52]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id B4B14180045B; Fri, 13 Jun 2025 23:28:35 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, Andreas Hindborg , linux-kernel@vger.kernel.org Cc: Boqun Feng , FUJITA Tomonori , Frederic Weisbecker , Thomas Gleixner , Anna-Maria Behnsen , John Stultz , Stephen Boyd , Miguel Ojeda , Alex Gaynor , Gary Guo , =?UTF-8?q?Bj=C3=B6rn=20Roy=20Baron?= , Benno Lossin , Alice Ryhl , Trevor Gross , Danilo Krummrich Subject: [PATCH v5 7/7] rust: hrtimer: Add forward_now() to HrTimer and HrTimerCallbackContext Date: Fri, 13 Jun 2025 19:22:28 -0400 Message-ID: <20250613232754.451450-8-lyude@redhat.com> In-Reply-To: <20250613232754.451450-1-lyude@redhat.com> References: <20250613232754.451450-1-lyude@redhat.com> 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 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Content-Type: text/plain; charset="utf-8" Using the HrTimer::raw_time_cb() function, we can now add an equivalent to hrtimer_forward_now() to both HrTimer and HrTimerCallbackContext. Signed-off-by: Lyude Paul --- V2: * Change from Ktime to Delta * Make sure that forward_now() takes a mutable reference to the timer struct * Reword this to point out that we're adding forward_now() to both callback context and mutable timer reference * Rename interval to duration V4: * Fix rust documentation for HrTimerCallbackContext (forgot to update both forward_now() declarations) * Use Pin<&mut Self> for context-less forward. Signed-off-by: Lyude Paul --- rust/kernel/time/hrtimer.rs | 58 ++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/rust/kernel/time/hrtimer.rs b/rust/kernel/time/hrtimer.rs index 79d86e1099a1e..0908359b0550a 100644 --- a/rust/kernel/time/hrtimer.rs +++ b/rust/kernel/time/hrtimer.rs @@ -201,7 +201,6 @@ unsafe fn raw_forward(self_ptr: *mut Self, now: HrTimer= Instant, interval: Del /// - The caller must ensure that the `hrtimer_clock_base` cannot poss= ibly change in the context /// this function is being called in. This means either exclusive ac= cess to `self_ptr` is /// required, or we must be from within the timer callback context o= f `self_ptr`. - #[expect(unused)] unsafe fn raw_cb_time(self_ptr: *const Self) -> HrTimerInstant where T: HasHrTimer, @@ -243,6 +242,44 @@ pub fn forward(self: Pin<&mut Self>, now: HrTimerInsta= nt, interval: Delta) -> // exclusive access to it - fulfilling the requirements of the C= API. unsafe { Self::raw_forward(self.get_unchecked_mut(), now, interval= ) } } + + /// Conditionally forward the timer. + /// + /// This is a variant of [`forward()`](Self::forward) that uses an int= erval after the current + /// time of the base clock for the [`HrTimer`]. + pub fn forward_now(self: Pin<&mut Self>, interval: Delta) -> u64 + where + T: HasHrTimer, + { + // SAFETY: `self` is a mutable reference, guaranteeing it is both = a valid pointer to Self + // and that we also have exclusive access to `self`. + let now =3D unsafe { Self::raw_cb_time(&*self.as_ref()) }; + + self.forward(now, interval) + } + + /// Return the time expiry for this [`HrTimer`]. + /// + /// This value should only be used as a snapshot, as the actual expiry= time could change after + /// this function is called. + pub fn expires(&self) -> HrTimerInstant + where + T: HasHrTimer, + { + // SAFETY: `self` is an immutable reference and thus always points= to a valid `HrTimer`. + let c_timer_ptr =3D unsafe { HrTimer::raw_get(self) }; + + // SAFETY: + // - `node.expires` is a ktime_t, so it must be within the range o= f `0` to `KTIME_MAX`. + // - There's no actual locking here, a racy read is fine and expec= ted + unsafe { + Instant::from_nanos( + // This `read_volatile` is intended to correspond to a REA= D_ONCE call. + // FIXME(read_once): Replace with `read_once` when availab= le on the Rust side. + core::ptr::read_volatile(&raw const ((*c_timer_ptr).node.e= xpires)), + ) + } + } } =20 /// Implemented by pointer types that point to structs that contain a [`Hr= Timer`]. @@ -702,6 +739,25 @@ pub fn forward(&mut self, now: HrTimerInstant, inte= rval: Delta) -> u64 // - By our type invariants, `self.0` always points to a valid `Hr= Timer` unsafe { HrTimer::::raw_forward(self.0.as_ptr(), now, interval)= } } + + /// Conditionally forward the timer. + /// + /// This is a variant of [`HrTimerCallbackContext::forward()`] that us= es an interval after the + /// current time of the base clock for the [`HrTimer`]. + pub fn forward_now(&mut self, duration: Delta) -> u64 + where + T: HasHrTimer, + { + self.forward( + // SAFETY: + // - We're guaranteed `self.0` points to a valid `HrTimer` = instance by type + // invariants. + // - We're guaranteed to be within the context of the timer ca= llback by our type + // invariants. + unsafe { HrTimer::::raw_cb_time(self.0.as_ptr()) }, + duration, + ) + } } =20 /// Use to implement the [`HasHrTimer`] trait. --=20 2.49.0