While testing, it turned out that upon error in the queue creation loop, we never trigger the af_xdp_cleanup() handler. This is because we pass errp instead of a local err pointer into the various AF_XDP setup functions instead of a scheme like:
bool fn(..., Error **errp) { Error *err = NULL; foo(arg, &err); if (err) { handle the error... error_propagate(errp, err); return false; } ... } With a conversion into the above format, the af_xdp_cleanup() handler is called as expected. Also, making sure the XDP program will be removed does require to set s->n_queues to i + 1 since the test is nc->queue_index == s->n_queues - 1, where nc->queue_index was set to i earlier. With both fixed the cleanup triggers as expected. Note the error_propagate() handles a NULL err internally. Signed-off-by: Daniel Borkmann <dan...@iogearbox.net> Cc: Ilya Maximets <i.maxim...@ovn.org> Cc: Jason Wang <jasow...@redhat.com> Cc: Anton Protopopov <as...@isovalent.com> --- net/af-xdp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/net/af-xdp.c b/net/af-xdp.c index b83d9bc47f..5d9857fdd8 100644 --- a/net/af-xdp.c +++ b/net/af-xdp.c @@ -559,12 +559,11 @@ int net_init_af_xdp(const Netdev *netdev, s->map_start_index = opts->map_start_index; } - if (af_xdp_umem_create(s, sock_fds ? sock_fds[i] : -1, errp) || - af_xdp_socket_create(s, opts, errp) || - af_xdp_update_xsk_map(s, errp)) { + if (af_xdp_umem_create(s, sock_fds ? sock_fds[i] : -1, &err) || + af_xdp_socket_create(s, opts, &err) || + af_xdp_update_xsk_map(s, &err)) { /* Make sure the XDP program will be removed. */ - s->n_queues = i; - error_propagate(errp, err); + s->n_queues = i + 1; goto err; } } @@ -586,6 +585,7 @@ int net_init_af_xdp(const Netdev *netdev, err: if (nc0) { qemu_del_net_client(nc0); + error_propagate(errp, err); } return -1; -- 2.43.0