This patches detects the number of combined channels on a AF_XDP port via using ethtool interface. If the number of combined channels is different from the n_rxq, netdev_afxdp will not be able to get all the packets from that port. Thus, abort the port setup when the case is detected.
Signed-off-by: Yi-Hung Wei <[email protected]> --- Travis CI: https://travis-ci.org/YiHungWei/ovs/builds/627972465 --- lib/netdev-afxdp.c | 15 +++++++++++++++ lib/netdev-linux.c | 27 +++++++++++++++++++++++++++ lib/netdev-linux.h | 2 ++ 3 files changed, 44 insertions(+) diff --git a/lib/netdev-afxdp.c b/lib/netdev-afxdp.c index 58365ed483e3..6d002882d355 100644 --- a/lib/netdev-afxdp.c +++ b/lib/netdev-afxdp.c @@ -601,6 +601,14 @@ netdev_afxdp_set_config(struct netdev *netdev, const struct smap *args, enum afxdp_mode xdp_mode; bool need_wakeup; int new_n_rxq; + int combined_channels; + + if (netdev_linux_ethtool_get_combined_channels(netdev, + &combined_channels)) { + VLOG_INFO("Cannot get the number of combined channels of %s. " + "Defaults it to 1.", netdev_get_name(netdev)); + combined_channels = 1; + } ovs_mutex_lock(&dev->mutex); new_n_rxq = MAX(smap_get_int(args, "n_rxq", NR_QUEUE), 1); @@ -611,6 +619,13 @@ netdev_afxdp_set_config(struct netdev *netdev, const struct smap *args, return EINVAL; } + if (new_n_rxq != combined_channels) { + ovs_mutex_unlock(&dev->mutex); + VLOG_ERR("%s: n_rxq: %d != combined channels: %d.", + netdev_get_name(netdev), new_n_rxq, combined_channels); + return EINVAL; + } + str_xdp_mode = smap_get_def(args, "xdp-mode", "best-effort"); for (xdp_mode = OVS_AF_XDP_MODE_BEST_EFFORT; xdp_mode < OVS_AF_XDP_MODE_MAX; diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index f8e59bacfb13..e3086fc1cbb6 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -2166,6 +2166,33 @@ out: netdev->get_features_error = error; } +int +netdev_linux_ethtool_get_combined_channels(struct netdev *netdev_, + int *combined_channels) +{ + struct netdev_linux *netdev = netdev_linux_cast(netdev_); + struct ethtool_channels echannels; + int err; + + ovs_mutex_lock(&netdev->mutex); + + COVERAGE_INC(netdev_get_ethtool); + + memset(&echannels, 0, sizeof echannels); + err = netdev_linux_do_ethtool(netdev_get_name(netdev_), + (struct ethtool_cmd *) &echannels, + ETHTOOL_GCHANNELS, "ETHTOOL_GCHANNELS"); + if (err) { + goto exit; + } + + *combined_channels = echannels.combined_count; + +exit: + ovs_mutex_unlock(&netdev->mutex); + return err; +} + /* Stores the features supported by 'netdev' into of '*current', '*advertised', * '*supported', and '*peer'. Each value is a bitmap of NETDEV_* bits. * Returns 0 if successful, otherwise a positive errno value. */ diff --git a/lib/netdev-linux.h b/lib/netdev-linux.h index e1e30f806557..55cade4bb356 100644 --- a/lib/netdev-linux.h +++ b/lib/netdev-linux.h @@ -27,6 +27,8 @@ struct netdev; int netdev_linux_ethtool_set_flag(struct netdev *netdev, uint32_t flag, const char *flag_name, bool enable); +int netdev_linux_ethtool_get_combined_channels(struct netdev *netdev, + int *combined_channels); int linux_get_ifindex(const char *netdev_name); #endif /* netdev-linux.h */ -- 2.17.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
