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
58 58
59 struct xsk_queue *tx ____cacheline_aligned_in_smp;59 struct xsk_queue *tx ____cacheline_aligned_in_smp;
60 struct list_head tx_list;60 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;
65 /* Protects generic receive. */61 /* Protects generic receive. */
66 spinlock_t rx_lock;62 spinlock_t rx_lock;
67 63
include/net/xsk_buff_pool.h+5−0
@@ -73,6 +73,11 @@ struct xsk_buff_pool { · 72 unmodified lines
73 bool dma_need_sync;73 bool dma_need_sync;
74 bool unaligned;74 bool unaligned;
75 void *addrs;75 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;
76 struct xdp_buff_xsk *free_heads[];81 struct xdp_buff_xsk *free_heads[];
77};82};
78 83
kernel/bpf/hashtab.c+1−0
@@ -152,6 +152,7 @@ static void htab_init_buckets(struct bpf_htab *htab) · 151 unmodified lines
152 lockdep_set_class(&htab->buckets[i].lock,152 lockdep_set_class(&htab->buckets[i].lock,
153 &htab->lockdep_key);153 &htab->lockdep_key);
154 }154 }
155 cond_resched();
155 }156 }
156}157}
157 158
kernel/bpf/syscall.c+0−1
@@ -17,7 +17,6 @@ · 16 unmodified lines
17#include <linux/fs.h>17#include <linux/fs.h>
18#include <linux/license.h>18#include <linux/license.h>
19#include <linux/filter.h>19#include <linux/filter.h>
20#include <linux/version.h>
21#include <linux/kernel.h>20#include <linux/kernel.h>
22#include <linux/idr.h>21#include <linux/idr.h>
23#include <linux/cred.h>22#include <linux/cred.h>
kernel/bpf/task_iter.c+9−9
@@ -37,7 +37,7 @@ retry: · 36 unmodified lines
37 if (!task) {37 if (!task) {
38 ++*tid;38 ++*tid;
39 goto retry;39 goto retry;
40 } else if (skip_if_dup_files && task->tgid != task->pid &&40 } else if (skip_if_dup_files && !thread_group_leader(task) &&
41 task->files == task->group_leader->files) {41 task->files == task->group_leader->files) {
42 put_task_struct(task);42 put_task_struct(task);
43 task = NULL;43 task = NULL;
@@ -151,14 +151,14 @@ again: · 107 unmodified lines
151 curr_task = info->task;151 curr_task = info->task;
152 curr_fd = info->fd;152 curr_fd = info->fd;
153 } else {153 } else {
154 curr_task = task_seq_get_next(ns, &curr_tid, true);154 curr_task = task_seq_get_next(ns, &curr_tid, true);
155 if (!curr_task) {155 if (!curr_task) {
156 info->task = NULL;156 info->task = NULL;
157 return NULL;157 info->tid = curr_tid;
158 }158 return NULL;
159 159 }
160 /* set info->task and info->tid */160
161 info->task = curr_task;161 /* set info->task and info->tid */
162 if (curr_tid == info->tid) {162 if (curr_tid == info->tid) {
163 curr_fd = info->fd;163 curr_fd = info->fd;
164 } else {164 } else {
net/xdp/xsk.c+13−3
@@ -423,9 +423,9 @@ static void xsk_destruct_skb(struct sk_buff *skb) · 422 unmodified lines
423 struct xdp_sock *xs = xdp_sk(skb->sk);423 struct xdp_sock *xs = xdp_sk(skb->sk);
424 unsigned long flags;424 unsigned long flags;
425 425
426 spin_lock_irqsave(&xs->tx_completion_lock, flags);426 spin_lock_irqsave(&xs->pool->cq_lock, flags);
427 xskq_prod_submit_addr(xs->pool->cq, addr);427 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);
429 429
430 sock_wfree(skb);430 sock_wfree(skb);
431}431}
@@ -437,6 +437,7 @@ static int xsk_generic_xmit(struct sock *sk) · 5 unmodified lines
437 bool sent_frame = false;437 bool sent_frame = false;
438 struct xdp_desc desc;438 struct xdp_desc desc;
439 struct sk_buff *skb;439 struct sk_buff *skb;
440 unsigned long flags;
440 int err = 0;441 int err = 0;
441 442
442 mutex_lock(&xs->mutex);443 mutex_lock(&xs->mutex);
@@ -468,10 +469,13 @@ static int xsk_generic_xmit(struct sock *sk) · 25 unmodified lines
468 * if there is space in it. This avoids having to implement469 * if there is space in it. This avoids having to implement
469 * any buffering in the Tx path.470 * any buffering in the Tx path.
470 */471 */
472 spin_lock_irqsave(&xs->pool->cq_lock, flags);
471 if (unlikely(err) || xskq_prod_reserve(xs->pool->cq)) {473 if (unlikely(err) || xskq_prod_reserve(xs->pool->cq)) {
474 spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
472 kfree_skb(skb);475 kfree_skb(skb);
473 goto out;476 goto out;
474 }477 }
478 spin_unlock_irqrestore(&xs->pool->cq_lock, flags);
475 479
476 skb->dev = xs->dev;480 skb->dev = xs->dev;
477 skb->priority = sk->sk_priority;481 skb->priority = sk->sk_priority;
@@ -483,6 +487,9 @@ static int xsk_generic_xmit(struct sock *sk) · 5 unmodified lines
483 if (err == NETDEV_TX_BUSY) {487 if (err == NETDEV_TX_BUSY) {
484 /* Tell user-space to retry the send */488 /* Tell user-space to retry the send */
485 skb->destructor = sock_wfree;489 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);
486 /* Free skb without triggering the perf drop trace */493 /* Free skb without triggering the perf drop trace */
487 consume_skb(skb);494 consume_skb(skb);
488 err = -EAGAIN;495 err = -EAGAIN;
@@ -878,6 +885,10 @@ static int xsk_bind(struct socket *sock, struct sockaddr *addr, int addr_len) · 389 unmodified lines
878 }885 }
879 }886 }
880 887
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
881 xs->dev = dev;892 xs->dev = dev;
882 xs->zc = xs->umem->zc;893 xs->zc = xs->umem->zc;
883 xs->queue_id = qid;894 xs->queue_id = qid;
@@ -1299,7 +1310,6 @@ static int xsk_create(struct net *net, struct socket *sock, int protocol, · 415 unmodified lines
1299 xs->state = XSK_READY;1310 xs->state = XSK_READY;
1300 mutex_init(&xs->mutex);1311 mutex_init(&xs->mutex);
1301 spin_lock_init(&xs->rx_lock);1312 spin_lock_init(&xs->rx_lock);
1302 spin_lock_init(&xs->tx_completion_lock);
1303 1313
1304 INIT_LIST_HEAD(&xs->map_list);1314 INIT_LIST_HEAD(&xs->map_list);
1305 spin_lock_init(&xs->map_list_lock);1315 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
71 INIT_LIST_HEAD(&pool->free_list);71 INIT_LIST_HEAD(&pool->free_list);
72 INIT_LIST_HEAD(&pool->xsk_tx_list);72 INIT_LIST_HEAD(&pool->xsk_tx_list);
73 spin_lock_init(&pool->xsk_tx_list_lock);73 spin_lock_init(&pool->xsk_tx_list_lock);
74 spin_lock_init(&pool->cq_lock);
74 refcount_set(&pool->users, 1);75 refcount_set(&pool->users, 1);
75 76
76 pool->fq = xs->fq_tmp;77 pool->fq = xs->fq_tmp;
77 pool->cq = xs->cq_tmp;78 pool->cq = xs->cq_tmp;
78 xs->fq_tmp = NULL;
79 xs->cq_tmp = NULL;
80 79
81 for (i = 0; i < pool->free_heads_cnt; i++) {80 for (i = 0; i < pool->free_heads_cnt; i++) {
82 xskb = &pool->heads[i];81 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
334 return xskq_prod_nb_free(q, 1) ? false : true;334 return xskq_prod_nb_free(q, 1) ? false : true;
335}335}
336 336
337static inline void xskq_prod_cancel(struct xsk_queue *q)
338{
339 q->cached_prod--;
340}
341
337static inline int xskq_prod_reserve(struct xsk_queue *q)342static inline int xskq_prod_reserve(struct xsk_queue *q)
338{343{
339 if (xskq_prod_is_full(q))344 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
121 /sys/kernel/btf/vmlinux \121 /sys/kernel/btf/vmlinux \
122 /boot/vmlinux-$(shell uname -r)122 /boot/vmlinux-$(shell uname -r)
123VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))123VMLINUX_BTF ?= $(abspath $(firstword $(wildcard $(VMLINUX_BTF_PATHS))))
124ifeq ($(VMLINUX_BTF),)
125$(error Cannot find a vmlinux for VMLINUX_BTF at any of "$(VMLINUX_BTF_PATHS)")
126endif
124 127
125# Define simple and short `make test_progs`, `make test_sysctl`, etc targets128# Define simple and short `make test_progs`, `make test_sysctl`, etc targets
126# to build individual tests.129# 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
1312#define DO_UPDATE 11312#define DO_UPDATE 1
1313#define DO_DELETE 01313#define DO_DELETE 0
1314 1314
1315#define MAP_RETRIES 20
1316
1317static 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
1331static 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
1315static void test_update_delete(unsigned int fn, void *data)1344static void test_update_delete(unsigned int fn, void *data)
1316{1345{
1317 int do_update = ((int *)data)[1];1346 int do_update = ((int *)data)[1];
1318 int fd = ((int *)data)[0];1347 int fd = ((int *)data)[0];
1319 int i, key, value;1348 int i, key, value, err;
1320 1349
1321 for (i = fn; i < MAP_SIZE; i += TASKS) {1350 for (i = fn; i < MAP_SIZE; i += TASKS) {
1322 key = value = i;1351 key = value = i;
1323 1352
1324 if (do_update) {1353 if (do_update) {
1325 assert(bpf_map_update_elem(fd, &key, &value,1354 err = map_update_retriable(fd, &key, &value, BPF_NOEXIST, MAP_RETRIES);
1326 BPF_NOEXIST) == 0);1355 if (err)
1327 assert(bpf_map_update_elem(fd, &key, &value,1356 printf("error %d %d\n", err, errno);
1328 BPF_EXIST) == 0);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);
1329 } else {1362 } 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);
1331 }1367 }
1332 }1368 }
1333}1369}
tools/testing/selftests/bpf/xdpxceiver.c+2−2
@@ -715,7 +715,7 @@ static void worker_pkt_dump(void) · 714 unmodified lines
715 int payload = *((uint32_t *)(pkt_buf[iter]->payload + PKT_HDR_SIZE));715 int payload = *((uint32_t *)(pkt_buf[iter]->payload + PKT_HDR_SIZE));
716 716
717 if (payload == EOT) {717 if (payload == EOT) {
718 ksft_print_msg("End-of-tranmission frame received\n");718 ksft_print_msg("End-of-transmission frame received\n");
719 fprintf(stdout, "---------------------------------------\n");719 fprintf(stdout, "---------------------------------------\n");
720 break;720 break;
721 }721 }
@@ -747,7 +747,7 @@ static void worker_pkt_validate(void) · 25 unmodified lines
747 }747 }
748 748
749 if (payloadseqnum == EOT) {749 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");
751 sigvar = 1;751 sigvar = 1;
752 break;752 break;
753 }753 }

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