---
# System prepended metadata

title: Meeting 2024-04-03
tags: [meeting notes]

---

# 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.



```

```