Skip to content

Commit e4c8f96

Browse files
committed
Merge branch 'veristat-memory-accounting-for-bpf-programs'
Eduard Zingerman says: ==================== veristat: memory accounting for bpf programs When working on the verifier, it is sometimes interesting to know how a particular change affects memory consumption. This patch-set modifies veristat to provide such information. As a collateral, kernel needs an update to make allocations reachable from BPF program load accountable in memcg statistics. Here is a sample output: Program Peak states Peak memory (MiB) --------------- ----------- ----------------- lavd_select_cpu 2153 43 lavd_enqueue 1982 41 lavd_dispatch 3480 28 Technically, this is implemented by creating and entering a new cgroup at the start of veristat execution. The difference between values from cgroup "memory.peak" file before and after bpf_object__load() is used as a metric. To minimize measurements jitter data is collected in megabytes. Changelog: v2: https://lore.kernel.org/bpf/[email protected]/ v2 -> v3: - bpf_verifier_state->jmp_history and bpf_verifier_env->explored_states allocations are switched from GFP_USER to GFP_KERNEL_ACCOUNT (Andrii, Alexei); - veristat.c:STR macro removed, PATH_MAX-1 == 4095 is hard-coded in scanf format strings (Andrii); - env->{orig,stat}_cgroup size changed to PATH_MAX (Andrii); - snprintf_trunc() is removed, flag -Wno-format-truncation is added to CFLAGS for veristat.o when compiled with gcc; v1: https://lore.kernel.org/bpf/[email protected]/ v1 -> v2: - a single cgroup, created at the beginning of execution, is now used for measurements (Andrii, Mykyta); - cgroup namespace is not created, as it turned out to be useless (Andrii); - veristat no longer mounts cgroup fs or changes subtree_control, instead it looks for an existing mount point and reports an error if memory.peak file can't be opened (Andrii, Alexei); - if 'mem_peak' statistics is not enabled, veristat skips cgroup setup; - code sharing with cgroup_helpers.c was considered but was decided against to simplify veristat github sync. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents ccefa19 + 67cdcc4 commit e4c8f96

File tree

4 files changed

+289
-48
lines changed

4 files changed

+289
-48
lines changed

kernel/bpf/btf.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3443,7 +3443,8 @@ btf_find_graph_root(const struct btf *btf, const struct btf_type *pt,
34433443
node_field_name = strstr(value_type, ":");
34443444
if (!node_field_name)
34453445
return -EINVAL;
3446-
value_type = kstrndup(value_type, node_field_name - value_type, GFP_KERNEL | __GFP_NOWARN);
3446+
value_type = kstrndup(value_type, node_field_name - value_type,
3447+
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
34473448
if (!value_type)
34483449
return -ENOMEM;
34493450
id = btf_find_by_name_kind(btf, value_type, BTF_KIND_STRUCT);
@@ -3958,7 +3959,7 @@ struct btf_record *btf_parse_fields(const struct btf *btf, const struct btf_type
39583959
/* This needs to be kzalloc to zero out padding and unused fields, see
39593960
* comment in btf_record_equal.
39603961
*/
3961-
rec = kzalloc(struct_size(rec, fields, cnt), GFP_KERNEL | __GFP_NOWARN);
3962+
rec = kzalloc(struct_size(rec, fields, cnt), GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
39623963
if (!rec)
39633964
return ERR_PTR(-ENOMEM);
39643965

@@ -9019,15 +9020,15 @@ static struct bpf_cand_cache *populate_cand_cache(struct bpf_cand_cache *cands,
90199020
bpf_free_cands_from_cache(*cc);
90209021
*cc = NULL;
90219022
}
9022-
new_cands = kmemdup(cands, sizeof_cands(cands->cnt), GFP_KERNEL);
9023+
new_cands = kmemdup(cands, sizeof_cands(cands->cnt), GFP_KERNEL_ACCOUNT);
90239024
if (!new_cands) {
90249025
bpf_free_cands(cands);
90259026
return ERR_PTR(-ENOMEM);
90269027
}
90279028
/* strdup the name, since it will stay in cache.
90289029
* the cands->name points to strings in prog's BTF and the prog can be unloaded.
90299030
*/
9030-
new_cands->name = kmemdup_nul(cands->name, cands->name_len, GFP_KERNEL);
9031+
new_cands->name = kmemdup_nul(cands->name, cands->name_len, GFP_KERNEL_ACCOUNT);
90319032
bpf_free_cands(cands);
90329033
if (!new_cands->name) {
90339034
kfree(new_cands);
@@ -9111,7 +9112,7 @@ bpf_core_add_cands(struct bpf_cand_cache *cands, const struct btf *targ_btf,
91119112
continue;
91129113

91139114
/* most of the time there is only one candidate for a given kind+name pair */
9114-
new_cands = kmalloc(sizeof_cands(cands->cnt + 1), GFP_KERNEL);
9115+
new_cands = kmalloc(sizeof_cands(cands->cnt + 1), GFP_KERNEL_ACCOUNT);
91159116
if (!new_cands) {
91169117
bpf_free_cands(cands);
91179118
return ERR_PTR(-ENOMEM);
@@ -9228,7 +9229,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
92289229
/* ~4k of temp memory necessary to convert LLVM spec like "0:1:0:5"
92299230
* into arrays of btf_ids of struct fields and array indices.
92309231
*/
9231-
specs = kcalloc(3, sizeof(*specs), GFP_KERNEL);
9232+
specs = kcalloc(3, sizeof(*specs), GFP_KERNEL_ACCOUNT);
92329233
if (!specs)
92339234
return -ENOMEM;
92349235

@@ -9253,7 +9254,7 @@ int bpf_core_apply(struct bpf_core_ctx *ctx, const struct bpf_core_relo *relo,
92539254
goto out;
92549255
}
92559256
if (cc->cnt) {
9256-
cands.cands = kcalloc(cc->cnt, sizeof(*cands.cands), GFP_KERNEL);
9257+
cands.cands = kcalloc(cc->cnt, sizeof(*cands.cands), GFP_KERNEL_ACCOUNT);
92579258
if (!cands.cands) {
92589259
err = -ENOMEM;
92599260
goto out;

kernel/bpf/verifier.c

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size)
14041404
goto out;
14051405

14061406
alloc_size = kmalloc_size_roundup(size_mul(new_n, size));
1407-
new_arr = krealloc(arr, alloc_size, GFP_KERNEL);
1407+
new_arr = krealloc(arr, alloc_size, GFP_KERNEL_ACCOUNT);
14081408
if (!new_arr) {
14091409
kfree(arr);
14101410
return NULL;
@@ -1421,7 +1421,7 @@ static void *realloc_array(void *arr, size_t old_n, size_t new_n, size_t size)
14211421
static int copy_reference_state(struct bpf_verifier_state *dst, const struct bpf_verifier_state *src)
14221422
{
14231423
dst->refs = copy_array(dst->refs, src->refs, src->acquired_refs,
1424-
sizeof(struct bpf_reference_state), GFP_KERNEL);
1424+
sizeof(struct bpf_reference_state), GFP_KERNEL_ACCOUNT);
14251425
if (!dst->refs)
14261426
return -ENOMEM;
14271427

@@ -1440,7 +1440,7 @@ static int copy_stack_state(struct bpf_func_state *dst, const struct bpf_func_st
14401440
size_t n = src->allocated_stack / BPF_REG_SIZE;
14411441

14421442
dst->stack = copy_array(dst->stack, src->stack, n, sizeof(struct bpf_stack_state),
1443-
GFP_KERNEL);
1443+
GFP_KERNEL_ACCOUNT);
14441444
if (!dst->stack)
14451445
return -ENOMEM;
14461446

@@ -1731,7 +1731,7 @@ static int copy_verifier_state(struct bpf_verifier_state *dst_state,
17311731

17321732
dst_state->jmp_history = copy_array(dst_state->jmp_history, src->jmp_history,
17331733
src->jmp_history_cnt, sizeof(*dst_state->jmp_history),
1734-
GFP_USER);
1734+
GFP_KERNEL_ACCOUNT);
17351735
if (!dst_state->jmp_history)
17361736
return -ENOMEM;
17371737
dst_state->jmp_history_cnt = src->jmp_history_cnt;
@@ -1760,7 +1760,7 @@ static int copy_verifier_state(struct bpf_verifier_state *dst_state,
17601760
for (i = 0; i <= src->curframe; i++) {
17611761
dst = dst_state->frame[i];
17621762
if (!dst) {
1763-
dst = kzalloc(sizeof(*dst), GFP_KERNEL);
1763+
dst = kzalloc(sizeof(*dst), GFP_KERNEL_ACCOUNT);
17641764
if (!dst)
17651765
return -ENOMEM;
17661766
dst_state->frame[i] = dst;
@@ -1874,7 +1874,7 @@ static struct bpf_scc_visit *scc_visit_alloc(struct bpf_verifier_env *env,
18741874
info = env->scc_info[scc];
18751875
num_visits = info ? info->num_visits : 0;
18761876
new_sz = sizeof(*info) + sizeof(struct bpf_scc_visit) * (num_visits + 1);
1877-
info = kvrealloc(env->scc_info[scc], new_sz, GFP_KERNEL);
1877+
info = kvrealloc(env->scc_info[scc], new_sz, GFP_KERNEL_ACCOUNT);
18781878
if (!info)
18791879
return NULL;
18801880
env->scc_info[scc] = info;
@@ -2095,7 +2095,7 @@ static struct bpf_verifier_state *push_stack(struct bpf_verifier_env *env,
20952095
struct bpf_verifier_stack_elem *elem;
20962096
int err;
20972097

2098-
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL);
2098+
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL_ACCOUNT);
20992099
if (!elem)
21002100
goto err;
21012101

@@ -2862,7 +2862,7 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env,
28622862
struct bpf_verifier_stack_elem *elem;
28632863
struct bpf_func_state *frame;
28642864

2865-
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL);
2865+
elem = kzalloc(sizeof(struct bpf_verifier_stack_elem), GFP_KERNEL_ACCOUNT);
28662866
if (!elem)
28672867
goto err;
28682868

@@ -2885,7 +2885,7 @@ static struct bpf_verifier_state *push_async_cb(struct bpf_verifier_env *env,
28852885
*/
28862886
elem->st.branches = 1;
28872887
elem->st.in_sleepable = is_sleepable;
2888-
frame = kzalloc(sizeof(*frame), GFP_KERNEL);
2888+
frame = kzalloc(sizeof(*frame), GFP_KERNEL_ACCOUNT);
28892889
if (!frame)
28902890
goto err;
28912891
init_func_state(env, frame,
@@ -3237,7 +3237,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
32373237
return -EINVAL;
32383238
}
32393239

3240-
tab = kzalloc(sizeof(*tab), GFP_KERNEL);
3240+
tab = kzalloc(sizeof(*tab), GFP_KERNEL_ACCOUNT);
32413241
if (!tab)
32423242
return -ENOMEM;
32433243
prog_aux->kfunc_tab = tab;
@@ -3253,7 +3253,7 @@ static int add_kfunc_call(struct bpf_verifier_env *env, u32 func_id, s16 offset)
32533253
return 0;
32543254

32553255
if (!btf_tab && offset) {
3256-
btf_tab = kzalloc(sizeof(*btf_tab), GFP_KERNEL);
3256+
btf_tab = kzalloc(sizeof(*btf_tab), GFP_KERNEL_ACCOUNT);
32573257
if (!btf_tab)
32583258
return -ENOMEM;
32593259
prog_aux->kfunc_btf_tab = btf_tab;
@@ -3939,7 +3939,7 @@ static int push_jmp_history(struct bpf_verifier_env *env, struct bpf_verifier_st
39393939

39403940
cnt++;
39413941
alloc_size = kmalloc_size_roundup(size_mul(cnt, sizeof(*p)));
3942-
p = krealloc(cur->jmp_history, alloc_size, GFP_USER);
3942+
p = krealloc(cur->jmp_history, alloc_size, GFP_KERNEL_ACCOUNT);
39433943
if (!p)
39443944
return -ENOMEM;
39453945
cur->jmp_history = p;
@@ -10356,7 +10356,7 @@ static int setup_func_entry(struct bpf_verifier_env *env, int subprog, int calls
1035610356
}
1035710357

1035810358
caller = state->frame[state->curframe];
10359-
callee = kzalloc(sizeof(*callee), GFP_KERNEL);
10359+
callee = kzalloc(sizeof(*callee), GFP_KERNEL_ACCOUNT);
1036010360
if (!callee)
1036110361
return -ENOMEM;
1036210362
state->frame[state->curframe + 1] = callee;
@@ -17693,17 +17693,18 @@ static int check_cfg(struct bpf_verifier_env *env)
1769317693
int *insn_stack, *insn_state, *insn_postorder;
1769417694
int ex_insn_beg, i, ret = 0;
1769517695

17696-
insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
17696+
insn_state = env->cfg.insn_state = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
1769717697
if (!insn_state)
1769817698
return -ENOMEM;
1769917699

17700-
insn_stack = env->cfg.insn_stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
17700+
insn_stack = env->cfg.insn_stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
1770117701
if (!insn_stack) {
1770217702
kvfree(insn_state);
1770317703
return -ENOMEM;
1770417704
}
1770517705

17706-
insn_postorder = env->cfg.insn_postorder = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
17706+
insn_postorder = env->cfg.insn_postorder =
17707+
kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
1770717708
if (!insn_postorder) {
1770817709
kvfree(insn_state);
1770917710
kvfree(insn_stack);
@@ -17837,7 +17838,7 @@ static int check_btf_func_early(struct bpf_verifier_env *env,
1783717838
urecord = make_bpfptr(attr->func_info, uattr.is_kernel);
1783817839
min_size = min_t(u32, krec_size, urec_size);
1783917840

17840-
krecord = kvcalloc(nfuncs, krec_size, GFP_KERNEL | __GFP_NOWARN);
17841+
krecord = kvcalloc(nfuncs, krec_size, GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
1784117842
if (!krecord)
1784217843
return -ENOMEM;
1784317844

@@ -17937,7 +17938,7 @@ static int check_btf_func(struct bpf_verifier_env *env,
1793717938
urecord = make_bpfptr(attr->func_info, uattr.is_kernel);
1793817939

1793917940
krecord = prog->aux->func_info;
17940-
info_aux = kcalloc(nfuncs, sizeof(*info_aux), GFP_KERNEL | __GFP_NOWARN);
17941+
info_aux = kcalloc(nfuncs, sizeof(*info_aux), GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
1794117942
if (!info_aux)
1794217943
return -ENOMEM;
1794317944

@@ -18023,7 +18024,7 @@ static int check_btf_line(struct bpf_verifier_env *env,
1802318024
* pass in a smaller bpf_line_info object.
1802418025
*/
1802518026
linfo = kvcalloc(nr_linfo, sizeof(struct bpf_line_info),
18026-
GFP_KERNEL | __GFP_NOWARN);
18027+
GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
1802718028
if (!linfo)
1802818029
return -ENOMEM;
1802918030

@@ -19408,7 +19409,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
1940819409
if (loop) {
1940919410
struct bpf_scc_backedge *backedge;
1941019411

19411-
backedge = kzalloc(sizeof(*backedge), GFP_KERNEL);
19412+
backedge = kzalloc(sizeof(*backedge), GFP_KERNEL_ACCOUNT);
1941219413
if (!backedge)
1941319414
return -ENOMEM;
1941419415
err = copy_verifier_state(&backedge->state, cur);
@@ -19472,7 +19473,7 @@ static int is_state_visited(struct bpf_verifier_env *env, int insn_idx)
1947219473
* When looping the sl->state.branches will be > 0 and this state
1947319474
* will not be considered for equivalence until branches == 0.
1947419475
*/
19475-
new_sl = kzalloc(sizeof(struct bpf_verifier_state_list), GFP_KERNEL);
19476+
new_sl = kzalloc(sizeof(struct bpf_verifier_state_list), GFP_KERNEL_ACCOUNT);
1947619477
if (!new_sl)
1947719478
return -ENOMEM;
1947819479
env->total_states++;
@@ -22976,13 +22977,13 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
2297622977
env->prev_linfo = NULL;
2297722978
env->pass_cnt++;
2297822979

22979-
state = kzalloc(sizeof(struct bpf_verifier_state), GFP_KERNEL);
22980+
state = kzalloc(sizeof(struct bpf_verifier_state), GFP_KERNEL_ACCOUNT);
2298022981
if (!state)
2298122982
return -ENOMEM;
2298222983
state->curframe = 0;
2298322984
state->speculative = false;
2298422985
state->branches = 1;
22985-
state->frame[0] = kzalloc(sizeof(struct bpf_func_state), GFP_KERNEL);
22986+
state->frame[0] = kzalloc(sizeof(struct bpf_func_state), GFP_KERNEL_ACCOUNT);
2298622987
if (!state->frame[0]) {
2298722988
kfree(state);
2298822989
return -ENOMEM;
@@ -23208,7 +23209,7 @@ static void print_verification_stats(struct bpf_verifier_env *env)
2320823209
int bpf_prog_ctx_arg_info_init(struct bpf_prog *prog,
2320923210
const struct bpf_ctx_arg_aux *info, u32 cnt)
2321023211
{
23211-
prog->aux->ctx_arg_info = kmemdup_array(info, cnt, sizeof(*info), GFP_KERNEL);
23212+
prog->aux->ctx_arg_info = kmemdup_array(info, cnt, sizeof(*info), GFP_KERNEL_ACCOUNT);
2321223213
prog->aux->ctx_arg_info_size = cnt;
2321323214

2321423215
return prog->aux->ctx_arg_info ? 0 : -ENOMEM;
@@ -24152,7 +24153,7 @@ static int compute_live_registers(struct bpf_verifier_env *env)
2415224153
* - repeat the computation while {in,out} fields changes for
2415324154
* any instruction.
2415424155
*/
24155-
state = kvcalloc(insn_cnt, sizeof(*state), GFP_KERNEL);
24156+
state = kvcalloc(insn_cnt, sizeof(*state), GFP_KERNEL_ACCOUNT);
2415624157
if (!state) {
2415724158
err = -ENOMEM;
2415824159
goto out;
@@ -24244,10 +24245,10 @@ static int compute_scc(struct bpf_verifier_env *env)
2424424245
* - 'low[t] == n' => smallest preorder number of the vertex reachable from 't' is 'n';
2424524246
* - 'dfs' DFS traversal stack, used to emulate explicit recursion.
2424624247
*/
24247-
stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
24248-
pre = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
24249-
low = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL);
24250-
dfs = kvcalloc(insn_cnt, sizeof(*dfs), GFP_KERNEL);
24248+
stack = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
24249+
pre = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
24250+
low = kvcalloc(insn_cnt, sizeof(int), GFP_KERNEL_ACCOUNT);
24251+
dfs = kvcalloc(insn_cnt, sizeof(*dfs), GFP_KERNEL_ACCOUNT);
2425124252
if (!stack || !pre || !low || !dfs) {
2425224253
err = -ENOMEM;
2425324254
goto exit;
@@ -24381,7 +24382,7 @@ static int compute_scc(struct bpf_verifier_env *env)
2438124382
dfs_sz--;
2438224383
}
2438324384
}
24384-
env->scc_info = kvcalloc(next_scc_id, sizeof(*env->scc_info), GFP_KERNEL);
24385+
env->scc_info = kvcalloc(next_scc_id, sizeof(*env->scc_info), GFP_KERNEL_ACCOUNT);
2438524386
if (!env->scc_info) {
2438624387
err = -ENOMEM;
2438724388
goto exit;
@@ -24409,7 +24410,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2440924410
/* 'struct bpf_verifier_env' can be global, but since it's not small,
2441024411
* allocate/free it every time bpf_check() is called
2441124412
*/
24412-
env = kvzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL);
24413+
env = kvzalloc(sizeof(struct bpf_verifier_env), GFP_KERNEL_ACCOUNT);
2441324414
if (!env)
2441424415
return -ENOMEM;
2441524416

@@ -24472,7 +24473,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2447224473

2447324474
env->explored_states = kvcalloc(state_htab_size(env),
2447424475
sizeof(struct list_head),
24475-
GFP_USER);
24476+
GFP_KERNEL_ACCOUNT);
2447624477
ret = -ENOMEM;
2447724478
if (!env->explored_states)
2447824479
goto skip_full_check;
@@ -24603,7 +24604,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2460324604
/* if program passed verifier, update used_maps in bpf_prog_info */
2460424605
env->prog->aux->used_maps = kmalloc_array(env->used_map_cnt,
2460524606
sizeof(env->used_maps[0]),
24606-
GFP_KERNEL);
24607+
GFP_KERNEL_ACCOUNT);
2460724608

2460824609
if (!env->prog->aux->used_maps) {
2460924610
ret = -ENOMEM;
@@ -24618,7 +24619,7 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr, __u3
2461824619
/* if program passed verifier, update used_btfs in bpf_prog_aux */
2461924620
env->prog->aux->used_btfs = kmalloc_array(env->used_btf_cnt,
2462024621
sizeof(env->used_btfs[0]),
24621-
GFP_KERNEL);
24622+
GFP_KERNEL_ACCOUNT);
2462224623
if (!env->prog->aux->used_btfs) {
2462324624
ret = -ENOMEM;
2462424625
goto err_release_maps;

tools/testing/selftests/bpf/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,11 @@ $(OUTPUT)/bench: $(OUTPUT)/bench.o \
841841
$(call msg,BINARY,,$@)
842842
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) $(filter %.a %.o,$^) $(LDLIBS) -o $@
843843

844+
# This works around GCC warning about snprintf truncating strings like:
845+
#
846+
# char a[PATH_MAX], b[PATH_MAX];
847+
# snprintf(a, "%s/foo", b); // triggers -Wformat-truncation
848+
$(OUTPUT)/veristat.o: CFLAGS += -Wno-format-truncation
844849
$(OUTPUT)/veristat.o: $(BPFOBJ)
845850
$(OUTPUT)/veristat: $(OUTPUT)/veristat.o
846851
$(call msg,BINARY,,$@)

0 commit comments

Comments
 (0)