bpf/progs/netd: make 'blocked_ports_map' mmapable

Perhaps not the best example, but virtually free considering
a bitmap of 64K bits is 8KiB no matter what.

Kernel will allocate:
  1 page for internal metadata (rounded up to a full page)
  N pages rounded up from array size, which is:
      number of elements (65536 bits / 64 bits per u64) = 1024
    * element size (u64 rounded up to a multiple of 8) = 8
    = 8192

This rounding up is unique to *mmapable* arrays.

thus on 4KiB page size: 12 KiB - waste is at most a few (<4) KiB
and on 16KiB page size: 32 KiB - which isn't great, but well that's 16KiB...
(presumably 16KiB is being used on devices with a lot of ram,
 where performance matters more than a little ram waste)

Note: AFAICT a kernel bpf program R/W map cannot be mapped R/O
into userspace, as the permissions on the page mapping would conflict.

(and obviously you cannot map R/W if you have only R/O access)

I'm not sure if this is architecture specific,
or simply an implementation limitation, but it is what I observed.

I think it's likely a missing kernel feature (even on 6.12)...

Test: TreeHugger
Flag: EXEMPT mainline
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I609ae61e17917ff441cac10a9b29af3fcacb53c5
This commit is contained in:
Maciej Żenczykowski 2025-08-07 14:45:27 -07:00
commit 12f752aae9

View file

@ -65,7 +65,7 @@ DEFINE_BPF_MAP_RO_NETD(configuration_map, ARRAY, uint32_t, uint32_t, CONFIGURATI
// TODO: consider whether we can merge some of these maps
// for example it might be possible to merge 2 or 3 of:
// uid_counterset_map + uid_owner_map + uid_permission_map
DEFINE_BPF_MAP_NO_NETD(blocked_ports_map, ARRAY, int, uint64_t,
DEFINE_BPF_MAP_NO_NETD(blocked_ports_map, MMAPABLE_ARRAY, int, uint64_t,
1024 /* 64K ports -> 1024 u64s */)
DEFINE_BPF_MAP_RW_NETD(cookie_tag_map, HASH, uint64_t, UidTagValue, 10000)
DEFINE_BPF_MAP_NO_NETD(uid_counterset_map, HASH, uint32_t, uint8_t, 4000)