Thanks for the review. I have added the existing measurement to the local commit message for the next full revision. For a 100,000-entry hash map in an x86-64 KVM guest, BPF syscall counts decreased from 200,004 to 395. The median of five untraced runs decreased from 0.774013 s to 0.733844 s, about 5.2% in this measurement. Syscalls were counted separately with strace. The v2 change affects error reporting, not this traversal algorithm or bound.
The 4 MiB eligibility check is intentional. Hash batch lookup must fit an entire bucket; ENOSPC leaves that bucket at the current cursor so it can be retried with a larger buffer. The bound guarantees that growth can accommodate even a worst-case bucket within the memory budget. Capping growth for otherwise unbounded maps leaves a problem when a later bucket is too large, after some entries have already been printed. The individual-lookup fallback starts from NULL and would print those entries again. The opaque batch cursor is a bucket cursor, not a key from which bpf_map_get_next_key() can resume. Returning an error instead would newly fail a dump that individual lookups could have completed. Thus the example with one million 4-byte keys and 4-byte values does intentionally use individual lookups. I am keeping the conservative bound to preserve the output behavior and memory limit. Broadening it would need an explicit solution for the post-output oversized-bucket case, beyond just capping the allocation.
