Nominally this rate limit is defined to avoid... getting rate-limited?
But it already severely limits the rate to unusable ‒ on two of my real systems this makes efibootmgr take 168ms/194ms, which accounts for 95%/82% of the run-time (and this is under strace, so it's 100% of the run-time) ‒ for klapki 0.2, this accounts for 36% and a large (140ms!) start-up delay, and for klapki 0.3 it's well over 50%. Well before you'd ever run afoul of the real limit.
Discounting "20ms" as "The user is not going to notice." is baffling. efibootmgr is infuriatingly slow. 20ms is ping-to-america level.
Worse yet, the entire kernel rate-limiter amounts to fs/efivarfs/file.c
this is the alloc_uid() ratelimit with 1s interval + 100 burst.
This means that we can (best-case) read 50 variables (read(...), read(0)) instantly, then do so again the next second.
Best-case because the current implementation is broken anyway: it sleeps for 10ms after the attribute read (sure), and then for 10ms after the two reads to read the rest of the variable (bad).
This limits libefivar to 33⅓ variables per second.
Most systems have roughly this many variables. Most programs only care about a very thin subset of them, and scarcely come close to reading enough to run afoul of the kernel limit. But even if they did, this limit is significantly harsher than the kernel limit ‒ it doesn't increase it (how could it? the limit's already there!), but severely increases latency for every single read, instead of just those over the rate.
It's strictly worse than just not doing it.
This was confirmed experimentally with strace -TTTT /bin/wc * * * * * (note the many every-variable expansions so it's noticeable, this system has fewer than 50 variables): there is both visually a very obvious "big burst, little slowdown" oscillation, but also (non-efivarfs reads filtered out)
(130+395)/2=262½ variables read in under a millisecond, and 4½ got limited.
But, much more importantly, the first screenful was free: 99% of programs that don't read every variable over and over and over, but fit well within the 33 (klapki's 7 and efibootmgr's 8, this is with the firmware's base boot entries + two additional ones; there isn't a non-hypothetical system in existence with 25 more boot entries).
Nominally this rate limit is defined to avoid... getting rate-limited?
But it already severely limits the rate to unusable ‒ on two of my real systems this makes efibootmgr take 168ms/194ms, which accounts for 95%/82% of the run-time (and this is under strace, so it's 100% of the run-time) ‒ for klapki 0.2, this accounts for 36% and a large (140ms!) start-up delay, and for klapki 0.3 it's well over 50%. Well before you'd ever run afoul of the real limit.
Discounting "20ms" as "The user is not going to notice." is baffling. efibootmgr is infuriatingly slow. 20ms is ping-to-america level.
Worse yet, the entire kernel rate-limiter amounts to fs/efivarfs/file.c
this is the
alloc_uid()
ratelimit with 1s interval + 100 burst.This means that we can (best-case) read 50 variables (read(...), read(0)) instantly, then do so again the next second.
Best-case because the current implementation is broken anyway: it sleeps for 10ms after the attribute read (sure), and then for 10ms after the two reads to read the rest of the variable (bad).
This limits libefivar to 33⅓ variables per second.
Most systems have roughly this many variables. Most programs only care about a very thin subset of them, and scarcely come close to reading enough to run afoul of the kernel limit. But even if they did, this limit is significantly harsher than the kernel limit ‒ it doesn't increase it (how could it? the limit's already there!), but severely increases latency for every single read, instead of just those over the rate. It's strictly worse than just not doing it.
This was confirmed experimentally with
strace -TTTT /bin/wc * * * * *
(note the many every-variable expansions so it's noticeable, this system has fewer than 50 variables): there is both visually a very obvious "big burst, little slowdown" oscillation, but also (non-efivarfs reads filtered out)or indeed
(130+395)/2=262½ variables read in under a millisecond, and 4½ got limited.
But, much more importantly, the first screenful was free: 99% of programs that don't read every variable over and over and over, but fit well within the 33 (klapki's 7 and efibootmgr's 8, this is with the firmware's base boot entries + two additional ones; there isn't a non-hypothetical system in existence with 25 more boot entries).
Fixes: https://bugs.debian.org/1056344:
and