Commit f90062b5 authored by Magnus Karlsson's avatar Magnus Karlsson Committed by Alexei Starovoitov

selftests: xsk: run all tests for busy-poll

Execute all xsk selftests for busy-poll mode too. Currently they were
only run for the standard interrupt driven softirq mode. Replace the
unused option queue-id with the new option busy-poll.
Signed-off-by: default avatarMagnus Karlsson <magnus.karlsson@intel.com>
Link: https://lore.kernel.org/r/20220510115604.8717-4-magnus.karlsson@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent f3e619bb
...@@ -109,6 +109,14 @@ setup_vethPairs() { ...@@ -109,6 +109,14 @@ setup_vethPairs() {
if [[ $verbose -eq 1 ]]; then if [[ $verbose -eq 1 ]]; then
echo "setting up ${VETH1}: namespace: ${NS1}" echo "setting up ${VETH1}: namespace: ${NS1}"
fi fi
if [[ $busy_poll -eq 1 ]]; then
echo 2 > /sys/class/net/${VETH0}/napi_defer_hard_irqs
echo 200000 > /sys/class/net/${VETH0}/gro_flush_timeout
echo 2 > /sys/class/net/${VETH1}/napi_defer_hard_irqs
echo 200000 > /sys/class/net/${VETH1}/gro_flush_timeout
fi
ip link set ${VETH1} netns ${NS1} ip link set ${VETH1} netns ${NS1}
ip netns exec ${NS1} ip link set ${VETH1} mtu ${MTU} ip netns exec ${NS1} ip link set ${VETH1} mtu ${MTU}
ip link set ${VETH0} mtu ${MTU} ip link set ${VETH0} mtu ${MTU}
...@@ -130,11 +138,11 @@ if [ $retval -ne 0 ]; then ...@@ -130,11 +138,11 @@ if [ $retval -ne 0 ]; then
fi fi
if [[ $verbose -eq 1 ]]; then if [[ $verbose -eq 1 ]]; then
VERBOSE_ARG="-v" ARGS+="-v "
fi fi
if [[ $dump_pkts -eq 1 ]]; then if [[ $dump_pkts -eq 1 ]]; then
DUMP_PKTS_ARG="-D" ARGS="-D "
fi fi
test_status $retval "${TEST_NAME}" test_status $retval "${TEST_NAME}"
...@@ -143,8 +151,19 @@ test_status $retval "${TEST_NAME}" ...@@ -143,8 +151,19 @@ test_status $retval "${TEST_NAME}"
statusList=() statusList=()
TEST_NAME="XSK KSELFTESTS" TEST_NAME="XSK_SELFTESTS_SOFTIRQ"
execxdpxceiver
retval=$?
test_status $retval "${TEST_NAME}"
statusList+=($retval)
cleanup_exit ${VETH0} ${VETH1} ${NS1}
TEST_NAME="XSK_SELFTESTS_BUSY_POLL"
busy_poll=1
setup_vethPairs
execxdpxceiver execxdpxceiver
retval=$? retval=$?
......
...@@ -90,6 +90,7 @@ ...@@ -90,6 +90,7 @@
#include <string.h> #include <string.h>
#include <stddef.h> #include <stddef.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/socket.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/queue.h> #include <sys/queue.h>
#include <time.h> #include <time.h>
...@@ -122,9 +123,11 @@ static void __exit_with_error(int error, const char *file, const char *func, int ...@@ -122,9 +123,11 @@ static void __exit_with_error(int error, const char *file, const char *func, int
#define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__) #define exit_with_error(error) __exit_with_error(error, __FILE__, __func__, __LINE__)
#define mode_string(test) (test)->ifobj_tx->xdp_flags & XDP_FLAGS_SKB_MODE ? "SKB" : "DRV" #define mode_string(test) (test)->ifobj_tx->xdp_flags & XDP_FLAGS_SKB_MODE ? "SKB" : "DRV"
#define busy_poll_string(test) (test)->ifobj_tx->busy_poll ? "BUSY-POLL " : ""
#define print_ksft_result(test) \ #define print_ksft_result(test) \
(ksft_test_result_pass("PASS: %s %s\n", mode_string(test), (test)->name)) (ksft_test_result_pass("PASS: %s %s%s\n", mode_string(test), busy_poll_string(test), \
(test)->name))
static void memset32_htonl(void *dest, u32 val, u32 size) static void memset32_htonl(void *dest, u32 val, u32 size)
{ {
...@@ -264,6 +267,26 @@ static int xsk_configure_umem(struct xsk_umem_info *umem, void *buffer, u64 size ...@@ -264,6 +267,26 @@ static int xsk_configure_umem(struct xsk_umem_info *umem, void *buffer, u64 size
return 0; return 0;
} }
static void enable_busy_poll(struct xsk_socket_info *xsk)
{
int sock_opt;
sock_opt = 1;
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_PREFER_BUSY_POLL,
(void *)&sock_opt, sizeof(sock_opt)) < 0)
exit_with_error(errno);
sock_opt = 20;
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL,
(void *)&sock_opt, sizeof(sock_opt)) < 0)
exit_with_error(errno);
sock_opt = BATCH_SIZE;
if (setsockopt(xsk_socket__fd(xsk->xsk), SOL_SOCKET, SO_BUSY_POLL_BUDGET,
(void *)&sock_opt, sizeof(sock_opt)) < 0)
exit_with_error(errno);
}
static int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem, static int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_info *umem,
struct ifobject *ifobject, bool shared) struct ifobject *ifobject, bool shared)
{ {
...@@ -287,8 +310,8 @@ static int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_inf ...@@ -287,8 +310,8 @@ static int xsk_configure_socket(struct xsk_socket_info *xsk, struct xsk_umem_inf
static struct option long_options[] = { static struct option long_options[] = {
{"interface", required_argument, 0, 'i'}, {"interface", required_argument, 0, 'i'},
{"queue", optional_argument, 0, 'q'}, {"busy-poll", no_argument, 0, 'b'},
{"dump-pkts", optional_argument, 0, 'D'}, {"dump-pkts", no_argument, 0, 'D'},
{"verbose", no_argument, 0, 'v'}, {"verbose", no_argument, 0, 'v'},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
...@@ -299,9 +322,9 @@ static void usage(const char *prog) ...@@ -299,9 +322,9 @@ static void usage(const char *prog)
" Usage: %s [OPTIONS]\n" " Usage: %s [OPTIONS]\n"
" Options:\n" " Options:\n"
" -i, --interface Use interface\n" " -i, --interface Use interface\n"
" -q, --queue=n Use queue n (default 0)\n"
" -D, --dump-pkts Dump packets L2 - L5\n" " -D, --dump-pkts Dump packets L2 - L5\n"
" -v, --verbose Verbose output\n"; " -v, --verbose Verbose output\n"
" -b, --busy-poll Enable busy poll\n";
ksft_print_msg(str, prog); ksft_print_msg(str, prog);
} }
...@@ -347,7 +370,7 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj ...@@ -347,7 +370,7 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
for (;;) { for (;;) {
char *sptr, *token; char *sptr, *token;
c = getopt_long(argc, argv, "i:Dv", long_options, &option_index); c = getopt_long(argc, argv, "i:Dvb", long_options, &option_index);
if (c == -1) if (c == -1)
break; break;
...@@ -373,6 +396,10 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj ...@@ -373,6 +396,10 @@ static void parse_command_line(struct ifobject *ifobj_tx, struct ifobject *ifobj
case 'v': case 'v':
opt_verbose = true; opt_verbose = true;
break; break;
case 'b':
ifobj_tx->busy_poll = true;
ifobj_rx->busy_poll = true;
break;
default: default:
usage(basename(argv[0])); usage(basename(argv[0]));
ksft_exit_xfail(); ksft_exit_xfail();
...@@ -716,11 +743,24 @@ static void kick_tx(struct xsk_socket_info *xsk) ...@@ -716,11 +743,24 @@ static void kick_tx(struct xsk_socket_info *xsk)
int ret; int ret;
ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0); ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0);
if (ret >= 0 || errno == ENOBUFS || errno == EAGAIN || errno == EBUSY || errno == ENETDOWN) if (ret >= 0)
return;
if (errno == ENOBUFS || errno == EAGAIN || errno == EBUSY || errno == ENETDOWN) {
usleep(100);
return; return;
}
exit_with_error(errno); exit_with_error(errno);
} }
static void kick_rx(struct xsk_socket_info *xsk)
{
int ret;
ret = recvfrom(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, NULL);
if (ret < 0)
exit_with_error(errno);
}
static void complete_pkts(struct xsk_socket_info *xsk, int batch_size) static void complete_pkts(struct xsk_socket_info *xsk, int batch_size)
{ {
unsigned int rcvd; unsigned int rcvd;
...@@ -745,15 +785,18 @@ static void complete_pkts(struct xsk_socket_info *xsk, int batch_size) ...@@ -745,15 +785,18 @@ static void complete_pkts(struct xsk_socket_info *xsk, int batch_size)
} }
} }
static void receive_pkts(struct pkt_stream *pkt_stream, struct xsk_socket_info *xsk, static void receive_pkts(struct ifobject *ifobj, struct pollfd *fds)
struct pollfd *fds)
{ {
struct pkt_stream *pkt_stream = ifobj->pkt_stream;
struct pkt *pkt = pkt_stream_get_next_rx_pkt(pkt_stream); struct pkt *pkt = pkt_stream_get_next_rx_pkt(pkt_stream);
struct xsk_socket_info *xsk = ifobj->xsk;
struct xsk_umem_info *umem = xsk->umem; struct xsk_umem_info *umem = xsk->umem;
u32 idx_rx = 0, idx_fq = 0, rcvd, i; u32 idx_rx = 0, idx_fq = 0, rcvd, i;
int ret; int ret;
while (pkt) { while (pkt) {
kick_rx(xsk);
rcvd = xsk_ring_cons__peek(&xsk->rx, BATCH_SIZE, &idx_rx); rcvd = xsk_ring_cons__peek(&xsk->rx, BATCH_SIZE, &idx_rx);
if (!rcvd) { if (!rcvd) {
if (xsk_ring_prod__needs_wakeup(&umem->fq)) { if (xsk_ring_prod__needs_wakeup(&umem->fq)) {
...@@ -890,6 +933,8 @@ static bool rx_stats_are_valid(struct ifobject *ifobject) ...@@ -890,6 +933,8 @@ static bool rx_stats_are_valid(struct ifobject *ifobject)
socklen_t optlen; socklen_t optlen;
int err; int err;
kick_rx(ifobject->xsk);
optlen = sizeof(stats); optlen = sizeof(stats);
err = getsockopt(fd, SOL_XDP, XDP_STATISTICS, &stats, &optlen); err = getsockopt(fd, SOL_XDP, XDP_STATISTICS, &stats, &optlen);
if (err) { if (err) {
...@@ -984,6 +1029,9 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject) ...@@ -984,6 +1029,9 @@ static void thread_common_ops(struct test_spec *test, struct ifobject *ifobject)
exit_with_error(-ret); exit_with_error(-ret);
usleep(USLEEP_MAX); usleep(USLEEP_MAX);
} }
if (ifobject->busy_poll)
enable_busy_poll(&ifobject->xsk_arr[i]);
} }
ifobject->xsk = &ifobject->xsk_arr[0]; ifobject->xsk = &ifobject->xsk_arr[0];
...@@ -1083,7 +1131,7 @@ static void *worker_testapp_validate_rx(void *arg) ...@@ -1083,7 +1131,7 @@ static void *worker_testapp_validate_rx(void *arg)
while (!rx_stats_are_valid(ifobject)) while (!rx_stats_are_valid(ifobject))
continue; continue;
else else
receive_pkts(ifobject->pkt_stream, ifobject->xsk, &fds); receive_pkts(ifobject, &fds);
if (test->total_steps == test->current_step) if (test->total_steps == test->current_step)
testapp_cleanup_xsk_res(ifobject); testapp_cleanup_xsk_res(ifobject);
......
...@@ -17,6 +17,14 @@ ...@@ -17,6 +17,14 @@
#define PF_XDP AF_XDP #define PF_XDP AF_XDP
#endif #endif
#ifndef SO_BUSY_POLL_BUDGET
#define SO_BUSY_POLL_BUDGET 70
#endif
#ifndef SO_PREFER_BUSY_POLL
#define SO_PREFER_BUSY_POLL 69
#endif
#define MAX_INTERFACES 2 #define MAX_INTERFACES 2
#define MAX_INTERFACE_NAME_CHARS 7 #define MAX_INTERFACE_NAME_CHARS 7
#define MAX_INTERFACES_NAMESPACE_CHARS 10 #define MAX_INTERFACES_NAMESPACE_CHARS 10
...@@ -139,6 +147,7 @@ struct ifobject { ...@@ -139,6 +147,7 @@ struct ifobject {
bool tx_on; bool tx_on;
bool rx_on; bool rx_on;
bool use_poll; bool use_poll;
bool busy_poll;
bool pacing_on; bool pacing_on;
u8 dst_mac[ETH_ALEN]; u8 dst_mac[ETH_ALEN];
u8 src_mac[ETH_ALEN]; u8 src_mac[ETH_ALEN];
......
...@@ -80,5 +80,9 @@ validate_ip_utility() ...@@ -80,5 +80,9 @@ validate_ip_utility()
execxdpxceiver() execxdpxceiver()
{ {
./${XSKOBJ} -i ${VETH0} -i ${VETH1},${NS1} ${VERBOSE_ARG} ${DUMP_PKTS_ARG} if [[ $busy_poll -eq 1 ]]; then
ARGS+="-b "
fi
./${XSKOBJ} -i ${VETH0} -i ${VETH1},${NS1} ${ARGS}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment