History

Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf

Daniel Borkmann says: ==================== pull-request: bpf 2020-12-28 The following pull-request contains BPF updates for your *net* tree. There is a small merge conflict between bpf tree commit 69ca310f3416 ("bpf: Save correct stopping point in file seq iteration") and net tree commit 66ed594409a1 ("bpf/task_iter: In task_file_seq_get_next use task_lookup_next_fd_rcu"). The get_files_struct() does not exist anymore in net, so take the hunk in HEAD and add the `info->tid = curr_tid` to the error path: [...] curr_task = task_seq_get_next(ns, &curr_tid, true); if (!curr_task) { info->task = NULL; info->tid = curr_tid; return NULL; } /* set info->task and info->tid */ [...] We've added 10 non-merge commits during the last 9 day(s) which contain a total of 11 files changed, 75 insertions(+), 20 deletions(-). The main changes are: 1) Various AF_XDP fixes such as fill/completion ring leak on failed bind and fixing a race in skb mode's backpressure mechanism, from Magnus Karlsson. 2) Fix latency spikes on lockdep enabled kernels by adding a rescheduling point to BPF hashtab initialization, from Eric Dumazet. 3) Fix a splat in task iterator by saving the correct stopping point in the seq file iteration, from Jonathan Lemon. 4) Fix BPF maps selftest by adding retries in case hashtab returns EBUSY errors on update/deletes, from Andrii Nakryiko. 5) Fix BPF selftest error reporting to something more user friendly if the vmlinux BTF cannot be found, from Kamal Mostafa. ====================

David S. Miller committed 5 years ago

Commit 4bfc4712 parents 1fef735 a61daaf11 files · +81 −27Browse files

Unified · Split

11 files
  1. include/net/xdp_sock.h +0 −4
  2. include/net/xsk_buff_pool.h +5 −0
  3. kernel/bpf/hashtab.c +1 −0
  4. kernel/bpf/syscall.c +0 −1
  5. kernel/bpf/task_iter.c +9 −9
  6. net/xdp/xsk.c +13 −3
  7. net/xdp/xsk_buff_pool.c +1 −2
  8. net/xdp/xsk_queue.h +5 −0
  9. tools/testing/selftests/bpf/Makefile +3 −0
  10. tools/testing/selftests/bpf/test_maps.c +42 −6
  11. tools/testing/selftests/bpf/xdpxceiver.c +2 −2
include/net/xdp_sock.h+0−4
@@ -58,10 +58,6 @@ struct xdp_sock { · 57 unmodified lines
5858
5959 struct xsk_queue *tx ____cacheline_aligned_in_smp;
6060 struct list_head tx_list;
61− /* Mutual exclusion of NAPI TX thread and sendmsg error paths
62− * in the SKB destructor callback.
63− */
64− spinlock_t tx_completion_lock;
6561 /* Protects generic receive. */
6662 spinlock_t rx_lock;
6763
include/net/xsk_buff_pool.h+5−0
@@ -73,6 +73,11 @@ struct xsk_buff_pool { · 72 unmodified lines
7373 bool dma_need_sync;
7474 bool unaligned;
7575 void *addrs;
76+ /* Mutual exclusion of the completion ring in the SKB mode. Two cases to protect:
77+ * NAPI TX thread and sendmsg error paths in the SKB destructor callback and when
78+ * sockets share a single cq when the same netdev and queue id is shared.
79+ */
80+ spinlock_t cq_lock;
7681 struct xdp_buff_xsk *free_heads[];
7782 };
7883
kernel/bpf/hashtab.c+1−0
@@ -152,6 +152,7 @@ static void htab_init_buckets(struct bpf_htab *htab) · 151 unmodified lines
152152 lockdep_set_class(&htab->buckets[i].lock,
153153 &htab->lockdep_key);
154154 }
155+ cond_resched();
155156 }
156157 }
157158
kernel/bpf/syscall.c+0−1
@@ -17,7 +17,6 @@ · 16 unmodified lines
1717 #include <linux/fs.h>
1818 #include <linux/license.h>
1919 #include <linux/filter.h>
20−#include <linux/version.h>
2120 #include <linux/kernel.h>
2221 #include <linux/idr.h>
2322 #include <linux/cred.h>
kernel/bpf/task_iter.c+9−9
@@ -37,7 +37,7 @@ retry: · 36 unmodified lines
3737 if (!task) {
3838 ++*tid;
3939 goto retry;
40− } else if (skip_if_dup_files && task->tgid != task->pid &&
40+ } else if (skip_if_dup_files && !thread_group_leader(task) &&
4141 task->files == task->group_leader->files) {
4242 put_task_struct(task);
4343 task = NULL;
@@ -151,14 +151,14 @@ again: · 107 unmodified lines
151151 curr_task = info->task;
152152 curr_fd = info->fd;
153153 } else {
154− curr_task = task_seq_get_next(ns, &curr_tid, true);
155− if (!curr_task) {
156− info->task = NULL;
157− return NULL;
158− }
159−
160− /* set info->task and info->tid */
161− info->task = curr_task;
154+ curr_task = task_seq_get_next(ns, &curr_tid, true);
155+ if (!curr_task) {
156+ info->task = NULL;
157+ info->tid = curr_tid;
158+ return NULL;
159+ }
160+
161+ /* set info->task and info->tid */
162162 if (curr_tid == info->tid) {
163163 curr_fd = info->fd;
164164 } else {
net/xdp/xsk.c+13−3
@@ -423,9 +423,9 @@ static void xsk_destruct_skb(struct sk_buff *skb) · 422 unmodified lines
423423 struct xdp_sock *xs = xdp_sk(skb->sk);
424424 unsigned long flags;
425425
426− spin_lock_irqsave(&xs->tx_completion_lock, flags);
426+ spin_lock_irqsave(&xs->pool->cq_lock, flags);
427427 xskq_prod_submit_addr(xs->pool->cq, addr);
428− spin_unlock_irqrestore(&xs->tx_completion_lock, flags);
428+ spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
429429
430430 sock_wfree(skb);
431431 }
@@ -437,6 +437,7 @@ static int xsk_generic_xmit(struct sock *sk) · 5 unmodified lines
437437 bool sent_frame = false;
438438 struct xdp_desc desc;
439439 struct sk_buff *skb;
440+ unsigned long flags;
440441 int err = 0;
441442
442443 mutex_lock(&xs->mutex);
@@ -468,10 +469,13 @@ static int xsk_generic_xmit(struct sock *sk) · 25 unmodified lines
468469 * if there is space in it. This avoids having to implement
469470 * any buffering in the Tx path.
470471 */
472+ spin_lock_irqsave(&xs->pool->cq_lock, flags);
471473 if (unlikely(err) || xskq_prod_reserve(xs->pool->cq)) {
474+ spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
472475 kfree_skb(skb);
473476 goto out;
474477 }
478+ spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
475479
476480 skb->dev = xs->dev;
477481 skb->priority = sk->sk_priority;
@@ -483,6 +487,9 @@ static int xsk_generic_xmit(struct sock *sk) · 5 unmodified lines
483487 if (err == NETDEV_TX_BUSY) {
484488 /* Tell user-space to retry the send */
485489 skb->destructor = sock_wfree;
490+ spin_lock_irqsave(&xs->pool->cq_lock, flags);
491+ xskq_prod_cancel(xs->pool->cq);
492+ spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
486493 /* Free skb without triggering the perf drop trace */
487494 consume_skb(skb);
488495 err = -EAGAIN;
@@ -878,6 +885,10 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) · 389 unmodified lines
878885 }
879886 }
880887
888+ /* FQ and CQ are now owned by the buffer pool and cleaned up with it. */
889+ xs->fq_tmp = NULL;
890+ xs->cq_tmp = NULL;
891+
881892 xs->dev = dev;
882893 xs->zc = xs->umem->zc;
883894 xs->queue_id = qid;
@@ -1299,7 +1310,6 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol, · 415 unmodified lines
12991310 xs->state = XSK_READY;
13001311 mutex_init(&xs->mutex);
13011312 spin_lock_init(&xs->rx_lock);
1302− spin_lock_init(&xs->tx_completion_lock);
13031313
13041314 INIT_LIST_HEAD(&xs->map_list);
13051315 spin_lock_init(&xs->map_list_lock);
net/xdp/xsk_buff_pool.c+1−2
@@ -71,12 +71,11 @@ struct xsk_buff_pool *xp_create_and_assign_umem(struct xdp_sock *xs, · 70 unmodified lines
7171 INIT_LIST_HEAD(&pool->free_list);
7272 INIT_LIST_HEAD(&pool->xsk_tx_list);
7373 spin_lock_init(&pool->xsk_tx_list_lock);
74+ spin_lock_init(&pool->cq_lock);
7475 refcount_set(&pool->users, 1);
7576
7677 pool->fq = xs->fq_tmp;
7778 pool->cq = xs->cq_tmp;
78− xs->fq_tmp = NULL;
79− xs->cq_tmp = NULL;
8079
8180 for (i = 0; i < pool->free_heads_cnt; i++) {
8281 xskb = &pool->heads[i];
net/xdp/xsk_queue.h+5−0
@@ -334,6 +334,11 @@ static inline bool xskq_prod_is_full(struct xsk_queue *q) · 333 unmodified lines
334334 return xskq_prod_nb_free(q, 1) ? false : true;
335335 }
336336
337+static inline void xskq_prod_cancel(struct xsk_queue *q)
338+{
339+ q->cached_prod--;
340+}
341+
337342 static inline int xskq_prod_reserve(struct xsk_queue *q)
338343 {
339344 if (xskq_prod_is_full(q))
tools/testing/selftests/bpf/Makefile+3−0
@@ -121,6 +121,9 @@ VMLINUX_BTF_PATHS ?= $(if $(O),$(O)/vmlinux) \ · 120 unmodified lines
121121 /sys/kernel/btf/vmlinux \
122122 /boot/vmlinux-$(shell uname -r)
123123 VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
124+ifeq ($(VMLINUX_BTF),)
125+$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
126+endif
124127
125128 # Define simple and short `make test_progs`, `make test_sysctl`, etc targets
126129 # to build individual tests.
tools/testing/selftests/bpf/test_maps.c+42−6
@@ -1312,22 +1312,58 @@ static void test_map_stress(void) · 1311 unmodified lines
13121312 #define DO_UPDATE 1
13131313 #define DO_DELETE 0
13141314
1315+#define MAP_RETRIES 20
1316+
1317+static int map_update_retriable(int map_fd, const void *key, const void *value,
1318+ int flags, int attempts)
1319+{
1320+ while (bpf_map_update_elem(map_fd, key, value, flags)) {
1321+ if (!attempts || (errno != EAGAIN && errno != EBUSY))
1322+ return -errno;
1323+
1324+ usleep(1);
1325+ attempts--;
1326+ }
1327+
1328+ return 0;
1329+}
1330+
1331+static int map_delete_retriable(int map_fd, const void *key, int attempts)
1332+{
1333+ while (bpf_map_delete_elem(map_fd, key)) {
1334+ if (!attempts || (errno != EAGAIN && errno != EBUSY))
1335+ return -errno;
1336+
1337+ usleep(1);
1338+ attempts--;
1339+ }
1340+
1341+ return 0;
1342+}
1343+
13151344 static void test_update_delete(unsigned int fn, void *data)
13161345 {
13171346 int do_update = ((int *)data)[1];
13181347 int fd = ((int *)data)[0];
1319− int i, key, value;
1348+ int i, key, value, err;
13201349
13211350 for (i = fn; i < MAP_SIZE; i += TASKS) {
13221351 key = value = i;
13231352
13241353 if (do_update) {
1325− assert(bpf_map_update_elem(fd, &key, &value,
1326− BPF_NOEXIST) == 0);
1327− assert(bpf_map_update_elem(fd, &key, &value,
1328− BPF_EXIST) == 0);
1354+ err = map_update_retriable(fd, &key, &value, BPF_NOEXIST, MAP_RETRIES);
1355+ if (err)
1356+ printf("error %d %d\n", err, errno);
1357+ assert(err == 0);
1358+ err = map_update_retriable(fd, &key, &value, BPF_EXIST, MAP_RETRIES);
1359+ if (err)
1360+ printf("error %d %d\n", err, errno);
1361+ assert(err == 0);
13291362 } else {
1330− assert(bpf_map_delete_elem(fd, &key) == 0);
1363+ err = map_delete_retriable(fd, &key, MAP_RETRIES);
1364+ if (err)
1365+ printf("error %d %d\n", err, errno);
1366+ assert(err == 0);
13311367 }
13321368 }
13331369 }
tools/testing/selftests/bpf/xdpxceiver.c+2−2
@@ -715,7 +715,7 @@ static void worker_pkt_dump(void) · 714 unmodified lines
715715 int payload = *((uint32_t *)(pkt_buf[iter]->payload + PKT_HDR_SIZE));
716716
717717 if (payload == EOT) {
718− ksft_print_msg("End-of-tranmission frame received\n");
718+ ksft_print_msg("End-of-transmission frame received\n");
719719 fprintf(stdout, "---------------------------------------\n");
720720 break;
721721 }
@@ -747,7 +747,7 @@ static void worker_pkt_validate(void) · 25 unmodified lines
747747 }
748748
749749 if (payloadseqnum == EOT) {
750− ksft_print_msg("End-of-tranmission frame received: PASS\n");
750+ ksft_print_msg("End-of-transmission frame received: PASS\n");
751751 sigvar = 1;
752752 break;
753753 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t