
Writing Network Drivers in Rust [pdf] - MrBuddyCasino
https://www.net.in.tum.de/fileadmin/bibtex/publications/theses/2018-ixy-rust.pdf
======
dswalter
Per a talk from Joshua Liebow-Feeser at the Rust Belt Rust 2018 conference,
Google is heavily using Rust for networking in their new Fuchsia operating
system.

This is a rough approximation of a quote he gave during the talk:

"What makes Rust different is not that you can write high-performance, bare-
metal code. People use C and C++ to do that all the time. What makes Rust
different is that when you write that code, it is safe, clean, and easy to
use, and you are confident in its correctness."

If even Google is using Rust for performance-critical development, that seems
pretty promising to me.

~~~
Thaxll
Isn't the networking stack of Fuchsia written in Go?

[https://fuchsia.googlesource.com/garnet/+/master/go/src/nets...](https://fuchsia.googlesource.com/garnet/+/master/go/src/netstack/)

[https://github.com/fuchsia-mirror?language=go](https://github.com/fuchsia-
mirror?language=go)

I'm pretty sure Go is the dominant language for networking in Fuchsia and not
Rust.

~~~
DougBTX
Links in the presentation point here:
[https://fuchsia.googlesource.com/garnet/+/master/bin/recover...](https://fuchsia.googlesource.com/garnet/+/master/bin/recovery_netstack/core/src/)

------
cesarb
Having written device drivers before, the first thing I wondered was how he
allocated a fixed region of physical memory in user space...

"In kernel space there is an API to allocate DMA memory, in user space we have
to use other mechanisms since this API is not available here. To disable
swapping, we can use mlock(2). [...] However, mlock(2) only ensures that the
page is kept in memory. The kernel is still able to move pages to different
physical addresses. To circumvent this problem, we use huge pages with a size
of 2 MiB. These pages cannot be migrated yet by the Linux kernel, thus stay
resident in physical memory."

He didn't, he's depending on an implementation quirk which might change in the
future (and also depending on the physical memory backing huge pages being in
a region which can be reached by the network device through DMA, though that's
probably always true on x86 when memory encryption is not in use).

~~~
codingbeer
DPDK also relies on this quirk if there is no IOMMU available. He does mention
the IOMMU as future work, but in the context of security.

------
ilovecaching
This is very cool. I’ve been working on using Rust to manage an XDP based
network driver that is much, much, much faster than the socket API in C, and
slightly faster than DPDK. There’s no driver in the traditional sense, Rust
works as a control plane and eBPF injector, while the XDP programs communicate
back to Rust through eBPF maps.

I’m extremely bullish on Rust, it’s such a breath of fresh air to be able to
write maintainable, modern code to do low level tasks. I was a C/C++ dev for a
little under a decade before switching to Rust and it really delivers on its
promises.

Also Rust using llvm is a huge boon to writing eBPF programs.

~~~
Klasiaster
This sounds very interesting, do you have some code (parts) to share?

~~~
jvtbatman
I'm also very interested in any more information regarding this since I'll be
doing my thesis work on XDP soon and would like to use Rust!

------
delta1
FTA

"Based on our findings we can conclude that Rust is a very well-suited
programming language for writing network drivers. It is not only a fast and
safe systems programming language but was also voted most beloved programming
language in 2016, 2017 and 2018 [15, 16, 17]. Writing more drivers in Rust
would certainly lead to safer and more reliable computer systems."

Working link to their code: [https://github.com/ixy-
languages/ixy.rs](https://github.com/ixy-languages/ixy.rs)

~~~
Xophmeister
How is “most beloved” a prerequisite to writing network drivers? Don’t get me
wrong, if Rust is a good technical fit, then that’s great, but so convince me
on those objective measures.

~~~
simias
"Most beloved" is a weird way to put it but if it's a way to gauge the state
of the language's ecosystem I'd say it's a very practical concern.

For instance these past few days I've been writing a small bootloader for some
embedded ARM chip. I pondered going with Rust but ended up using C for two
main reasons:

\- I know that if it's doable in Rust it's doable in C but the opposite is not
always true (or straightforward). In particular bare-metal/very low level Rust
is still somewhat experimental, you can't use stable Rust if you want to be
able to use inline ASM or other advanced features. I have very tight
constraints regarding code size and memory use and I was concerned that I
might not control that as effectively with Rust code than with C.

\- There's already a bunch of C code written for this chip that I can reuse
without any friction (no binding generation, no ffi etc...). The vendor even
provides a huge header file with the full memory map and some code to init the
PLLs.

If you're coding in a vacuum then how "beloved" a language is is mostly
irrelevant but if you want to benefit from the ecosystem then having a
language that people want to use and support is extremely important. The
tooling will mature and stabilize as more and more people use Rust to write
bare-metal code and device drivers, which will eventually make my first point
above irrelevant. Then if the language becomes popular enough it will be
easier to find Rust code or pre-made crates to do what you want which will
hopefully eventually solve my 2nd issue.

~~~
hra5th
What ARM chip are you considering this for? Is it a Cortex M?

~~~
simias
No, Cortex A in an Arria10 SoC. The boot process is tedious because you have
to load the FPGA before you can access the external RAM so the stage 1
bootloader has to fit 256KB code+data. Currently I'm using a multi-stage
U-Boot but for simplicity and robustness I'd like to cram everything in a
single stage loader.

Since I can't get u-boot to create a small enough image with all the features
that I want (and also because I want to add vendor-specific customizations on
top) I decided to try and rewrite a small, single purpose loader from scratch.
I considered Rust but then that meant that I'd have to port or rewrite all of
u-boot's code I want to reuse (especially the vendor code contributed by
Altera mentioned in the previous post). So C it is.

------
Jhsto
I recently wrote my bachelors thesis and I wish it could have been as
practical as this. Props for German universities for allowing a software
engineering project to be accepted. There is no way I could have gotten away
with so little amount of academic references.

~~~
ambentzen
When I took my bachelors, each semester we split the 27-ish people in our year
into groups of about 6 people that had to write a piece of software related to
a theme, e.g. compilers or robots, where the courses that semester supported
the theme. At the end of the semester we handed in a report of approximately
100 pages detailing the decisions and design and theory behind the practical
work we did, which we had to defend orally.

The bachelor project was more of the same, but each group should do a part of
a bigger piece of software. I don't recall having any academic references in
our final report.

It was a very nice way to learn, as you had your group members to study with
and learn from each other.

This was in Denmark, Aalborg University. Which have just been named the best
engineering university in Europe, and the fourth best in the world [0].

[0] [https://www.usnews.com/education/best-global-
universities/en...](https://www.usnews.com/education/best-global-
universities/engineering)

~~~
Fredej
Hah, I was reading this thinking "That sounds so much like Aalborg". I'm so
incredibly happy I went there :)

Here's another report from MIT from earlier this year, reporting largely the
same, placing Aalborg at 3rd or 4th depending on the method used [0].

[0] [http://neet.mit.edu/wp-
content/uploads/2018/03/MIT_NEET_Glob...](http://neet.mit.edu/wp-
content/uploads/2018/03/MIT_NEET_GlobalStateEngineeringEducation2018.pdf)

------
hardwaresofton
Related (Writing network drivers in Go):

[https://news.ycombinator.com/item?id=18399389](https://news.ycombinator.com/item?id=18399389)

I'm excited to read both of these.

~~~
arendtio
Same university and department :D

~~~
hardwaresofton
Yeah I noticed!

Seeing that this is an undergrad thesis makes me feel like I did nothing in
undergrad. I'm impressed

~~~
blub
Maybe I missed something, but all of these network drivers in Go, Rust, C# etc
are just re-implementations of the original C driver, where it would seem to
me that the real work happened.

That would make the ports still be an interesting experiment, but not as
impressive IMO.

~~~
tracker1
I think it depends. Writing a non-trivial language port is an interesting way
to show off a language. Though it also tends to be an ugly way to show off a
language. It depends on the ugliness of implementation for a given language.
Early in C# I saw some really ugly implementations of crypto from other
languages, for example. Often pretty obvious the person porting didn't
understand the new language well.

Some things hard in one language are easy in another, and it usually helps to
have a good understanding of both. Just my own POV. However, low level code
often requires one to do things "the hard way" for performance reasons. I
particularly appreciate what Go, Rust, C# and others bring to the table.

Most of the code I write isn't particularly performance intensive, so I tend
to reach for JS in early implementations. Though happy to rewrite if/when
performance becomes a concern. I really enjoy articles like this.

------
lukego
Since we are looking at PCI Ethernet drivers written in languages other than C
(fun!) here is one written in Forth too:
[https://github.com/openbios/openfirmware/blob/master/dev/ne2...](https://github.com/openbios/openfirmware/blob/master/dev/ne2000/ne2kpci.fth)

Good to remember that C and Unix kernels haven't always had a monopoly on
device drivers.

------
jononor
The Rust version of ixy seems to have as many or a bit more lines of code than
the C version? That is a bit suprising to me. 1306 for Rust, and '1000' for C.
The Rust additionally uses 4 dependencies from crates.io

Unsafe usage is quite small, at 10%, which seems good for a hardware device
driver.

~~~
klohto
I’m not sure if this is a critique or a question. If former, then I don’t
understand why would that matter. Even at 4 times the length of the code, Rust
is safer, more robust and better optimized. So why would the length matter?

~~~
Riverheart
One of Rust's selling points is zero cost abstractions which would normally
imply doing more work with less code (as you would expect in a high level
language like Python). So it is surprising that it takes that many more lines
of code to achieve what C does without those abstractions.

~~~
rantanplan
"zero cost abstractions" usually means you don't pay a performance penalty for
abstractions you do not use.

~~~
tjoff
Also means that the abstractions themselves don't introduce unnecessary
overhead. It's taken from C++.

 _C++ implementations obey the zero-overhead principle: What you don’t use,
you don’t pay for [Stroustrup, 1994]. And further: What you do use, you
couldn’t hand code any better. – Stroustrup_

[https://blog.rust-lang.org/2015/05/11/traits.html](https://blog.rust-
lang.org/2015/05/11/traits.html)

------
godelmachine
Contrast this with
[https://news.ycombinator.com/item?id=18399389](https://news.ycombinator.com/item?id=18399389),
both of which are trending.

------
noodlesUK
Does anyone happen to have a copy of the LaTeX template that they are using? I
really like the typography of the two that are currently on the frontpage.

~~~
tlamponi
It may be this: [https://github.com/fwalch/tum-thesis-
latex](https://github.com/fwalch/tum-thesis-latex)

At least it's linked here: [https://www.in.tum.de/fuer-studierende/bachelor-
studiengaeng...](https://www.in.tum.de/fuer-studierende/bachelor-
studiengaenge/informatik-games-engineering/abschlussarbeit/)

------
_pmf_
What really would be nice is an extension of what Zinc does, namely encode the
IO registers as strongly types entities. Maybe not even encode their usage,
but also their usage (r/w/rw).

------
xyproto
Reading the conclusion in the PDF, the Rust version is not faster than the C
version and not necessarily safer either, since there is plenty of "unsafe"
Rust code involved.

While Rust is nice in some areas, I'm not convinced this is anything more than
yet another "let's rewrite it in Rust, because I happen to like Rust" article.

Angry comments defending Rust incoming in 3..2..

~~~
red75prime
> not necessarily safer either

Rust version will not be safer if the authors did 10 times more errors per
line than average C programmer.

~~~
red75prime
Rust version has 10% of lines marked as `unsafe`. Programmers need to make 10
times more errors per line to introduce the same number of errors that are
considered unsafe in Rust (memory corruption, data races, double frees,
deallocated memory usage). I'm not sure what's wrong with this statement.

------
bvelica
I was hopping to see something like that. Thank you!

------
OpenBSD-reich
Why rust? Didn't Ada and SPARK already pretty much solve the problems rust is
tackling? rust feels like the systemd of languages: came out of nowhere and
very heavily evangelized.

~~~
imtringued
Do those languages have anything even remotely similar to linear types [0]? If
not then they aren't even in the same league as Rust.

[0]
[https://en.wikipedia.org/wiki/Substructural_type_system](https://en.wikipedia.org/wiki/Substructural_type_system)

These types of comments really irritate me. New thing X comes out that solves
an unsolved problem. Then someone comments "why not obsolete thing Y that
doesn't solve the problem sufficiently"?

I constantly see comparisons like JVM vs WASM [1], or in this case Ada vs
Rust. And very often the newer thing is superior and is not popular just
because of cargo culting.

[1] i.e. To obtain similar performance while still using java bytecode you
will have to stop using the Java object model completely and exclusively use
sun.misc.Unsafe and calculate field offsets of structs manually and still have
the risk of vulnerabilities like buffer overflows similar to writing programs
in C.

------
discoball
Nim produces smaller binaries, has zero-pause, realtime gc (and you can even
define gc behavior) and compiles to optimized C. It's a win over Rust in every
way including ease of use. Big issue with Nim is tribalism, pure and simple.
It's author failed to get any major corporations behind it so it doesn't get
hyped up in constant Medium articles and conference talks and therefore does
not get a lot of attention, which keeps it a niche language, sadly.

~~~
grogers
[https://nim-lang.org/docs/gc.html](https://nim-lang.org/docs/gc.html)

> Tests show that a 2ms max pause time will be met in almost all cases on
> modern CPUs (with the cycle collector disabled).

So in a reduced mode, pause times are only bounded by 2ms. Not sure how you
could say that is zero pause

~~~
jononor
Certainly not zero, but probably enough for hitting the frame deadline for
60fps graphics (16ms). Could even enough for real-time audio processing (at
4ms or 8ms). That will cover the vast majority of latency requirements that
application developers using an OS deals with.

Some embedded realtime cases might have more strict deadline requirements, or
be complicated by the potential jitter that a GC _might_ intoduce. Eg most
discrete math used in motor control systems assumes a fixed sample period.

~~~
chc
I haven't done game dev beyond hobbyist level, but 12.5% of your total budget
for a frame seems pretty significant. Is that kind of percentage hit generally
considered negligible?

~~~
Kaveren
60 FPS is not enough, many people have monitors with much higher refresh rates
(120 hz, more). You have virtual reality which basically requires a higher
refresh rate than 60 FPS to begin with. Using a runtime component for garbage
collection is highly sub-optimal.

Rust is possibly an ideal language for game development. Standard Rust has no
runtime component, which is perfect. It's also a high-performance language.

The ecosystem for Rust game development is immature, but there's progress
being made.

~~~
majewsky
Standard Rust absolutely has runtime components. Otherwise a "Hello World"
would not compile into several 100 KiB of binary. (Not saying that that's bad,
just that this is how it is.)

~~~
red75prime
It has runtime as in "C runtime", that is the code which runs before and after
`main` and the code of standard library. It doesn't have runtime as in "Java
runtime" (or "C# runtime") that includes the code that runs alongside your
code (garbage collection thread).

~~~
Kaveren
Yes, I was loose in my use of the term "runtime" and sacrificing correctness.
Writing "runtime component" rather than "runtime" makes it more misleading. I
probably should've worded my original comment more wisely.

