Re: [PATCH net-next v7 0/5] Rust abstractions for network PHY drivers

Andrew Lunn
2023-10-27T14:26:27Z

On Thu, Oct 26, 2023 at 09:26:05PM -0700, Boqun Feng wrote:
> On Thu, Oct 26, 2023 at 08:11:00PM -0700, Boqun Feng wrote:
> [...]
> > > likely will be merged. Real problems can be fixed up later, if need
> > > be.
> >
> > But this doesn't apply to pure API, right? So if some one post a pure
> > Rust API with no user, but some tests, and the CI passes, the API won't
> > get merged? Even though no review is fine and if API has problems, we
> > can fix it later?
> >
>
> I brought this up because (at least) at this stage one of the focus
> areas of Rust is: how to wrap C structs and functions into a sound and
> reasonable API. So it's ideal if we can see more API proposals.
>
> As you may already see in the reviews of this patchset, a lot of effort
> was spent on reviewing the API based on its designed semantics (rather
> than its usage in the last patch). This is the extra effort of using
> Rust. Is it worth? I don't know, the experiment will answer that in the
> end ;-) But at least having an API design with a clear semantics and
> some future guards is great.
>
> The review because of this may take longer time than C code, so if we
> really want to keep up with netdev speed, maybe we relax the
> must-have-in-tree-user rule, so that we can review API design and
> soundness in our pace.

The rule about having a user is there for a few reasons:

Without seeing the user, you cannot say if the API makes sense. How
is the user using the API? Is the architecture of the user correct?
Fixing the architecture of the user could change the API. As an
example, i've seen Rust wrapper on top of sockets. The read/write
method use a plain block of memory. However, for a network filesystem,
what you actually need to send is probably represented by a folio of
pages in the buffer cache. Its more efficient to hand the folio over
to the network stack. If the data is coming from user space, its
probably coming via a socket. So its probably in the form of a list of
chunks of data, maybe still in userspace, maybe with a header added in
kernel space. You want to pass that representation to the stack, which
can already handle it in an optimal way. A plain block of memory could
in fact be correct, there are use cases where its simple command being
sent to a modem. But its impossible to say what is correct unless you
can use the user.

Another point is that internal API are unstable. Any developer can
change any API anywhere in the kernel, if they can justify it. That is
an important feature of the kernel, and we don't like making it harder
to change APIs. If you cannot see both sides of an API, its hard to
know if you can change it, or how you need to change it. And at the
moment, there are very few Rust developers. An API in Rust is going to
be harder for a developer to change. So we have a strong reason to
keep Rust APIs minimal, with clear users.

But this API unstableness plays both ways. You don't need a perfect
API before it is merged. You just need it good enough. You can keep
working on it once its merged. If you missed something which makes is
unsound, not a problem, its just a bug, fix it an move on, like any
other bug.

Andrew