Mirage-firewall memory assignment

How much memory should I assign to a mirage-firewall qube? Is 32 MB always sufficient? What’s the benefit of going higher, to 64? Is there OOM risk at 32?

Thanks all for opening up your work for cross-comparison!

In my experience 32 is sufficient. I have never had reports of any
memory issues, even under intensive use…
@palainp is a developer of the mirage-firewall, and proposes 32.
I do not know why others raise that value.

I never presume to speak for the Qubes team.
When I comment in the Forum I speak for myself.

1 Like

Dear @Euwiiwueir, @unman,

the story behind this setting is interesting but a bit long, so I’ll try to keep it short :slight_smile:

With MirageOS, “large” memory chunks (such as network packets) can be managed in two ways: either directly by the GC (allocation and free, which is pretty fast, but needs extra copies), or with manual allocation of a “bigarray” and transfer management to the GC, which will free it when it is convinced that the bigarray is no longer in use (so the memory remains used a little longer than necessary). It’s a trade-off between memory usage and being able to avoid copies between different network layers.
For the past year or two, some developpers from Mirage (including me) have been making changes to switch from the latter to the former, with the idea that memory management is more important than performance (and btw I observe almost no performance drop so far).

TLDR: There were GitHub issues caused by memory fragmentation due to bigarrays taking too long to be freed. Increasing the unikernel size from 32MB to 64MB leaves the time for GC to do its job, and, at one point, it was a recommended setting. Currently, I feel that things are better and that getting back to 32MB is acceptable.
And I don’t recommend trying to reduce it any further, the unikernel crashes with OOM after a few network packets :slight_smile:

2 Likes

Thanks for the context, and thanks for the project. :saluting_face:

1 Like

Following on from:

Here, to start, are some lightly tested mirage firewall configurations that have been working well for me.


Use case: firewall qube as netvm for LAN-only utilities:

qvm-prefs sys-m-firewall-lan memory 32

(i.e. the recommended default) I use this firewall to isolate access to the 192.168.*.* subnet. It’s only for intra-LAN ssh and configuring my router over its web admin frontend.


Use case: firewall qube as netvm for several light-use WAN browser qubes:

qvm-prefs sys-m-firewall-browse memory 32

(i.e. the recommended default)


Use case: firewall qube as netvm for gateway qube to ethernet connection to NAS:

qvm-prefs sys-m-firewall-nas memory 48

What characterizes this networking path is bursty batch traffic; sporadic large file/stream transfers to/from the Qubes workstation over nfs. I believe 32MB was throttling throughput, but this is based on feeling rather than benchmarking.


Use case: toplevel WAN firewall qube, mediating all browsing, VPN, sys-whonix, light torrenting:

qvm-prefs sys-m-firewall-wan memory 64
qvm-prefs sys-m-firewall-wan kernelopts '--nat-table-size 10000'

(Default nat-table-size: 5000)
In this case I’m confident 32MB was throttling performance compared to a Linux-based firewall. The above are the first adjustments I tried in order to regain performance, and they worked, and I haven’t tried tweaking them for greater efficiency.

2 Likes

I use 64 because I have 16GB of RAM and am not fighting for 32MiB, I prefer to have connectivity independent of workflow.

400MiB is the default for sys-firewall. With Mirage using 64MiB, you can have ~6 mirage replacements (400 / 64 = 6.25). That’s a lot already.

2 Likes