Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

Daniel Borkmann says:

====================
pull-request: bpf 2021-10-26

We've added 12 non-merge commits during the last 7 day(s) which contain
a total of 23 files changed, 118 insertions(+), 98 deletions(-).

The main changes are:

1) Fix potential race window in BPF tail call compatibility check, from Toke Høiland-Jørgensen.

2) Fix memory leak in cgroup fs due to missing cgroup_bpf_offline(), from Quanyang Wang.

3) Fix file descriptor reference counting in generic_map_update_batch(), from Xu Kuohai.

4) Fix bpf_jit_limit knob to the max supported limit by the arch's JIT, from Lorenz Bauer.

5) Fix BPF sockmap ->poll callbacks for UDP and AF_UNIX sockets, from Cong Wang and Yucong Sun.

6) Fix BPF sockmap concurrency issue in TCP on non-blocking sendmsg calls, from Liu Jian.

7) Fix build failure of INODE_STORAGE and TASK_STORAGE maps on !CONFIG_NET, from Tejun Heo.

* https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf:
bpf: Fix potential race in tail call compatibility check
bpf: Move BPF_MAP_TYPE for INODE_STORAGE and TASK_STORAGE outside of CONFIG_NET
selftests/bpf: Use recv_timeout() instead of retries
net: Implement ->sock_is_readable() for UDP and AF_UNIX
skmsg: Extract and reuse sk_msg_is_readable()
net: Rename ->stream_memory_read to ->sock_is_readable
tcp_bpf: Fix one concurrency problem in the tcp_bpf_send_verdict function
cgroup: Fix memory leak caused by missing cgroup_bpf_offline
bpf: Fix error usage of map_fd and fdget() in generic_map_update_batch()
bpf: Prevent increasing bpf_jit_limit above max
bpf: Define bpf_jit_alloc_exec_limit for arm64 JIT
bpf: Define bpf_jit_alloc_exec_limit for riscv JIT
====================

Link: https://lore.kernel.org/r/20211026201920.11296-1-daniel@iogearbox.net
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+118 -98
+5
arch/arm64/net/bpf_jit_comp.c
··· 1136 1136 return prog; 1137 1137 } 1138 1138 1139 + u64 bpf_jit_alloc_exec_limit(void) 1140 + { 1141 + return BPF_JIT_REGION_SIZE; 1142 + } 1143 + 1139 1144 void *bpf_jit_alloc_exec(unsigned long size) 1140 1145 { 1141 1146 return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
+5
arch/riscv/net/bpf_jit_core.c
··· 166 166 return prog; 167 167 } 168 168 169 + u64 bpf_jit_alloc_exec_limit(void) 170 + { 171 + return BPF_JIT_REGION_SIZE; 172 + } 173 + 169 174 void *bpf_jit_alloc_exec(unsigned long size) 170 175 { 171 176 return __vmalloc_node_range(size, PAGE_SIZE, BPF_JIT_REGION_START,
+5 -2
include/linux/bpf.h
··· 929 929 * stored in the map to make sure that all callers and callees have 930 930 * the same prog type and JITed flag. 931 931 */ 932 - enum bpf_prog_type type; 933 - bool jited; 932 + struct { 933 + spinlock_t lock; 934 + enum bpf_prog_type type; 935 + bool jited; 936 + } owner; 934 937 /* Programs with direct jumps into programs part of this array. */ 935 938 struct list_head poke_progs; 936 939 struct bpf_map *map;
+4 -4
include/linux/bpf_types.h
··· 101 101 #endif 102 102 BPF_MAP_TYPE(BPF_MAP_TYPE_ARRAY_OF_MAPS, array_of_maps_map_ops) 103 103 BPF_MAP_TYPE(BPF_MAP_TYPE_HASH_OF_MAPS, htab_of_maps_map_ops) 104 - #ifdef CONFIG_NET 105 - BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops) 106 - BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP_HASH, dev_map_hash_ops) 107 - BPF_MAP_TYPE(BPF_MAP_TYPE_SK_STORAGE, sk_storage_map_ops) 108 104 #ifdef CONFIG_BPF_LSM 109 105 BPF_MAP_TYPE(BPF_MAP_TYPE_INODE_STORAGE, inode_storage_map_ops) 110 106 #endif 111 107 BPF_MAP_TYPE(BPF_MAP_TYPE_TASK_STORAGE, task_storage_map_ops) 108 + #ifdef CONFIG_NET 109 + BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP, dev_map_ops) 110 + BPF_MAP_TYPE(BPF_MAP_TYPE_DEVMAP_HASH, dev_map_hash_ops) 111 + BPF_MAP_TYPE(BPF_MAP_TYPE_SK_STORAGE, sk_storage_map_ops) 112 112 BPF_MAP_TYPE(BPF_MAP_TYPE_CPUMAP, cpu_map_ops) 113 113 #if defined(CONFIG_XDP_SOCKETS) 114 114 BPF_MAP_TYPE(BPF_MAP_TYPE_XSKMAP, xsk_map_ops)
+1
include/linux/filter.h
··· 1051 1051 extern int bpf_jit_harden; 1052 1052 extern int bpf_jit_kallsyms; 1053 1053 extern long bpf_jit_limit; 1054 + extern long bpf_jit_limit_max; 1054 1055 1055 1056 typedef void (*bpf_jit_fill_hole_t)(void *area, unsigned int size); 1056 1057
+1
include/linux/skmsg.h
··· 128 128 struct sk_msg *msg, u32 bytes); 129 129 int sk_msg_recvmsg(struct sock *sk, struct sk_psock *psock, struct msghdr *msg, 130 130 int len, int flags); 131 + bool sk_msg_is_readable(struct sock *sk); 131 132 132 133 static inline void sk_msg_check_to_free(struct sk_msg *msg, u32 i, u32 bytes) 133 134 {
+7 -1
include/net/sock.h
··· 1208 1208 #endif 1209 1209 1210 1210 bool (*stream_memory_free)(const struct sock *sk, int wake); 1211 - bool (*stream_memory_read)(const struct sock *sk); 1211 + bool (*sock_is_readable)(struct sock *sk); 1212 1212 /* Memory pressure */ 1213 1213 void (*enter_memory_pressure)(struct sock *sk); 1214 1214 void (*leave_memory_pressure)(struct sock *sk); ··· 2820 2820 2821 2821 int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len); 2822 2822 2823 + static inline bool sk_is_readable(struct sock *sk) 2824 + { 2825 + if (sk->sk_prot->sock_is_readable) 2826 + return sk->sk_prot->sock_is_readable(sk); 2827 + return false; 2828 + } 2823 2829 #endif /* _SOCK_H */
+1 -1
include/net/tls.h
··· 375 375 void tls_sw_free_ctx_rx(struct tls_context *tls_ctx); 376 376 int tls_sw_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, 377 377 int nonblock, int flags, int *addr_len); 378 - bool tls_sw_stream_read(const struct sock *sk); 378 + bool tls_sw_sock_is_readable(struct sock *sk); 379 379 ssize_t tls_sw_splice_read(struct socket *sock, loff_t *ppos, 380 380 struct pipe_inode_info *pipe, 381 381 size_t len, unsigned int flags);
+1
kernel/bpf/arraymap.c
··· 1072 1072 INIT_WORK(&aux->work, prog_array_map_clear_deferred); 1073 1073 INIT_LIST_HEAD(&aux->poke_progs); 1074 1074 mutex_init(&aux->poke_mutex); 1075 + spin_lock_init(&aux->owner.lock); 1075 1076 1076 1077 map = array_map_alloc(attr); 1077 1078 if (IS_ERR(map)) {
+16 -8
kernel/bpf/core.c
··· 524 524 int bpf_jit_kallsyms __read_mostly = IS_BUILTIN(CONFIG_BPF_JIT_DEFAULT_ON); 525 525 int bpf_jit_harden __read_mostly; 526 526 long bpf_jit_limit __read_mostly; 527 + long bpf_jit_limit_max __read_mostly; 527 528 528 529 static void 529 530 bpf_prog_ksym_set_addr(struct bpf_prog *prog) ··· 818 817 static int __init bpf_jit_charge_init(void) 819 818 { 820 819 /* Only used as heuristic here to derive limit. */ 821 - bpf_jit_limit = min_t(u64, round_up(bpf_jit_alloc_exec_limit() >> 2, 820 + bpf_jit_limit_max = bpf_jit_alloc_exec_limit(); 821 + bpf_jit_limit = min_t(u64, round_up(bpf_jit_limit_max >> 2, 822 822 PAGE_SIZE), LONG_MAX); 823 823 return 0; 824 824 } ··· 1823 1821 bool bpf_prog_array_compatible(struct bpf_array *array, 1824 1822 const struct bpf_prog *fp) 1825 1823 { 1824 + bool ret; 1825 + 1826 1826 if (fp->kprobe_override) 1827 1827 return false; 1828 1828 1829 - if (!array->aux->type) { 1829 + spin_lock(&array->aux->owner.lock); 1830 + 1831 + if (!array->aux->owner.type) { 1830 1832 /* There's no owner yet where we could check for 1831 1833 * compatibility. 1832 1834 */ 1833 - array->aux->type = fp->type; 1834 - array->aux->jited = fp->jited; 1835 - return true; 1835 + array->aux->owner.type = fp->type; 1836 + array->aux->owner.jited = fp->jited; 1837 + ret = true; 1838 + } else { 1839 + ret = array->aux->owner.type == fp->type && 1840 + array->aux->owner.jited == fp->jited; 1836 1841 } 1837 - 1838 - return array->aux->type == fp->type && 1839 - array->aux->jited == fp->jited; 1842 + spin_unlock(&array->aux->owner.lock); 1843 + return ret; 1840 1844 } 1841 1845 1842 1846 static int bpf_check_tail_call(const struct bpf_prog *fp)
+7 -4
kernel/bpf/syscall.c
··· 543 543 544 544 if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) { 545 545 array = container_of(map, struct bpf_array, map); 546 - type = array->aux->type; 547 - jited = array->aux->jited; 546 + spin_lock(&array->aux->owner.lock); 547 + type = array->aux->owner.type; 548 + jited = array->aux->owner.jited; 549 + spin_unlock(&array->aux->owner.lock); 548 550 } 549 551 550 552 seq_printf(m, ··· 1339 1337 void __user *values = u64_to_user_ptr(attr->batch.values); 1340 1338 void __user *keys = u64_to_user_ptr(attr->batch.keys); 1341 1339 u32 value_size, cp, max_count; 1342 - int ufd = attr->map_fd; 1340 + int ufd = attr->batch.map_fd; 1343 1341 void *key, *value; 1344 1342 struct fd f; 1345 1343 int err = 0; 1346 1344 1347 - f = fdget(ufd); 1348 1345 if (attr->batch.elem_flags & ~BPF_F_LOCK) 1349 1346 return -EINVAL; 1350 1347 ··· 1368 1367 return -ENOMEM; 1369 1368 } 1370 1369 1370 + f = fdget(ufd); /* bpf_map_do_batch() guarantees ufd is valid */ 1371 1371 for (cp = 0; cp < max_count; cp++) { 1372 1372 err = -EFAULT; 1373 1373 if (copy_from_user(key, keys + cp * map->key_size, ··· 1388 1386 1389 1387 kvfree(value); 1390 1388 kvfree(key); 1389 + fdput(f); 1391 1390 return err; 1392 1391 } 1393 1392
+3 -1
kernel/cgroup/cgroup.c
··· 2187 2187 * And don't kill the default root. 2188 2188 */ 2189 2189 if (list_empty(&root->cgrp.self.children) && root != &cgrp_dfl_root && 2190 - !percpu_ref_is_dying(&root->cgrp.self.refcnt)) 2190 + !percpu_ref_is_dying(&root->cgrp.self.refcnt)) { 2191 + cgroup_bpf_offline(&root->cgrp); 2191 2192 percpu_ref_kill(&root->cgrp.self.refcnt); 2193 + } 2192 2194 cgroup_put(&root->cgrp); 2193 2195 kernfs_kill_sb(sb); 2194 2196 }
+14
net/core/skmsg.c
··· 474 474 } 475 475 EXPORT_SYMBOL_GPL(sk_msg_recvmsg); 476 476 477 + bool sk_msg_is_readable(struct sock *sk) 478 + { 479 + struct sk_psock *psock; 480 + bool empty = true; 481 + 482 + rcu_read_lock(); 483 + psock = sk_psock(sk); 484 + if (likely(psock)) 485 + empty = list_empty(&psock->ingress_msg); 486 + rcu_read_unlock(); 487 + return !empty; 488 + } 489 + EXPORT_SYMBOL_GPL(sk_msg_is_readable); 490 + 477 491 static struct sk_msg *sk_psock_create_ingress_msg(struct sock *sk, 478 492 struct sk_buff *skb) 479 493 {
+1 -1
net/core/sysctl_net_core.c
··· 419 419 .mode = 0600, 420 420 .proc_handler = proc_dolongvec_minmax_bpf_restricted, 421 421 .extra1 = &long_one, 422 - .extra2 = &long_max, 422 + .extra2 = &bpf_jit_limit_max, 423 423 }, 424 424 #endif 425 425 {
+1 -4
net/ipv4/tcp.c
··· 486 486 { 487 487 if (tcp_epollin_ready(sk, target)) 488 488 return true; 489 - 490 - if (sk->sk_prot->stream_memory_read) 491 - return sk->sk_prot->stream_memory_read(sk); 492 - return false; 489 + return sk_is_readable(sk); 493 490 } 494 491 495 492 /*
+13 -14
net/ipv4/tcp_bpf.c
··· 150 150 EXPORT_SYMBOL_GPL(tcp_bpf_sendmsg_redir); 151 151 152 152 #ifdef CONFIG_BPF_SYSCALL 153 - static bool tcp_bpf_stream_read(const struct sock *sk) 154 - { 155 - struct sk_psock *psock; 156 - bool empty = true; 157 - 158 - rcu_read_lock(); 159 - psock = sk_psock(sk); 160 - if (likely(psock)) 161 - empty = list_empty(&psock->ingress_msg); 162 - rcu_read_unlock(); 163 - return !empty; 164 - } 165 - 166 153 static int tcp_msg_wait_data(struct sock *sk, struct sk_psock *psock, 167 154 long timeo) 168 155 { ··· 219 232 bool cork = false, enospc = sk_msg_full(msg); 220 233 struct sock *sk_redir; 221 234 u32 tosend, delta = 0; 235 + u32 eval = __SK_NONE; 222 236 int ret; 223 237 224 238 more_data: ··· 263 275 case __SK_REDIRECT: 264 276 sk_redir = psock->sk_redir; 265 277 sk_msg_apply_bytes(psock, tosend); 278 + if (!psock->apply_bytes) { 279 + /* Clean up before releasing the sock lock. */ 280 + eval = psock->eval; 281 + psock->eval = __SK_NONE; 282 + psock->sk_redir = NULL; 283 + } 266 284 if (psock->cork) { 267 285 cork = true; 268 286 psock->cork = NULL; 269 287 } 270 288 sk_msg_return(sk, msg, tosend); 271 289 release_sock(sk); 290 + 272 291 ret = tcp_bpf_sendmsg_redir(sk_redir, msg, tosend, flags); 292 + 293 + if (eval == __SK_REDIRECT) 294 + sock_put(sk_redir); 295 + 273 296 lock_sock(sk); 274 297 if (unlikely(ret < 0)) { 275 298 int free = sk_msg_free_nocharge(sk, msg); ··· 478 479 prot[TCP_BPF_BASE].unhash = sock_map_unhash; 479 480 prot[TCP_BPF_BASE].close = sock_map_close; 480 481 prot[TCP_BPF_BASE].recvmsg = tcp_bpf_recvmsg; 481 - prot[TCP_BPF_BASE].stream_memory_read = tcp_bpf_stream_read; 482 + prot[TCP_BPF_BASE].sock_is_readable = sk_msg_is_readable; 482 483 483 484 prot[TCP_BPF_TX] = prot[TCP_BPF_BASE]; 484 485 prot[TCP_BPF_TX].sendmsg = tcp_bpf_sendmsg;
+3
net/ipv4/udp.c
··· 2867 2867 !(sk->sk_shutdown & RCV_SHUTDOWN) && first_packet_length(sk) == -1) 2868 2868 mask &= ~(EPOLLIN | EPOLLRDNORM); 2869 2869 2870 + /* psock ingress_msg queue should not contain any bad checksum frames */ 2871 + if (sk_is_readable(sk)) 2872 + mask |= EPOLLIN | EPOLLRDNORM; 2870 2873 return mask; 2871 2874 2872 2875 }
+1
net/ipv4/udp_bpf.c
··· 114 114 *prot = *base; 115 115 prot->close = sock_map_close; 116 116 prot->recvmsg = udp_bpf_recvmsg; 117 + prot->sock_is_readable = sk_msg_is_readable; 117 118 } 118 119 119 120 static void udp_bpf_check_v6_needs_rebuild(struct proto *ops)
+2 -2
net/tls/tls_main.c
··· 681 681 682 682 prot[TLS_BASE][TLS_SW] = prot[TLS_BASE][TLS_BASE]; 683 683 prot[TLS_BASE][TLS_SW].recvmsg = tls_sw_recvmsg; 684 - prot[TLS_BASE][TLS_SW].stream_memory_read = tls_sw_stream_read; 684 + prot[TLS_BASE][TLS_SW].sock_is_readable = tls_sw_sock_is_readable; 685 685 prot[TLS_BASE][TLS_SW].close = tls_sk_proto_close; 686 686 687 687 prot[TLS_SW][TLS_SW] = prot[TLS_SW][TLS_BASE]; 688 688 prot[TLS_SW][TLS_SW].recvmsg = tls_sw_recvmsg; 689 - prot[TLS_SW][TLS_SW].stream_memory_read = tls_sw_stream_read; 689 + prot[TLS_SW][TLS_SW].sock_is_readable = tls_sw_sock_is_readable; 690 690 prot[TLS_SW][TLS_SW].close = tls_sk_proto_close; 691 691 692 692 #ifdef CONFIG_TLS_DEVICE
+1 -1
net/tls/tls_sw.c
··· 2026 2026 return copied ? : err; 2027 2027 } 2028 2028 2029 - bool tls_sw_stream_read(const struct sock *sk) 2029 + bool tls_sw_sock_is_readable(struct sock *sk) 2030 2030 { 2031 2031 struct tls_context *tls_ctx = tls_get_ctx(sk); 2032 2032 struct tls_sw_context_rx *ctx = tls_sw_ctx_rx(tls_ctx);
+4
net/unix/af_unix.c
··· 3052 3052 /* readable? */ 3053 3053 if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) 3054 3054 mask |= EPOLLIN | EPOLLRDNORM; 3055 + if (sk_is_readable(sk)) 3056 + mask |= EPOLLIN | EPOLLRDNORM; 3055 3057 3056 3058 /* Connection-based need to check for termination and startup */ 3057 3059 if ((sk->sk_type == SOCK_STREAM || sk->sk_type == SOCK_SEQPACKET) && ··· 3092 3090 3093 3091 /* readable? */ 3094 3092 if (!skb_queue_empty_lockless(&sk->sk_receive_queue)) 3093 + mask |= EPOLLIN | EPOLLRDNORM; 3094 + if (sk_is_readable(sk)) 3095 3095 mask |= EPOLLIN | EPOLLRDNORM; 3096 3096 3097 3097 /* Connection-based need to check for termination and startup */
+2
net/unix/unix_bpf.c
··· 102 102 *prot = *base; 103 103 prot->close = sock_map_close; 104 104 prot->recvmsg = unix_bpf_recvmsg; 105 + prot->sock_is_readable = sk_msg_is_readable; 105 106 } 106 107 107 108 static void unix_stream_bpf_rebuild_protos(struct proto *prot, ··· 111 110 *prot = *base; 112 111 prot->close = sock_map_close; 113 112 prot->recvmsg = unix_bpf_recvmsg; 113 + prot->sock_is_readable = sk_msg_is_readable; 114 114 prot->unhash = sock_map_unhash; 115 115 } 116 116
+20 -55
tools/testing/selftests/bpf/prog_tests/sockmap_listen.c
··· 949 949 int err, n; 950 950 u32 key; 951 951 char b; 952 - int retries = 100; 953 952 954 953 zero_verdict_count(verd_mapfd); 955 954 ··· 1001 1002 goto close_peer1; 1002 1003 if (pass != 1) 1003 1004 FAIL("%s: want pass count 1, have %d", log_prefix, pass); 1004 - again: 1005 - n = read(c0, &b, 1); 1006 - if (n < 0) { 1007 - if (errno == EAGAIN && retries--) { 1008 - usleep(1000); 1009 - goto again; 1010 - } 1011 - FAIL_ERRNO("%s: read", log_prefix); 1012 - } 1005 + n = recv_timeout(c0, &b, 1, 0, IO_TIMEOUT_SEC); 1006 + if (n < 0) 1007 + FAIL_ERRNO("%s: recv_timeout", log_prefix); 1013 1008 if (n == 0) 1014 - FAIL("%s: incomplete read", log_prefix); 1009 + FAIL("%s: incomplete recv", log_prefix); 1015 1010 1016 1011 close_peer1: 1017 1012 xclose(p1); ··· 1564 1571 const char *log_prefix = redir_mode_str(mode); 1565 1572 int c0, c1, p0, p1; 1566 1573 unsigned int pass; 1567 - int retries = 100; 1568 1574 int err, n; 1569 1575 int sfd[2]; 1570 1576 u32 key; ··· 1598 1606 if (pass != 1) 1599 1607 FAIL("%s: want pass count 1, have %d", log_prefix, pass); 1600 1608 1601 - again: 1602 - n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1); 1603 - if (n < 0) { 1604 - if (errno == EAGAIN && retries--) { 1605 - usleep(1000); 1606 - goto again; 1607 - } 1608 - FAIL_ERRNO("%s: read", log_prefix); 1609 - } 1609 + n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC); 1610 + if (n < 0) 1611 + FAIL_ERRNO("%s: recv_timeout", log_prefix); 1610 1612 if (n == 0) 1611 - FAIL("%s: incomplete read", log_prefix); 1613 + FAIL("%s: incomplete recv", log_prefix); 1612 1614 1613 1615 close: 1614 1616 xclose(c1); ··· 1734 1748 const char *log_prefix = redir_mode_str(mode); 1735 1749 int c0, c1, p0, p1; 1736 1750 unsigned int pass; 1737 - int retries = 100; 1738 1751 int err, n; 1739 1752 u32 key; 1740 1753 char b; ··· 1766 1781 if (pass != 1) 1767 1782 FAIL("%s: want pass count 1, have %d", log_prefix, pass); 1768 1783 1769 - again: 1770 - n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1); 1771 - if (n < 0) { 1772 - if (errno == EAGAIN && retries--) { 1773 - usleep(1000); 1774 - goto again; 1775 - } 1776 - FAIL_ERRNO("%s: read", log_prefix); 1777 - } 1784 + n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC); 1785 + if (n < 0) 1786 + FAIL_ERRNO("%s: recv_timeout", log_prefix); 1778 1787 if (n == 0) 1779 - FAIL("%s: incomplete read", log_prefix); 1788 + FAIL("%s: incomplete recv", log_prefix); 1780 1789 1781 1790 close_cli1: 1782 1791 xclose(c1); ··· 1820 1841 const char *log_prefix = redir_mode_str(mode); 1821 1842 int c0, c1, p0, p1; 1822 1843 unsigned int pass; 1823 - int retries = 100; 1824 1844 int err, n; 1825 1845 int sfd[2]; 1826 1846 u32 key; ··· 1854 1876 if (pass != 1) 1855 1877 FAIL("%s: want pass count 1, have %d", log_prefix, pass); 1856 1878 1857 - again: 1858 - n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1); 1859 - if (n < 0) { 1860 - if (errno == EAGAIN && retries--) { 1861 - usleep(1000); 1862 - goto again; 1863 - } 1864 - FAIL_ERRNO("%s: read", log_prefix); 1865 - } 1879 + n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC); 1880 + if (n < 0) 1881 + FAIL_ERRNO("%s: recv_timeout", log_prefix); 1866 1882 if (n == 0) 1867 - FAIL("%s: incomplete read", log_prefix); 1883 + FAIL("%s: incomplete recv", log_prefix); 1868 1884 1869 1885 close_cli1: 1870 1886 xclose(c1); ··· 1904 1932 int sfd[2]; 1905 1933 u32 key; 1906 1934 char b; 1907 - int retries = 100; 1908 1935 1909 1936 zero_verdict_count(verd_mapfd); 1910 1937 ··· 1934 1963 if (pass != 1) 1935 1964 FAIL("%s: want pass count 1, have %d", log_prefix, pass); 1936 1965 1937 - again: 1938 - n = read(mode == REDIR_INGRESS ? p0 : c0, &b, 1); 1939 - if (n < 0) { 1940 - if (errno == EAGAIN && retries--) { 1941 - usleep(1000); 1942 - goto again; 1943 - } 1944 - FAIL_ERRNO("%s: read", log_prefix); 1945 - } 1966 + n = recv_timeout(mode == REDIR_INGRESS ? p0 : c0, &b, 1, 0, IO_TIMEOUT_SEC); 1967 + if (n < 0) 1968 + FAIL_ERRNO("%s: recv_timeout", log_prefix); 1946 1969 if (n == 0) 1947 - FAIL("%s: incomplete read", log_prefix); 1970 + FAIL("%s: incomplete recv", log_prefix); 1948 1971 1949 1972 close: 1950 1973 xclose(c1);