From: Benoît Ganne Date: Wed, 25 Aug 2021 14:53:22 +0000 (+0200) Subject: af_xdp: fix stale rx/tx pointers in xsk objects X-Git-Tag: v22.02-rc0~99 X-Git-Url: https://gerrit.fd.io/r/gitweb?a=commitdiff_plain;h=4fe2f4c29e3672f38038d34f177a9ccbff18d9ad;p=vpp.git af_xdp: fix stale rx/tx pointers in xsk objects xsk objects keep pointers to the rx and tx objects. If we re-allocate the rx and tx vectors after initializing the associated xsk object, the pointers in the xsk object will be staled. To avoid this, we allocate the vectors to the max expected size instead of growing them. Type: fix Change-Id: If30433a28c186787d66c12dbab34bf210c95b519 Signed-off-by: Benoît Ganne --- diff --git a/src/plugins/af_xdp/device.c b/src/plugins/af_xdp/device.c index 2600170704b..c82b700bbea 100644 --- a/src/plugins/af_xdp/device.c +++ b/src/plugins/af_xdp/device.c @@ -17,7 +17,10 @@ #include #include +#include +#include #include +#include #include #include #include @@ -188,16 +191,9 @@ af_xdp_create_queue (vlib_main_t *vm, af_xdp_create_if_args_t *args, const int is_rx = qid < ad->rxq_num; const int is_tx = qid < ad->txq_num; - vec_validate_aligned (ad->umem, qid, CLIB_CACHE_LINE_BYTES); umem = vec_elt_at_index (ad->umem, qid); - - vec_validate_aligned (ad->xsk, qid, CLIB_CACHE_LINE_BYTES); xsk = vec_elt_at_index (ad->xsk, qid); - - vec_validate_aligned (ad->rxqs, qid, CLIB_CACHE_LINE_BYTES); rxq = vec_elt_at_index (ad->rxqs, qid); - - vec_validate_aligned (ad->txqs, qid, CLIB_CACHE_LINE_BYTES); txq = vec_elt_at_index (ad->txqs, qid); /* @@ -321,6 +317,31 @@ af_xdp_get_numa (const char *ifname) return numa; } +static void +af_xdp_get_q_count (const char *ifname, int *rxq_num, int *txq_num) +{ + struct ethtool_channels ec = { .cmd = ETHTOOL_GCHANNELS }; + struct ifreq ifr = { .ifr_data = (void *) &ec }; + int fd, err; + + *rxq_num = *txq_num = 1; + + fd = socket (AF_INET, SOCK_DGRAM, 0); + if (fd < 0) + return; + + snprintf (ifr.ifr_name, sizeof (ifr.ifr_name), "%s", ifname); + err = ioctl (fd, SIOCETHTOOL, &ifr); + + close (fd); + + if (err) + return; + + *rxq_num = clib_max (ec.combined_count, ec.rx_count); + *txq_num = clib_max (ec.combined_count, ec.tx_count); +} + static clib_error_t * af_xdp_device_rxq_read_ready (clib_file_t * f) { @@ -375,8 +396,7 @@ af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args) args->rxq_size = args->rxq_size ? args->rxq_size : 2 * VLIB_FRAME_SIZE; args->txq_size = args->txq_size ? args->txq_size : 2 * VLIB_FRAME_SIZE; - rxq_num = args->rxq_num ? args->rxq_num : 1; - txq_num = tm->n_vlib_mains; + args->rxq_num = args->rxq_num ? args->rxq_num : 1; if (!args->linux_ifname) { @@ -397,6 +417,17 @@ af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args) goto err0; } + af_xdp_get_q_count (args->linux_ifname, &rxq_num, &txq_num); + if (args->rxq_num > rxq_num && AF_XDP_NUM_RX_QUEUES_ALL != args->rxq_num) + { + args->rv = VNET_API_ERROR_INVALID_VALUE; + args->error = clib_error_create ("too many rxq requested (%d > %d)", + args->rxq_num, rxq_num); + goto err0; + } + rxq_num = clib_min (rxq_num, args->rxq_num); + txq_num = clib_min (txq_num, tm->n_vlib_mains); + pool_get_zero (am->devices, ad); if (tm->n_vlib_mains > 1 && @@ -412,6 +443,12 @@ af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args) q_num = clib_max (rxq_num, txq_num); ad->rxq_num = rxq_num; ad->txq_num = txq_num; + + vec_validate_aligned (ad->umem, q_num - 1, CLIB_CACHE_LINE_BYTES); + vec_validate_aligned (ad->xsk, q_num - 1, CLIB_CACHE_LINE_BYTES); + vec_validate_aligned (ad->rxqs, q_num - 1, CLIB_CACHE_LINE_BYTES); + vec_validate_aligned (ad->txqs, q_num - 1, CLIB_CACHE_LINE_BYTES); + for (i = 0; i < q_num; i++) { if (af_xdp_create_queue (vm, args, ad, i)) @@ -433,7 +470,7 @@ af_xdp_create_if (vlib_main_t * vm, af_xdp_create_if_args_t * args) ad->rxq_num = clib_min (i, rxq_num); ad->txq_num = clib_min (i, txq_num); - if (i < rxq_num && AF_XDP_NUM_RX_QUEUES_ALL != rxq_num) + if (i < rxq_num && AF_XDP_NUM_RX_QUEUES_ALL != args->rxq_num) { ad->rxq_num = ad->txq_num = 0; goto err1; /* failed creating requested rxq: fatal error, bailing