Skip to content

Commit a7bc577

Browse files
committed
Merge branch 'xdp-bpf-fixes'
John Fastabend says: ==================== net: Fixes for XDP/BPF The following fixes, UAPI updates, and small improvement, i. XDP needs to be called inside RCU with preempt disabled. ii. Not strictly a bug fix but we have an attach command in the sockmap UAPI already to avoid having a single kernel released with only the attach and not the detach I'm pushing this into net branch. Its early in the RC cycle so I think this is OK (not ideal but better than supporting a UAPI with a missing detach forever). iii. Final patch replace cpu_relax with cond_resched in devmap. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents 109980b + 374fb01 commit a7bc577

File tree

6 files changed

+89
-26
lines changed

6 files changed

+89
-26
lines changed

include/linux/bpf.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -385,16 +385,16 @@ static inline void __dev_map_flush(struct bpf_map *map)
385385

386386
#if defined(CONFIG_STREAM_PARSER) && defined(CONFIG_BPF_SYSCALL)
387387
struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key);
388-
int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
388+
int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type);
389389
#else
390390
static inline struct sock *__sock_map_lookup_elem(struct bpf_map *map, u32 key)
391391
{
392392
return NULL;
393393
}
394394

395-
static inline int sock_map_attach_prog(struct bpf_map *map,
396-
struct bpf_prog *prog,
397-
u32 type)
395+
static inline int sock_map_prog(struct bpf_map *map,
396+
struct bpf_prog *prog,
397+
u32 type)
398398
{
399399
return -EOPNOTSUPP;
400400
}

kernel/bpf/devmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ static void dev_map_free(struct bpf_map *map)
159159
unsigned long *bitmap = per_cpu_ptr(dtab->flush_needed, cpu);
160160

161161
while (!bitmap_empty(bitmap, dtab->map.max_entries))
162-
cpu_relax();
162+
cond_resched();
163163
}
164164

165165
for (i = 0; i < dtab->map.max_entries; i++) {

kernel/bpf/sockmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -792,7 +792,7 @@ static int sock_map_ctx_update_elem(struct bpf_sock_ops_kern *skops,
792792
return err;
793793
}
794794

795-
int sock_map_attach_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)
795+
int sock_map_prog(struct bpf_map *map, struct bpf_prog *prog, u32 type)
796796
{
797797
struct bpf_stab *stab = container_of(map, struct bpf_stab, map);
798798
struct bpf_prog *orig;

kernel/bpf/syscall.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1096,10 +1096,10 @@ static int bpf_obj_get(const union bpf_attr *attr)
10961096

10971097
#define BPF_PROG_ATTACH_LAST_FIELD attach_flags
10981098

1099-
static int sockmap_get_from_fd(const union bpf_attr *attr)
1099+
static int sockmap_get_from_fd(const union bpf_attr *attr, bool attach)
11001100
{
1101+
struct bpf_prog *prog = NULL;
11011102
int ufd = attr->target_fd;
1102-
struct bpf_prog *prog;
11031103
struct bpf_map *map;
11041104
struct fd f;
11051105
int err;
@@ -1109,16 +1109,20 @@ static int sockmap_get_from_fd(const union bpf_attr *attr)
11091109
if (IS_ERR(map))
11101110
return PTR_ERR(map);
11111111

1112-
prog = bpf_prog_get_type(attr->attach_bpf_fd, BPF_PROG_TYPE_SK_SKB);
1113-
if (IS_ERR(prog)) {
1114-
fdput(f);
1115-
return PTR_ERR(prog);
1112+
if (attach) {
1113+
prog = bpf_prog_get_type(attr->attach_bpf_fd,
1114+
BPF_PROG_TYPE_SK_SKB);
1115+
if (IS_ERR(prog)) {
1116+
fdput(f);
1117+
return PTR_ERR(prog);
1118+
}
11161119
}
11171120

1118-
err = sock_map_attach_prog(map, prog, attr->attach_type);
1121+
err = sock_map_prog(map, prog, attr->attach_type);
11191122
if (err) {
11201123
fdput(f);
1121-
bpf_prog_put(prog);
1124+
if (prog)
1125+
bpf_prog_put(prog);
11221126
return err;
11231127
}
11241128

@@ -1155,7 +1159,7 @@ static int bpf_prog_attach(const union bpf_attr *attr)
11551159
break;
11561160
case BPF_SK_SKB_STREAM_PARSER:
11571161
case BPF_SK_SKB_STREAM_VERDICT:
1158-
return sockmap_get_from_fd(attr);
1162+
return sockmap_get_from_fd(attr, true);
11591163
default:
11601164
return -EINVAL;
11611165
}
@@ -1204,7 +1208,10 @@ static int bpf_prog_detach(const union bpf_attr *attr)
12041208
ret = cgroup_bpf_update(cgrp, NULL, attr->attach_type, false);
12051209
cgroup_put(cgrp);
12061210
break;
1207-
1211+
case BPF_SK_SKB_STREAM_PARSER:
1212+
case BPF_SK_SKB_STREAM_VERDICT:
1213+
ret = sockmap_get_from_fd(attr, false);
1214+
break;
12081215
default:
12091216
return -EINVAL;
12101217
}

net/core/dev.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3981,8 +3981,13 @@ static int netif_rx_internal(struct sk_buff *skb)
39813981
trace_netif_rx(skb);
39823982

39833983
if (static_key_false(&generic_xdp_needed)) {
3984-
int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog),
3985-
skb);
3984+
int ret;
3985+
3986+
preempt_disable();
3987+
rcu_read_lock();
3988+
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
3989+
rcu_read_unlock();
3990+
preempt_enable();
39863991

39873992
/* Consider XDP consuming the packet a success from
39883993
* the netdev point of view we do not want to count
@@ -4500,18 +4505,20 @@ static int netif_receive_skb_internal(struct sk_buff *skb)
45004505
if (skb_defer_rx_timestamp(skb))
45014506
return NET_RX_SUCCESS;
45024507

4503-
rcu_read_lock();
4504-
45054508
if (static_key_false(&generic_xdp_needed)) {
4506-
int ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog),
4507-
skb);
4509+
int ret;
45084510

4509-
if (ret != XDP_PASS) {
4510-
rcu_read_unlock();
4511+
preempt_disable();
4512+
rcu_read_lock();
4513+
ret = do_xdp_generic(rcu_dereference(skb->dev->xdp_prog), skb);
4514+
rcu_read_unlock();
4515+
preempt_enable();
4516+
4517+
if (ret != XDP_PASS)
45114518
return NET_RX_DROP;
4512-
}
45134519
}
45144520

4521+
rcu_read_lock();
45154522
#ifdef CONFIG_RPS
45164523
if (static_key_false(&rps_needed)) {
45174524
struct rps_dev_flow voidflow, *rflow = &voidflow;

tools/testing/selftests/bpf/test_maps.c

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -558,7 +558,7 @@ static void test_sockmap(int tasks, void *data)
558558
}
559559
}
560560

561-
/* Test attaching bad fds */
561+
/* Test attaching/detaching bad fds */
562562
err = bpf_prog_attach(-1, fd, BPF_SK_SKB_STREAM_PARSER, 0);
563563
if (!err) {
564564
printf("Failed invalid parser prog attach\n");
@@ -571,6 +571,30 @@ static void test_sockmap(int tasks, void *data)
571571
goto out_sockmap;
572572
}
573573

574+
err = bpf_prog_attach(-1, fd, __MAX_BPF_ATTACH_TYPE, 0);
575+
if (!err) {
576+
printf("Failed unknown prog attach\n");
577+
goto out_sockmap;
578+
}
579+
580+
err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_PARSER);
581+
if (err) {
582+
printf("Failed empty parser prog detach\n");
583+
goto out_sockmap;
584+
}
585+
586+
err = bpf_prog_detach(fd, BPF_SK_SKB_STREAM_VERDICT);
587+
if (err) {
588+
printf("Failed empty verdict prog detach\n");
589+
goto out_sockmap;
590+
}
591+
592+
err = bpf_prog_detach(fd, __MAX_BPF_ATTACH_TYPE);
593+
if (!err) {
594+
printf("Detach invalid prog successful\n");
595+
goto out_sockmap;
596+
}
597+
574598
/* Load SK_SKB program and Attach */
575599
err = bpf_prog_load(SOCKMAP_PARSE_PROG,
576600
BPF_PROG_TYPE_SK_SKB, &obj, &parse_prog);
@@ -643,6 +667,13 @@ static void test_sockmap(int tasks, void *data)
643667
goto out_sockmap;
644668
}
645669

670+
err = bpf_prog_attach(verdict_prog, map_fd_rx,
671+
__MAX_BPF_ATTACH_TYPE, 0);
672+
if (!err) {
673+
printf("Attached unknown bpf prog\n");
674+
goto out_sockmap;
675+
}
676+
646677
/* Test map update elem afterwards fd lives in fd and map_fd */
647678
for (i = 0; i < 6; i++) {
648679
err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
@@ -809,6 +840,24 @@ static void test_sockmap(int tasks, void *data)
809840
assert(status == 0);
810841
}
811842

843+
err = bpf_prog_detach(map_fd_rx, __MAX_BPF_ATTACH_TYPE);
844+
if (!err) {
845+
printf("Detached an invalid prog type.\n");
846+
goto out_sockmap;
847+
}
848+
849+
err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_PARSER);
850+
if (err) {
851+
printf("Failed parser prog detach\n");
852+
goto out_sockmap;
853+
}
854+
855+
err = bpf_prog_detach(map_fd_rx, BPF_SK_SKB_STREAM_VERDICT);
856+
if (err) {
857+
printf("Failed parser prog detach\n");
858+
goto out_sockmap;
859+
}
860+
812861
/* Test map close sockets */
813862
for (i = 0; i < 6; i++)
814863
close(sfd[i]);

0 commit comments

Comments
 (0)