Open lmb opened 1 year ago
- Structs of valid types which have no compiler inserted padding, aka packed structs
Why is the no padding required?
Because the padding is completely invisible to regular Go. Pretty printing a value doesn't show such padding. What happens when we write into the padding via unsafe
? Is padding taken into account when comparing values?
The only way I'd be comfortable with this is if we zeroed the padding somehow, but then we wouldn't do that in the fastpath.
Ah, we generate Go types using go tool cgo -godefs
which includes the padding. So it sounds like that would still work.
Timo is in the process of moving cilium/cilium over to use ebpf.Map more consistently and he found that map operations in the lib allocate a lot more than the old code paths. Timo was able to improve that quite a bit with a simple fix: https://github.com/cilium/ebpf/pull/1053 However we are still a bit more inefficient than the previous code.
The reason is that cilium/cilium essentially passes
unsafe.Pointer
to map keys and values, skipping marshaling altogether. This works since the Go in-memory layout of certain types are identical to the result produced bybinary.Write(NativeEndian)
. There is a check in CI which ensures that types passed as map keys and values have the correct layout (I think?).I want to investigate if we can extend this approach to all users of the library, without requiring a build time / CI check. The lib should check at run time whether the type of a value satisfies the following invariants and pass unsafe.Pointer to the backing memory of the value.
uint64