# Meeting 2024-04-03
<!-- Leave your topic starting with ### in the relevant sections below -->
## Critical
<!-- bugs, soundness issues, urgent patches/reviews etc. -->
## Status Reports
<!-- You want to report on something you are working on/request reviews.
Or you want to know the status of something someone else is doing -->
### `syn` & friends in the kernel?
## Discussion Questions
<!-- Anything that requires lengthy discussion/more general questions also fit here -->
### Bikeshedding the name `ForeignBorrowed`
Context:
```text
On 23.03.24 07:32, Andreas Hindborg wrote:
> Benno Lossin <benno.lossin@proton.me> writes:
>> On 3/13/24 12:05, Andreas Hindborg wrote:
>>> +
>>> + /// Data associated with the `struct request_queue` that is allocated for
>>> + /// the `GenDisk` associated with this `Operations` implementation.
>>> + type QueueData: ForeignOwnable;
>>> +
>>> + /// Data associated with a dispatch queue. This is stored as a pointer in
>>> + /// the C `struct blk_mq_hw_ctx` that represents a hardware queue.
>>> + type HwData: ForeignOwnable;
>>> +
>>> + /// Data associated with a `TagSet`. This is stored as a pointer in `struct
>>> + /// blk_mq_tag_set`.
>>> + type TagSetData: ForeignOwnable;
>>> +
>>> + /// Called by the kernel to get an initializer for a `Pin<&mut RequestData>`.
>>> + fn new_request_data(
>>> + //rq: ARef<Request<Self>>,
>>> + tagset_data: <Self::TagSetData as ForeignOwnable>::Borrowed<'_>,
>>
>> Since you need to use this pattern a lot, it might be a good idea to
>> introduce a type alias to help with this:
>>
>> type ForeignBorrowed<'a, T> = <T as ForeignOwnable>::Borrowed<'a>;
>>
>> What do the others think?
>>
>> The function would then become (with the RPITIT improvement as well):
>>
>> fn new_request_data(
>> //rq: ARef<Request<Self>>,
>> tagset_data: ForeignBorrowed<'_, Self::TagSetData>,
>> ) -> impl PinInit<Self::RequestData>;
>
> A bit more concise, I think it is better. I'll go ahead and kill that
> commented out argument that sneaked into the patch as well :)
```
I just picked `ForeignBorrowed`, since it was easy and quick, but we might want to choose a different one. Eg one that is shorter. Some options that came to mind:
- `Foreign`
- `FBorrow`
### Splitting up `helpers.c`
Anybody against splitting up `helpers.c` ?
https://rust-for-linux.zulipchat.com/#narrow/stream/288089-General/topic/Splitting.20up.20helpers.2Ec/near/430980731
## Miscellaneous
<!-- stuff that does not fit into other categories -->
### `u63` or `NonNegativeI64`
`ktime_t` in kernel (per Boqun's understanding):
* when used as a timestamp, the valid range is `[0, KTIME_MAX]`, where `KTIME_MAX` is `i64::MAX`.
* when used as a time delta, for the efficiency, the valid range is `[-KTIME_MAX, KTIME_MAX]`.
Therefore it's defined as an `i64`. Notice that I don't think negative timedeltas are the usual cases, they are probably used mostly for "rebasing" a duration, for example:
t2 = t1 + (base2 - base1);
most usages of a duration are adding it to a time base (e.g in timer code) to calculate a future timestamp. (You cannot arm a timer that fires in a past time).
so I (Boqun) generally agree Benno's suggestion [making Duration non negative](https://lore.kernel.org/rust-for-linux/kZmwObXVcyEJFVR3I05Nab0WdjcccDVARoOm6U9EmXhd89fxYRjvNmEAUZsueWTUlBlHp8jpU3i2YfgN9aWCLZameta0tPT_OgQdBOWUIko=@proton.me/), however to mirror the `ktime_t` semantics in kernel, I will need a `u63` or `NonNegativeI64` for `Duration`, so that `Option<Duration>` or `Either<Duration, Duration>` can be put into a `i64`. This will gives the same time and space efficiency as the C code.
My question is: does LLVM support this? If so, is there any Rust work already covering this?
Gary: Rust compiler does have a notion of scalar range, but it won't (and can't) optimise `Result<NonNegativeI64, NonNegativeI64>` (the reason being that you need ability to get `&mut NonNegativeI64` for both variants and it's not possible if there're only 8 bytes in total). `Option` works fine.
```rust=
#![feature(rustc_attrs)]
#[repr(transparent)]
#[rustc_layout_scalar_valid_range_start(0)]
#[rustc_layout_scalar_valid_range_end(9_223_372_036_854_775_807)] // i64::MAX
pub struct NonNegativeI64(i64);
fn main() {
println!("{}", core::mem::size_of::<Option<NonNegativeI64>>()); // 8
println!("{}", core::mem::size_of::<Result<NonNegativeI64, NonNegativeI64>>()); // 16
}
```
I think we could have both a `Delta` type and a `Duration` type?
Cross ref to this discussion: https://internals.rust-lang.org/t/non-negative-integer-types/17796
```rust
fn elapsed_since(t1: TimeStamp, t2: TimeStamp) -> Option<Duration> {
if t1 < t2 {
return Some(t2 - t1);
} else {
return None;
}
}
```
Gary: I think what could be done is
```rust
impl Sub for TimeStamp {
type Output = Delta;
}
impl Delta {
fn as_duration(self) -> Option<Duration> {
if self.0 < 0 {
None
} else {
Some(self.0)
}
}
}
fn elapsed_since(t1: TimeStamp, t2: TimeStamp) -> Option<Duration> {
(t1 - t2).as_duration()
}
```
If the `as_duration` part is inlined into the checking code then it'll just be optimised to checking delta is non-negative.
```
```