Merge branch 'net-xsk-update-tx-queue-consumer'

Jason Xing says:

====================
net: xsk: update tx queue consumer

Patch 1 makes sure the consumer is updated at the end of generic xmit.
Patch 2 adds corresponding test.
====================

Link: https://patch.msgid.link/20250703141712.33190-1-kerneljasonxing@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jakub Kicinski 2025-07-08 18:28:10 -07:00
commit 01af000187
3 changed files with 66 additions and 8 deletions

View File

@ -300,6 +300,13 @@ static bool xsk_tx_writeable(struct xdp_sock *xs)
return true;
}
static void __xsk_tx_release(struct xdp_sock *xs)
{
__xskq_cons_release(xs->tx);
if (xsk_tx_writeable(xs))
xs->sk.sk_write_space(&xs->sk);
}
static bool xsk_is_bound(struct xdp_sock *xs)
{
if (READ_ONCE(xs->state) == XSK_BOUND) {
@ -407,11 +414,8 @@ void xsk_tx_release(struct xsk_buff_pool *pool)
struct xdp_sock *xs;
rcu_read_lock();
list_for_each_entry_rcu(xs, &pool->xsk_tx_list, tx_list) {
__xskq_cons_release(xs->tx);
if (xsk_tx_writeable(xs))
xs->sk.sk_write_space(&xs->sk);
}
list_for_each_entry_rcu(xs, &pool->xsk_tx_list, tx_list)
__xsk_tx_release(xs);
rcu_read_unlock();
}
EXPORT_SYMBOL(xsk_tx_release);
@ -858,8 +862,7 @@ static int __xsk_generic_xmit(struct sock *sk)
out:
if (sent_frame)
if (xsk_tx_writeable(xs))
sk->sk_write_space(sk);
__xsk_tx_release(xs);
mutex_unlock(&xs->mutex);
return err;

View File

@ -109,6 +109,8 @@
#include <network_helpers.h>
#define MAX_TX_BUDGET_DEFAULT 32
static bool opt_verbose;
static bool opt_print_tests;
static enum test_mode opt_mode = TEST_MODE_ALL;
@ -1091,11 +1093,45 @@ static bool is_pkt_valid(struct pkt *pkt, void *buffer, u64 addr, u32 len)
return true;
}
static u32 load_value(u32 *counter)
{
return __atomic_load_n(counter, __ATOMIC_ACQUIRE);
}
static bool kick_tx_with_check(struct xsk_socket_info *xsk, int *ret)
{
u32 max_budget = MAX_TX_BUDGET_DEFAULT;
u32 cons, ready_to_send;
int delta;
cons = load_value(xsk->tx.consumer);
ready_to_send = load_value(xsk->tx.producer) - cons;
*ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0);
delta = load_value(xsk->tx.consumer) - cons;
/* By default, xsk should consume exact @max_budget descs at one
* send in this case where hitting the max budget limit in while
* loop is triggered in __xsk_generic_xmit(). Please make sure that
* the number of descs to be sent is larger than @max_budget, or
* else the tx.consumer will be updated in xskq_cons_peek_desc()
* in time which hides the issue we try to verify.
*/
if (ready_to_send > max_budget && delta != max_budget)
return false;
return true;
}
static int kick_tx(struct xsk_socket_info *xsk)
{
int ret;
ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0);
if (xsk->check_consumer) {
if (!kick_tx_with_check(xsk, &ret))
return TEST_FAILURE;
} else {
ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0);
}
if (ret >= 0)
return TEST_PASS;
if (errno == ENOBUFS || errno == EAGAIN || errno == EBUSY || errno == ENETDOWN) {
@ -2613,6 +2649,23 @@ static int testapp_adjust_tail_grow_mb(struct test_spec *test)
XSK_UMEM__LARGE_FRAME_SIZE * 2);
}
static int testapp_tx_queue_consumer(struct test_spec *test)
{
int nr_packets;
if (test->mode == TEST_MODE_ZC) {
ksft_test_result_skip("Can not run TX_QUEUE_CONSUMER test for ZC mode\n");
return TEST_SKIP;
}
nr_packets = MAX_TX_BUDGET_DEFAULT + 1;
pkt_stream_replace(test, nr_packets, MIN_PKT_SIZE);
test->ifobj_tx->xsk->batch_size = nr_packets;
test->ifobj_tx->xsk->check_consumer = true;
return testapp_validate_traffic(test);
}
static void run_pkt_test(struct test_spec *test)
{
int ret;
@ -2723,6 +2776,7 @@ static const struct test_spec tests[] = {
{.name = "XDP_ADJUST_TAIL_SHRINK_MULTI_BUFF", .test_func = testapp_adjust_tail_shrink_mb},
{.name = "XDP_ADJUST_TAIL_GROW", .test_func = testapp_adjust_tail_grow},
{.name = "XDP_ADJUST_TAIL_GROW_MULTI_BUFF", .test_func = testapp_adjust_tail_grow_mb},
{.name = "TX_QUEUE_CONSUMER", .test_func = testapp_tx_queue_consumer},
};
static void print_tests(void)

View File

@ -95,6 +95,7 @@ struct xsk_socket_info {
u32 batch_size;
u8 dst_mac[ETH_ALEN];
u8 src_mac[ETH_ALEN];
bool check_consumer;
};
struct pkt {