I am having fun while writing the Snabb Switch Ethernet device driver. This is like Intel’s standard E1000/IGB/IGBE driver for Linux except that:
- It is written in LuaJIT. (It’s my first LuaJIT program, I’m a newbie.)
- It runs in a normal Linux userspace process but talks directly to hardware.
- It is tailor made for one application, a simple hypervisor-friendly ethernet switch.
I have been optimizing the LuaJIT selftest code to transmit ethernet packets in a loop. I am pretty encouraged by the performance that I see: 3.1% CPU utilization on a low-end Hetzner EX6 machine to saturate a 1Gbps ethernet port with tiny packets. That is 28 nanoseconds of CPU time per packet.
I hope the details will be interesting. It is not so often that people write about low-level networking in high-level dynamic programming languages, is it? So, to give a quick taste, the driver source code is in intel.lua and the selftest main loop works like this:
1 2 3 4 5 6 7 8 |
|
and here is what that means:
- Sleep while the hardware transmit queue is at least 75% full (
tx_load
). - Fill up the transmit queue with 60-byte packets (
add_txbuf
). - Tell the NIC hardware to process the transmit queue (
flush_tx
). - Stop after 10 seconds have elapsed (
get_time_ns
).
This is all accomplished by directly controlling the NIC using memory-mapped register I/O and DMA with shared memory. The only operating system calls here are to sleep and check the time.
This is a really fun sort of programming to be doing!
Going forward I am really excited to see how much of a production quality Ethernet switch can be written in a high-level dynamic programming language, and how neatly any parts that are ultimately written in C can be integrated into the whole. This is an open source project and you are welcome to join in the fun too!
(Comments welcome on the Snabb Switch Reddit.)