Skip to content

Commit 9fd7aca

Browse files
committed
Merge branch 'bpf-misc-updates'
Daniel Borkmann says: ==================== Misc BPF updates This set contains a couple of misc updates: stack usage reduction for perf_sample_data in tracing progs, reduction of stale data in verifier on register state transitions that I still had in my queue and few selftest improvements as well as bpf_set_hash() helper for tc programs. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 41e8e40 + ded092c commit 9fd7aca

File tree

7 files changed

+102
-15
lines changed

7 files changed

+102
-15
lines changed

include/uapi/linux/bpf.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,11 @@ union bpf_attr {
513513
* Get the owner uid of the socket stored inside sk_buff.
514514
* @skb: pointer to skb
515515
* Return: uid of the socket owner on success or overflowuid if failed.
516+
*
517+
* u32 bpf_set_hash(skb, hash)
518+
* Set full skb->hash.
519+
* @skb: pointer to skb
520+
* @hash: hash to set
516521
*/
517522
#define __BPF_FUNC_MAPPER(FN) \
518523
FN(unspec), \
@@ -562,7 +567,8 @@ union bpf_attr {
562567
FN(xdp_adjust_head), \
563568
FN(probe_read_str), \
564569
FN(get_socket_cookie), \
565-
FN(get_socket_uid),
570+
FN(get_socket_uid), \
571+
FN(set_hash),
566572

567573
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
568574
* function eBPF program intends to call

kernel/bpf/verifier.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,8 +1346,8 @@ static void clear_all_pkt_pointers(struct bpf_verifier_env *env)
13461346
if (reg->type != PTR_TO_PACKET &&
13471347
reg->type != PTR_TO_PACKET_END)
13481348
continue;
1349-
reg->type = UNKNOWN_VALUE;
1350-
reg->imm = 0;
1349+
__mark_reg_unknown_value(state->spilled_regs,
1350+
i / BPF_REG_SIZE);
13511351
}
13521352
}
13531353

@@ -1952,6 +1952,7 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn)
19521952
*/
19531953
regs[insn->dst_reg].type = CONST_IMM;
19541954
regs[insn->dst_reg].imm = insn->imm;
1955+
regs[insn->dst_reg].id = 0;
19551956
regs[insn->dst_reg].max_value = insn->imm;
19561957
regs[insn->dst_reg].min_value = insn->imm;
19571958
regs[insn->dst_reg].min_align = calc_align(insn->imm);
@@ -2409,6 +2410,7 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
24092410

24102411
regs[insn->dst_reg].type = CONST_IMM;
24112412
regs[insn->dst_reg].imm = imm;
2413+
regs[insn->dst_reg].id = 0;
24122414
return 0;
24132415
}
24142416

@@ -2828,6 +2830,8 @@ static bool states_equal(struct bpf_verifier_env *env,
28282830
return false;
28292831
if (i % BPF_REG_SIZE)
28302832
continue;
2833+
if (old->stack_slot_type[i] != STACK_SPILL)
2834+
continue;
28312835
if (memcmp(&old->spilled_regs[i / BPF_REG_SIZE],
28322836
&cur->spilled_regs[i / BPF_REG_SIZE],
28332837
sizeof(old->spilled_regs[0])))

kernel/trace/bpf_trace.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -266,14 +266,16 @@ static const struct bpf_func_proto bpf_perf_event_read_proto = {
266266
.arg2_type = ARG_ANYTHING,
267267
};
268268

269+
static DEFINE_PER_CPU(struct perf_sample_data, bpf_sd);
270+
269271
static __always_inline u64
270272
__bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
271273
u64 flags, struct perf_raw_record *raw)
272274
{
273275
struct bpf_array *array = container_of(map, struct bpf_array, map);
276+
struct perf_sample_data *sd = this_cpu_ptr(&bpf_sd);
274277
unsigned int cpu = smp_processor_id();
275278
u64 index = flags & BPF_F_INDEX_MASK;
276-
struct perf_sample_data sample_data;
277279
struct bpf_event_entry *ee;
278280
struct perf_event *event;
279281

@@ -294,9 +296,9 @@ __bpf_perf_event_output(struct pt_regs *regs, struct bpf_map *map,
294296
if (unlikely(event->oncpu != cpu))
295297
return -EOPNOTSUPP;
296298

297-
perf_sample_data_init(&sample_data, 0, 0);
298-
sample_data.raw = raw;
299-
perf_event_output(event, &sample_data, regs);
299+
perf_sample_data_init(sd, 0, 0);
300+
sd->raw = raw;
301+
perf_event_output(event, sd, regs);
300302
return 0;
301303
}
302304

net/core/filter.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,6 +1874,24 @@ static const struct bpf_func_proto bpf_set_hash_invalid_proto = {
18741874
.arg1_type = ARG_PTR_TO_CTX,
18751875
};
18761876

1877+
BPF_CALL_2(bpf_set_hash, struct sk_buff *, skb, u32, hash)
1878+
{
1879+
/* Set user specified hash as L4(+), so that it gets returned
1880+
* on skb_get_hash() call unless BPF prog later on triggers a
1881+
* skb_clear_hash().
1882+
*/
1883+
__skb_set_sw_hash(skb, hash, true);
1884+
return 0;
1885+
}
1886+
1887+
static const struct bpf_func_proto bpf_set_hash_proto = {
1888+
.func = bpf_set_hash,
1889+
.gpl_only = false,
1890+
.ret_type = RET_INTEGER,
1891+
.arg1_type = ARG_PTR_TO_CTX,
1892+
.arg2_type = ARG_ANYTHING,
1893+
};
1894+
18771895
BPF_CALL_3(bpf_skb_vlan_push, struct sk_buff *, skb, __be16, vlan_proto,
18781896
u16, vlan_tci)
18791897
{
@@ -2744,6 +2762,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id)
27442762
return &bpf_get_hash_recalc_proto;
27452763
case BPF_FUNC_set_hash_invalid:
27462764
return &bpf_set_hash_invalid_proto;
2765+
case BPF_FUNC_set_hash:
2766+
return &bpf_set_hash_proto;
27472767
case BPF_FUNC_perf_event_output:
27482768
return &bpf_skb_event_output_proto;
27492769
case BPF_FUNC_get_smp_processor_id:
@@ -2774,12 +2794,6 @@ xdp_func_proto(enum bpf_func_id func_id)
27742794
}
27752795
}
27762796

2777-
static const struct bpf_func_proto *
2778-
cg_skb_func_proto(enum bpf_func_id func_id)
2779-
{
2780-
return sk_filter_func_proto(func_id);
2781-
}
2782-
27832797
static const struct bpf_func_proto *
27842798
lwt_inout_func_proto(enum bpf_func_id func_id)
27852799
{
@@ -3344,7 +3358,7 @@ const struct bpf_verifier_ops xdp_prog_ops = {
33443358
};
33453359

33463360
const struct bpf_verifier_ops cg_skb_prog_ops = {
3347-
.get_func_proto = cg_skb_func_proto,
3361+
.get_func_proto = sk_filter_func_proto,
33483362
.is_valid_access = sk_filter_is_valid_access,
33493363
.convert_ctx_access = bpf_convert_ctx_access,
33503364
.test_run = bpf_prog_test_run_skb,

tools/include/uapi/linux/bpf.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,11 @@ union bpf_attr {
513513
* Get the owner uid of the socket stored inside sk_buff.
514514
* @skb: pointer to skb
515515
* Return: uid of the socket owner on success or overflowuid if failed.
516+
*
517+
* u32 bpf_set_hash(skb, hash)
518+
* Set full skb->hash.
519+
* @skb: pointer to skb
520+
* @hash: hash to set
516521
*/
517522
#define __BPF_FUNC_MAPPER(FN) \
518523
FN(unspec), \
@@ -562,7 +567,8 @@ union bpf_attr {
562567
FN(xdp_adjust_head), \
563568
FN(probe_read_str), \
564569
FN(get_socket_cookie), \
565-
FN(get_socket_uid),
570+
FN(get_socket_uid), \
571+
FN(set_hash),
566572

567573
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
568574
* function eBPF program intends to call

tools/testing/selftests/bpf/test_align.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <stddef.h>
1010
#include <stdbool.h>
1111

12+
#include <sys/resource.h>
13+
1214
#include <linux/unistd.h>
1315
#include <linux/filter.h>
1416
#include <linux/bpf_perf_event.h>
@@ -432,6 +434,9 @@ static int do_test(unsigned int from, unsigned int to)
432434
int main(int argc, char **argv)
433435
{
434436
unsigned int from = 0, to = ARRAY_SIZE(tests);
437+
struct rlimit rinf = { RLIM_INFINITY, RLIM_INFINITY };
438+
439+
setrlimit(RLIMIT_MEMLOCK, &rinf);
435440

436441
if (argc == 3) {
437442
unsigned int l = atoi(argv[argc - 2]);

tools/testing/selftests/bpf/test_maps.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,54 @@ static void test_hashmap_percpu(int task, void *data)
239239
close(fd);
240240
}
241241

242+
static void test_hashmap_walk(int task, void *data)
243+
{
244+
int fd, i, max_entries = 100000;
245+
long long key, value, next_key;
246+
bool next_key_valid = true;
247+
248+
fd = bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(key), sizeof(value),
249+
max_entries, map_flags);
250+
if (fd < 0) {
251+
printf("Failed to create hashmap '%s'!\n", strerror(errno));
252+
exit(1);
253+
}
254+
255+
for (i = 0; i < max_entries; i++) {
256+
key = i; value = key;
257+
assert(bpf_map_update_elem(fd, &key, &value, BPF_NOEXIST) == 0);
258+
}
259+
260+
for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
261+
&next_key) == 0; i++) {
262+
key = next_key;
263+
assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
264+
}
265+
266+
assert(i == max_entries);
267+
268+
assert(bpf_map_get_next_key(fd, NULL, &key) == 0);
269+
for (i = 0; next_key_valid; i++) {
270+
next_key_valid = bpf_map_get_next_key(fd, &key, &next_key) == 0;
271+
assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
272+
value++;
273+
assert(bpf_map_update_elem(fd, &key, &value, BPF_EXIST) == 0);
274+
key = next_key;
275+
}
276+
277+
assert(i == max_entries);
278+
279+
for (i = 0; bpf_map_get_next_key(fd, !i ? NULL : &key,
280+
&next_key) == 0; i++) {
281+
key = next_key;
282+
assert(bpf_map_lookup_elem(fd, &key, &value) == 0);
283+
assert(value - 1 == key);
284+
}
285+
286+
assert(i == max_entries);
287+
close(fd);
288+
}
289+
242290
static void test_arraymap(int task, void *data)
243291
{
244292
int key, next_key, fd;
@@ -464,6 +512,7 @@ static void test_map_stress(void)
464512
run_parallel(100, test_hashmap, NULL);
465513
run_parallel(100, test_hashmap_percpu, NULL);
466514
run_parallel(100, test_hashmap_sizes, NULL);
515+
run_parallel(100, test_hashmap_walk, NULL);
467516

468517
run_parallel(100, test_arraymap, NULL);
469518
run_parallel(100, test_arraymap_percpu, NULL);
@@ -549,6 +598,7 @@ static void run_all_tests(void)
549598
{
550599
test_hashmap(0, NULL);
551600
test_hashmap_percpu(0, NULL);
601+
test_hashmap_walk(0, NULL);
552602

553603
test_arraymap(0, NULL);
554604
test_arraymap_percpu(0, NULL);

0 commit comments

Comments
 (0)