Skip to content

Commit 1f23262

Browse files
pa1guptagregkh
authored andcommitted
bpf: Skip redundant IBPB in pack allocator
commit a23c1c5 upstream. bpf_prog_pack_alloc() issues IBPB on all CPUs on every cBPF allocation, even when reusing chunks from an existing pack where no new memory was touched since the last IBPB. Since IBPB on all CPUs is heavy, Dave Hansen suggested to track allocation since last IBPB, and only issue IBPB at reuse for the chunks that have not seen an IBPB since they were last freed. Track per-pack whether an IBPB is needed via arch_flush_needed. Set it when allocating a chunk, reset on IBPB flush. On reuse, conditionally issue the flush. Since IBPB invalidates all BTB entries, clear the flag on all packs after flushing. Signed-off-by: Pawan Gupta <pawan.kumar.gupta@linux.intel.com> Acked-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 3b3b23c commit 1f23262

1 file changed

Lines changed: 14 additions & 1 deletion

File tree

kernel/bpf/core.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,7 @@ int bpf_jit_add_poke_descriptor(struct bpf_prog *prog,
851851
struct bpf_prog_pack {
852852
struct list_head list;
853853
void *ptr;
854+
bool arch_flush_needed;
854855
unsigned long bitmap[];
855856
};
856857

@@ -906,6 +907,8 @@ static struct bpf_prog_pack *alloc_new_pack(bpf_jit_fill_hole_t bpf_fill_ill_ins
906907
bitmap_zero(pack->bitmap, BPF_PROG_PACK_SIZE / BPF_PROG_CHUNK_SIZE);
907908
list_add_tail(&pack->list, &pack_list);
908909

910+
if (static_branch_unlikely(&bpf_pred_flush_enabled))
911+
pack->arch_flush_needed = true;
909912
set_vm_flush_reset_perms(pack->ptr);
910913
set_memory_rox((unsigned long)pack->ptr, BPF_PROG_PACK_SIZE / PAGE_SIZE);
911914
return pack;
@@ -952,8 +955,15 @@ void *bpf_prog_pack_alloc(u32 size, bpf_jit_fill_hole_t bpf_fill_ill_insns, bool
952955

953956
found_free_area:
954957
/* Flush only for cBPF as it may contain a crafted gadget */
955-
if (static_branch_unlikely(&bpf_pred_flush_enabled) && was_classic)
958+
if (static_branch_unlikely(&bpf_pred_flush_enabled) &&
959+
pack->arch_flush_needed &&
960+
was_classic) {
961+
struct bpf_prog_pack *p;
962+
956963
static_call_cond(bpf_arch_pred_flush)();
964+
list_for_each_entry(p, &pack_list, list)
965+
p->arch_flush_needed = false;
966+
}
957967
bitmap_set(pack->bitmap, pos, nbits);
958968
ptr = (void *)(pack->ptr) + (pos << BPF_PROG_CHUNK_SHIFT);
959969

@@ -991,6 +1001,9 @@ void bpf_prog_pack_free(struct bpf_binary_header *hdr)
9911001
"bpf_prog_pack bug: missing bpf_arch_text_invalidate?\n");
9921002

9931003
bitmap_clear(pack->bitmap, pos, nbits);
1004+
1005+
if (static_branch_unlikely(&bpf_pred_flush_enabled))
1006+
pack->arch_flush_needed = true;
9941007
if (bitmap_find_next_zero_area(pack->bitmap, BPF_PROG_CHUNK_COUNT, 0,
9951008
BPF_PROG_CHUNK_COUNT, 0) == 0) {
9961009
list_del(&pack->list);

0 commit comments

Comments
 (0)