From nobody Sat Oct 4 04:59:52 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 7951B2D3EDE for ; Wed, 20 Aug 2025 20:37:30 +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=1755722252; cv=none; b=tMyEUW/6aSm8rplqZlzJvOg8L+vTl6jv4rKSkXsotSDOoFSS4XNV3lAwh+99yxWCtSoOOR0zmqsVXebCIhp+6JfJzwQHZVPzlQcsI0KLi4Lh9oeYnqoH/uOlxEo8O9CbpkHIfygsa6CuLVTSe2hfDRiNblHb75Gv7hEIu82V7dg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1755722252; c=relaxed/simple; bh=5124OcJB0LjDSkPH9HDI5nlX3yMOglKE0+T90eM7zpU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=neH3wIGn1PBAOT4v2u6Q6DsTXh5GTR+rqHeaIPN/dMhYy4qLZqbAbXXXDvj+T8ibjgHTyHVdbFeHCUuxfQYG6YxgRAg7ponwpQwtBz/RUa6OYM3dC9lF3sta3y+MtRyU+arBd4yDtff9gHHDfKq87xpjACAosgwg1f9m8y4795g= 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=SOo/8yz2; 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="SOo/8yz2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1755722249; 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=T3qJccqSG1utm0kjz6SVdgEmigmg25RGxr25fQrvr/M=; b=SOo/8yz2ifS5oikYTX0gB2XZMuZJwQ5RpRftzjbk7xtTMhNHSiv6M3J7BM0NbDaYucD+qc F6SoCrtR3rZv2g6tHpeD4osRgfTGT6cEJUkQZzivo02lt4S6Bwz9y7/THuBhNVMnTGHl3Z 2MImC6HAQo9hAc0q9xVNwIlnFnePJV8= Received: from mx-prod-mc-01.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-321-U5-hFK5vM--L5qJweO_9KA-1; Wed, 20 Aug 2025 16:37:26 -0400 X-MC-Unique: U5-hFK5vM--L5qJweO_9KA-1 X-Mimecast-MFC-AGG-ID: U5-hFK5vM--L5qJweO_9KA_1755722243 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 72141195422A; Wed, 20 Aug 2025 20:37:23 +0000 (UTC) Received: from chopper.redhat.com (unknown [10.22.81.238]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 0E30819A4C99; Wed, 20 Aug 2025 20:37:19 +0000 (UTC) From: Lyude Paul To: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, Thomas Gleixner , Andreas Hindborg , FUJITA Tomonori Cc: Boqun Feng , Frederic Weisbecker , 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 v3 2/2] rust: time: Implement basic arithmetic operations for Delta Date: Wed, 20 Aug 2025 16:26:44 -0400 Message-ID: <20250820203704.731588-3-lyude@redhat.com> In-Reply-To: <20250820203704.731588-1-lyude@redhat.com> References: <20250820203704.731588-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.0 on 10.30.177.17 Content-Type: text/plain; charset="utf-8" While rvkms is only going to be using a few of these, since Deltas are basically the same as i64 it's easy enough to just implement all of the basic arithmetic operations for Delta types. Keep in mind there's one quirk here - the kernel has no support for i64 % i64 on 32 bit platforms, the closest we have is i64 % i32 through div_s64_rem(). So, instead of implementing ops::Rem or ops::RemAssign we simply provide Delta::rem_nanos(). Signed-off-by: Lyude Paul Reviewed-by: Andreas Hindborg Reviewed-by: Daniel Almeida Reviewed-by: FUJITA Tomonori --- V2: * Don't forget to make sure that we inline all of these * Drop ops::Rem and ops::RemAssign implementations for Delta, replace with Delta::rem_nanos() instead. It turns out that there's actually no way to perform i64 % i64 on 32 bit platforms in the kernel at the moment, the closest that we have is div_s64_rem() which only allows a 32 bit divisor. * Actually use the kernel arithmetic helpers for division/remainders so that this code works on both 32 and 64 bit platforms. V3: * Change the output type for Div to i64, drop DivAssign * Change Mul/MulAssign to accept i64, not another Delta * Fix parameter name in rem_nanos (ns -> dividend) rust/kernel/time.rs | 98 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs index 4bd7a8a009f3e..e64c5b13152dd 100644 --- a/rust/kernel/time.rs +++ b/rust/kernel/time.rs @@ -265,6 +265,78 @@ pub struct Delta { nanos: i64, } =20 +impl ops::Add for Delta { + type Output =3D Self; + + #[inline] + fn add(self, rhs: Self) -> Self { + Self { + nanos: self.nanos + rhs.nanos, + } + } +} + +impl ops::AddAssign for Delta { + #[inline] + fn add_assign(&mut self, rhs: Self) { + self.nanos +=3D rhs.nanos; + } +} + +impl ops::Sub for Delta { + type Output =3D Self; + + #[inline] + fn sub(self, rhs: Self) -> Self::Output { + Self { + nanos: self.nanos - rhs.nanos, + } + } +} + +impl ops::SubAssign for Delta { + #[inline] + fn sub_assign(&mut self, rhs: Self) { + self.nanos -=3D rhs.nanos; + } +} + +impl ops::Mul for Delta { + type Output =3D Self; + + #[inline] + fn mul(self, rhs: i64) -> Self::Output { + Self { + nanos: self.nanos * rhs, + } + } +} + +impl ops::MulAssign for Delta { + #[inline] + fn mul_assign(&mut self, rhs: i64) { + self.nanos *=3D rhs; + } +} + +impl ops::Div for Delta { + type Output =3D i64; + + #[inline] + fn div(self, rhs: Self) -> Self::Output { + #[cfg(CONFIG_64BIT)] + { + self.nanos / rhs.nanos + } + + #[cfg(not(CONFIG_64BIT))] + { + // SAFETY: This function is always safe to call regardless of = the input values + unsafe { bindings::div64_s64(self.nanos, rhs.nanos) } + } + } +} + impl Delta { /// A span of time equal to zero. pub const ZERO: Self =3D Self { nanos: 0 }; @@ -353,4 +425,30 @@ pub fn as_millis(self) -> i64 { bindings::ktime_to_ms(self.as_nanos()) } } + + /// Return `self % dividend` where `dividend` is in nanoseconds. + /// + /// The kernel doesn't have any emulation for `s64 % s64` on 32 bit pl= atforms, so this is + /// limited to 32 bit dividends. + #[inline] + pub fn rem_nanos(self, dividend: i32) -> Self { + #[cfg(CONFIG_64BIT)] + { + Self { + nanos: self.as_nanos() % i64::from(dividend), + } + } + + #[cfg(not(CONFIG_64BIT))] + { + let mut rem =3D 0; + + // SAFETY: `rem` is in the stack, so we can always provide a v= alid pointer to it. + unsafe { bindings::div_s64_rem(self.as_nanos(), dividend, &mut= rem) }; + + Self { + nanos: i64::from(rem), + } + } + } } --=20 2.50.0