Le 07/11/2022 à 23:39, Song Liu a écrit : > This patchset tries to address the following issues: > > 1. Direct map fragmentation > > On x86, STRICT_*_RWX requires the direct map of any RO+X memory to be also > RO+X. These set_memory_* calls cause 1GB page table entries to be split > into 2MB and 4kB ones. This fragmentation in direct map results in bigger > and slower page table, and pressure for both instruction and data TLB. > > Our previous work in bpf_prog_pack tries to address this issue from BPF > program side. Based on the experiments by Aaron Lu [4], bpf_prog_pack has > greatly reduced direct map fragmentation from BPF programs. > > 2. iTLB pressure from BPF program > > Dynamic kernel text such as modules and BPF programs (even with current > bpf_prog_pack) use 4kB pages on x86, when the total size of modules and > BPF program is big, we can see visible performance drop caused by high > iTLB miss rate. > > 3. TLB shootdown for short-living BPF programs > > Before bpf_prog_pack loading and unloading BPF programs requires global > TLB shootdown. This patchset (and bpf_prog_pack) replaces it with a local > TLB flush. > > 4. Reduce memory usage by BPF programs (in some cases) > > Most BPF programs and various trampolines are small, and they often > occupies a whole page. From a random server in our fleet, 50% of the > loaded BPF programs are less than 500 byte in size, and 75% of them are > less than 2kB in size. Allowing these BPF programs to share 2MB pages > would yield some memory saving for systems with many BPF programs. For > systems with only small number of BPF programs, this patch may waste a > little memory by allocating one 2MB page, but using only part of it. > > > Based on our experiments [5], we measured 0.5% performance improvement > from bpf_prog_pack. This patchset further boosts the improvement to 0.7%. > The difference is because bpf_prog_pack uses 512x 4kB pages instead of > 1x 2MB page, bpf_prog_pack as-is doesn't resolve #2 above. > > This patchset replaces bpf_prog_pack with a better API and makes it > available for other dynamic kernel text, such as modules, ftrace, kprobe. > > > This set enables bpf programs and bpf dispatchers to share huge pages with > new API: > execmem_alloc() > execmem_alloc() > execmem_fill() > > The idea is similar to Peter's suggestion in [1]. > > execmem_alloc() manages a set of PMD_SIZE RO+X memory, and allocates these > memory to its users. execmem_alloc() is used to free memory allocated by > execmem_alloc(). execmem_fill() is used to update memory allocated by > execmem_alloc(). > > Memory allocated by execmem_alloc() is RO+X, so this doesnot violate W^X. > The caller has to update the content with text_poke like mechanism. > Specifically, execmem_fill() is provided to update memory allocated by > execmem_alloc(). execmem_fill() also makes sure the update stays in the > boundary of one chunk allocated by execmem_alloc(). Please refer to patch > 1/5 for more details of > > Patch 3/5 uses these new APIs in bpf program and bpf dispatcher. > > Patch 4/5 and 5/5 allows static kernel text (_stext to _etext) to share > PMD_SIZE pages with dynamic kernel text on x86_64. This is achieved by > allocating PMD_SIZE pages to roundup(_etext, PMD_SIZE), and then use > _etext to roundup(_etext, PMD_SIZE) for dynamic kernel text. Would it be possible to have something more generic than being stuck to PMD_SIZE ? On powerpc 8xx, PMD_SIZE is 4MB and hugepages are 512kB and 8MB. Christophe