Skip to content

Commit 0790fd9

Browse files
sidchintamaneniKernel Patches Daemon
authored andcommitted
bpf: Introduce new structs and struct fields for fast path termination
Introduced the definition of struct bpf_term_aux_states required to support fast-path termination of BPF programs. Added the memory allocation and free logic for newly added term_states feild in struct bpf_prog. Signed-off-by: Raj Sahu <[email protected]> Signed-off-by: Siddharth Chintamaneni <[email protected]>
1 parent 2d215b0 commit 0790fd9

File tree

2 files changed

+79
-27
lines changed

2 files changed

+79
-27
lines changed

include/linux/bpf.h

Lines changed: 48 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1584,6 +1584,25 @@ struct bpf_stream_stage {
15841584
int len;
15851585
};
15861586

1587+
struct call_aux_states {
1588+
int call_bpf_insn_idx;
1589+
int jit_call_idx;
1590+
u8 is_helper_kfunc;
1591+
u8 is_bpf_loop;
1592+
u8 is_bpf_loop_cb_inline;
1593+
};
1594+
1595+
struct bpf_term_patch_call_sites {
1596+
u32 call_sites_cnt;
1597+
struct call_aux_states *call_states;
1598+
};
1599+
1600+
struct bpf_term_aux_states {
1601+
struct bpf_prog *prog;
1602+
struct work_struct work;
1603+
struct bpf_term_patch_call_sites *patch_call_sites;
1604+
};
1605+
15871606
struct bpf_prog_aux {
15881607
atomic64_t refcnt;
15891608
u32 used_map_cnt;
@@ -1618,6 +1637,7 @@ struct bpf_prog_aux {
16181637
bool tail_call_reachable;
16191638
bool xdp_has_frags;
16201639
bool exception_cb;
1640+
bool is_bpf_loop_cb_non_inline;
16211641
bool exception_boundary;
16221642
bool is_extended; /* true if extended by freplace program */
16231643
bool jits_use_priv_stack;
@@ -1696,33 +1716,34 @@ struct bpf_prog_aux {
16961716
};
16971717

16981718
struct bpf_prog {
1699-
u16 pages; /* Number of allocated pages */
1700-
u16 jited:1, /* Is our filter JIT'ed? */
1701-
jit_requested:1,/* archs need to JIT the prog */
1702-
gpl_compatible:1, /* Is filter GPL compatible? */
1703-
cb_access:1, /* Is control block accessed? */
1704-
dst_needed:1, /* Do we need dst entry? */
1705-
blinding_requested:1, /* needs constant blinding */
1706-
blinded:1, /* Was blinded */
1707-
is_func:1, /* program is a bpf function */
1708-
kprobe_override:1, /* Do we override a kprobe? */
1709-
has_callchain_buf:1, /* callchain buffer allocated? */
1710-
enforce_expected_attach_type:1, /* Enforce expected_attach_type checking at attach time */
1711-
call_get_stack:1, /* Do we call bpf_get_stack() or bpf_get_stackid() */
1712-
call_get_func_ip:1, /* Do we call get_func_ip() */
1713-
tstamp_type_access:1, /* Accessed __sk_buff->tstamp_type */
1714-
sleepable:1; /* BPF program is sleepable */
1715-
enum bpf_prog_type type; /* Type of BPF program */
1716-
enum bpf_attach_type expected_attach_type; /* For some prog types */
1717-
u32 len; /* Number of filter blocks */
1718-
u32 jited_len; /* Size of jited insns in bytes */
1719-
u8 tag[BPF_TAG_SIZE];
1720-
struct bpf_prog_stats __percpu *stats;
1721-
int __percpu *active;
1722-
unsigned int (*bpf_func)(const void *ctx,
1723-
const struct bpf_insn *insn);
1724-
struct bpf_prog_aux *aux; /* Auxiliary fields */
1725-
struct sock_fprog_kern *orig_prog; /* Original BPF program */
1719+
u16 pages; /* Number of allocated pages */
1720+
u16 jited:1, /* Is our filter JIT'ed? */
1721+
jit_requested:1,/* archs need to JIT the prog */
1722+
gpl_compatible:1, /* Is filter GPL compatible? */
1723+
cb_access:1, /* Is control block accessed? */
1724+
dst_needed:1, /* Do we need dst entry? */
1725+
blinding_requested:1, /* needs constant blinding */
1726+
blinded:1, /* Was blinded */
1727+
is_func:1, /* program is a bpf function */
1728+
kprobe_override:1, /* Do we override a kprobe? */
1729+
has_callchain_buf:1, /* callchain buffer allocated? */
1730+
enforce_expected_attach_type:1, /* Enforce expected_attach_type checking at attach time */
1731+
call_get_stack:1, /* Do we call bpf_get_stack() or bpf_get_stackid() */
1732+
call_get_func_ip:1, /* Do we call get_func_ip() */
1733+
tstamp_type_access:1, /* Accessed __sk_buff->tstamp_type */
1734+
sleepable:1; /* BPF program is sleepable */
1735+
enum bpf_prog_type type; /* Type of BPF program */
1736+
enum bpf_attach_type expected_attach_type; /* For some prog types */
1737+
u32 len; /* Number of filter blocks */
1738+
u32 jited_len; /* Size of jited insns in bytes */
1739+
u8 tag[BPF_TAG_SIZE];
1740+
struct bpf_prog_stats __percpu *stats;
1741+
int __percpu *active;
1742+
unsigned int (*bpf_func)(const void *ctx,
1743+
const struct bpf_insn *insn);
1744+
struct bpf_prog_aux *aux; /* Auxiliary fields */
1745+
struct sock_fprog_kern *orig_prog; /* Original BPF program */
1746+
struct bpf_term_aux_states *term_states;
17261747
/* Instructions for interpreter */
17271748
union {
17281749
DECLARE_FLEX_ARRAY(struct sock_filter, insns);

kernel/bpf/core.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
100100
gfp_t gfp_flags = bpf_memcg_flags(GFP_KERNEL | __GFP_ZERO | gfp_extra_flags);
101101
struct bpf_prog_aux *aux;
102102
struct bpf_prog *fp;
103+
struct bpf_term_aux_states *term_states = NULL;
104+
struct bpf_term_patch_call_sites *patch_call_sites = NULL;
103105

104106
size = round_up(size, __PAGE_SIZE);
105107
fp = __vmalloc(size, gfp_flags);
@@ -118,11 +120,24 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
118120
return NULL;
119121
}
120122

123+
term_states = kzalloc(sizeof(*term_states), bpf_memcg_flags(GFP_KERNEL | gfp_extra_flags));
124+
if (!term_states)
125+
goto free_alloc_percpu;
126+
127+
patch_call_sites = kzalloc(sizeof(*patch_call_sites), bpf_memcg_flags(GFP_KERNEL | gfp_extra_flags));
128+
if (!patch_call_sites)
129+
goto free_bpf_term_states;
130+
121131
fp->pages = size / PAGE_SIZE;
122132
fp->aux = aux;
123133
fp->aux->prog = fp;
124134
fp->jit_requested = ebpf_jit_enabled();
125135
fp->blinding_requested = bpf_jit_blinding_enabled(fp);
136+
fp->term_states = term_states;
137+
fp->term_states->patch_call_sites = patch_call_sites;
138+
fp->term_states->patch_call_sites->call_sites_cnt = 0;
139+
fp->term_states->prog = fp;
140+
126141
#ifdef CONFIG_CGROUP_BPF
127142
aux->cgroup_atype = CGROUP_BPF_ATTACH_TYPE_INVALID;
128143
#endif
@@ -140,6 +155,15 @@ struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flag
140155
#endif
141156

142157
return fp;
158+
159+
free_bpf_term_states:
160+
kfree(term_states);
161+
free_alloc_percpu:
162+
free_percpu(fp->active);
163+
kfree(aux);
164+
vfree(fp);
165+
166+
return NULL;
143167
}
144168

145169
struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags)
@@ -266,13 +290,15 @@ struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
266290
memcpy(fp, fp_old, fp_old->pages * PAGE_SIZE);
267291
fp->pages = pages;
268292
fp->aux->prog = fp;
293+
fp->term_states->prog = fp;
269294

270295
/* We keep fp->aux from fp_old around in the new
271296
* reallocated structure.
272297
*/
273298
fp_old->aux = NULL;
274299
fp_old->stats = NULL;
275300
fp_old->active = NULL;
301+
fp_old->term_states = NULL;
276302
__bpf_prog_free(fp_old);
277303
}
278304

@@ -287,6 +313,11 @@ void __bpf_prog_free(struct bpf_prog *fp)
287313
kfree(fp->aux->poke_tab);
288314
kfree(fp->aux);
289315
}
316+
if (fp->term_states) {
317+
if (fp->term_states->patch_call_sites)
318+
kfree(fp->term_states->patch_call_sites);
319+
kfree(fp->term_states);
320+
}
290321
free_percpu(fp->stats);
291322
free_percpu(fp->active);
292323
vfree(fp);

0 commit comments

Comments
 (0)