diff mbox series

[net-next,v2,1/6] rust: time: Implement PartialEq and PartialOrd for Ktime

Message ID 20241005122531.20298-2-fujita.tomonori@gmail.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series rust: Add IO polling | expand

Checks

Context Check Description
netdev/series_format success Posting correctly formatted
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 6 this patch: 6
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers warning 1 maintainers not CCed: boqun.feng@gmail.com
netdev/build_clang success Errors and warnings before: 7 this patch: 7
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 39 this patch: 40
netdev/checkpatch warning WARNING: added, moved or deleted file(s), does MAINTAINERS need updating?
netdev/build_clang_rust success Errors and warnings before: 4 this patch: 4
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

FUJITA Tomonori Oct. 5, 2024, 12:25 p.m. UTC
Implement PartialEq and PartialOrd trait for Ktime by using C's
ktime_compare function so two Ktime instances can be compared to
determine whether a timeout is met or not.

Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
---
 rust/helpers/helpers.c |  1 +
 rust/helpers/time.c    |  8 ++++++++
 rust/kernel/time.rs    | 22 ++++++++++++++++++++++
 3 files changed, 31 insertions(+)
 create mode 100644 rust/helpers/time.c

Comments

Fiona Behrens Oct. 6, 2024, 10:28 a.m. UTC | #1
On 5 Oct 2024, at 14:25, FUJITA Tomonori wrote:

> Implement PartialEq and PartialOrd trait for Ktime by using C's
> ktime_compare function so two Ktime instances can be compared to
> determine whether a timeout is met or not.

Why is this only PartialEq/PartialOrd? Could we either document why or implement Eq/Ord as well?

>
> Signed-off-by: FUJITA Tomonori <fujita.tomonori@gmail.com>
> ---
>  rust/helpers/helpers.c |  1 +
>  rust/helpers/time.c    |  8 ++++++++
>  rust/kernel/time.rs    | 22 ++++++++++++++++++++++
>  3 files changed, 31 insertions(+)
>  create mode 100644 rust/helpers/time.c
>
> diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
> index 30f40149f3a9..c274546bcf78 100644
> --- a/rust/helpers/helpers.c
> +++ b/rust/helpers/helpers.c
> @@ -21,6 +21,7 @@
>  #include "slab.c"
>  #include "spinlock.c"
>  #include "task.c"
> +#include "time.c"
>  #include "uaccess.c"
>  #include "wait.c"
>  #include "workqueue.c"
> diff --git a/rust/helpers/time.c b/rust/helpers/time.c
> new file mode 100644
> index 000000000000..d6f61affb2c3
> --- /dev/null
> +++ b/rust/helpers/time.c
> @@ -0,0 +1,8 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/ktime.h>
> +
> +int rust_helper_ktime_compare(const ktime_t cmp1, const ktime_t cmp2)
> +{
> +	return ktime_compare(cmp1, cmp2);
> +}
> diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
> index e3bb5e89f88d..c40105941a2c 100644
> --- a/rust/kernel/time.rs
> +++ b/rust/kernel/time.rs
> @@ -81,3 +81,25 @@ fn sub(self, other: Ktime) -> Ktime {
>          }
>      }
>  }
> +
> +impl PartialEq for Ktime {
> +    #[inline]
> +    fn eq(&self, other: &Self) -> bool {
> +        // SAFETY: FFI call.
> +        let ret = unsafe { bindings::ktime_compare(self.inner, other.inner) };
> +        ret == 0
> +    }
> +}
> +
> +impl PartialOrd for Ktime {
> +    #[inline]
> +    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
> +        // SAFETY: FFI call.
> +        let ret = unsafe { bindings::ktime_compare(self.inner, other.inner) };
> +        match ret {
> +            0 => Some(core::cmp::Ordering::Equal),
> +            x if x < 0 => Some(core::cmp::Ordering::Less),
> +            _ => Some(core::cmp::Ordering::Greater),
> +        }
> +    }
> +}
> -- 
> 2.34.1
FUJITA Tomonori Oct. 7, 2024, 5:37 a.m. UTC | #2
On Sun, 06 Oct 2024 12:28:59 +0200
Fiona Behrens <finn@kloenk.dev> wrote:

>> Implement PartialEq and PartialOrd trait for Ktime by using C's
>> ktime_compare function so two Ktime instances can be compared to
>> determine whether a timeout is met or not.
> 
> Why is this only PartialEq/PartialOrd? Could we either document why or implement Eq/Ord as well?

Because what we need to do is comparing two Ktime instances so we
don't need them?
Fiona Behrens Oct. 7, 2024, 8:28 a.m. UTC | #3
On 7 Oct 2024, at 7:37, FUJITA Tomonori wrote:

> On Sun, 06 Oct 2024 12:28:59 +0200
> Fiona Behrens <finn@kloenk.dev> wrote:
>
>>> Implement PartialEq and PartialOrd trait for Ktime by using C's
>>> ktime_compare function so two Ktime instances can be compared to
>>> determine whether a timeout is met or not.
>>
>> Why is this only PartialEq/PartialOrd? Could we either document why or implement Eq/Ord as well?
>
> Because what we need to do is comparing two Ktime instances so we
> don't need them?

Eq is basically just a marker trait, so you could argue we would never need it. I think because those 2 traits mostly just document logic it would make sense to also implement them to not create rethinking if then there is some logic that might want it and then the question is why was it omitted.

 - Fiona
Alice Ryhl Oct. 7, 2024, 8:41 a.m. UTC | #4
On Mon, Oct 7, 2024 at 7:37 AM FUJITA Tomonori
<fujita.tomonori@gmail.com> wrote:
>
> On Sun, 06 Oct 2024 12:28:59 +0200
> Fiona Behrens <finn@kloenk.dev> wrote:
>
> >> Implement PartialEq and PartialOrd trait for Ktime by using C's
> >> ktime_compare function so two Ktime instances can be compared to
> >> determine whether a timeout is met or not.
> >
> > Why is this only PartialEq/PartialOrd? Could we either document why or implement Eq/Ord as well?
>
> Because what we need to do is comparing two Ktime instances so we
> don't need them?

When you implement PartialEq without Eq, you are telling the reader
that this is a weird type such as floats where there exists values
that are not equal to themselves. That's not the case here, so don't
confuse the reader by leaving out `Eq`.

Alice
FUJITA Tomonori Oct. 7, 2024, 9:29 a.m. UTC | #5
On Mon, 7 Oct 2024 10:41:23 +0200
Alice Ryhl <aliceryhl@google.com> wrote:

>> >> Implement PartialEq and PartialOrd trait for Ktime by using C's
>> >> ktime_compare function so two Ktime instances can be compared to
>> >> determine whether a timeout is met or not.
>> >
>> > Why is this only PartialEq/PartialOrd? Could we either document why or implement Eq/Ord as well?
>>
>> Because what we need to do is comparing two Ktime instances so we
>> don't need them?
> 
> When you implement PartialEq without Eq, you are telling the reader
> that this is a weird type such as floats where there exists values
> that are not equal to themselves. That's not the case here, so don't
> confuse the reader by leaving out `Eq`.

Understood. I'll add Eq/Ord in the next version.
Andrew Lunn Oct. 7, 2024, 1:15 p.m. UTC | #6
On Mon, Oct 07, 2024 at 10:41:23AM +0200, Alice Ryhl wrote:
> On Mon, Oct 7, 2024 at 7:37 AM FUJITA Tomonori
> <fujita.tomonori@gmail.com> wrote:
> >
> > On Sun, 06 Oct 2024 12:28:59 +0200
> > Fiona Behrens <finn@kloenk.dev> wrote:
> >
> > >> Implement PartialEq and PartialOrd trait for Ktime by using C's
> > >> ktime_compare function so two Ktime instances can be compared to
> > >> determine whether a timeout is met or not.
> > >
> > > Why is this only PartialEq/PartialOrd? Could we either document why or implement Eq/Ord as well?
> >
> > Because what we need to do is comparing two Ktime instances so we
> > don't need them?
> 
> When you implement PartialEq without Eq, you are telling the reader
> that this is a weird type such as floats where there exists values
> that are not equal to themselves. That's not the case here, so don't
> confuse the reader by leaving out `Eq`.
 
This might be one of those areas where there needs to be a difference
between C and Rust in terms of kernel rules. For C, there would need
to be a user. Here you seem to be saying the type system needs it, for
the type to be meaningful, even if there is no user?

Without Eq, would the compiler complain on an == operation, saying it
is not a valid operation? Is there a clear difference between nobody
has implemented this yet, vs such an operation is impossible, such as
your float example?

	Andrew
Alice Ryhl Oct. 7, 2024, 1:59 p.m. UTC | #7
On Mon, Oct 7, 2024 at 3:16 PM Andrew Lunn <andrew@lunn.ch> wrote:
>
> On Mon, Oct 07, 2024 at 10:41:23AM +0200, Alice Ryhl wrote:
> > On Mon, Oct 7, 2024 at 7:37 AM FUJITA Tomonori
> > <fujita.tomonori@gmail.com> wrote:
> > >
> > > On Sun, 06 Oct 2024 12:28:59 +0200
> > > Fiona Behrens <finn@kloenk.dev> wrote:
> > >
> > > >> Implement PartialEq and PartialOrd trait for Ktime by using C's
> > > >> ktime_compare function so two Ktime instances can be compared to
> > > >> determine whether a timeout is met or not.
> > > >
> > > > Why is this only PartialEq/PartialOrd? Could we either document why or implement Eq/Ord as well?
> > >
> > > Because what we need to do is comparing two Ktime instances so we
> > > don't need them?
> >
> > When you implement PartialEq without Eq, you are telling the reader
> > that this is a weird type such as floats where there exists values
> > that are not equal to themselves. That's not the case here, so don't
> > confuse the reader by leaving out `Eq`.
>
> This might be one of those areas where there needs to be a difference
> between C and Rust in terms of kernel rules. For C, there would need
> to be a user. Here you seem to be saying the type system needs it, for
> the type to be meaningful, even if there is no user?
>
> Without Eq, would the compiler complain on an == operation, saying it
> is not a valid operation? Is there a clear difference between nobody
> has implemented this yet, vs such an operation is impossible, such as
> your float example?

Think of it this way: I wrote an implementation of something that
works in situations A and B, but I only use it in situation A. Must I
write my program in a way to make it impossible to use it in situation
B? That's how I see this case. Implementing Eq does not involve adding
any new functions.

Alice
diff mbox series

Patch

diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index 30f40149f3a9..c274546bcf78 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -21,6 +21,7 @@ 
 #include "slab.c"
 #include "spinlock.c"
 #include "task.c"
+#include "time.c"
 #include "uaccess.c"
 #include "wait.c"
 #include "workqueue.c"
diff --git a/rust/helpers/time.c b/rust/helpers/time.c
new file mode 100644
index 000000000000..d6f61affb2c3
--- /dev/null
+++ b/rust/helpers/time.c
@@ -0,0 +1,8 @@ 
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/ktime.h>
+
+int rust_helper_ktime_compare(const ktime_t cmp1, const ktime_t cmp2)
+{
+	return ktime_compare(cmp1, cmp2);
+}
diff --git a/rust/kernel/time.rs b/rust/kernel/time.rs
index e3bb5e89f88d..c40105941a2c 100644
--- a/rust/kernel/time.rs
+++ b/rust/kernel/time.rs
@@ -81,3 +81,25 @@  fn sub(self, other: Ktime) -> Ktime {
         }
     }
 }
+
+impl PartialEq for Ktime {
+    #[inline]
+    fn eq(&self, other: &Self) -> bool {
+        // SAFETY: FFI call.
+        let ret = unsafe { bindings::ktime_compare(self.inner, other.inner) };
+        ret == 0
+    }
+}
+
+impl PartialOrd for Ktime {
+    #[inline]
+    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
+        // SAFETY: FFI call.
+        let ret = unsafe { bindings::ktime_compare(self.inner, other.inner) };
+        match ret {
+            0 => Some(core::cmp::Ordering::Equal),
+            x if x < 0 => Some(core::cmp::Ordering::Less),
+            _ => Some(core::cmp::Ordering::Greater),
+        }
+    }
+}