Netdev flags are queried multiple times per poll loop. Sending a GETLINK command for each can be very inefficient if there is RTNL lock contention.
Cache the result of the query as we do with other netdev attributes. Signed-off-by: Adrian Moreno <[email protected]> --- lib/netdev-linux.c | 15 ++++++++++++--- lib/tnl-ports.c | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index c464b24d4..f1a9e5fcd 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -264,6 +264,7 @@ enum { VALID_DRVINFO = 1 << 6, VALID_FEATURES = 1 << 7, VALID_NUMA_ID = 1 << 8, + VALID_FLAGS = 1 << 9, }; /* Linux 4.4 introduced the ability to skip the internal stats gathering @@ -829,7 +830,7 @@ netdev_linux_run(const struct netdev_class *netdev_class OVS_UNUSED) ovs_mutex_lock(&netdev->mutex); update_flags_local(netdev); - netdev_linux_changed(netdev, netdev->ifi_flags, 0); + netdev_linux_changed(netdev, netdev->ifi_flags, VALID_FLAGS); ovs_mutex_unlock(&netdev->mutex); netdev_close(netdev_); @@ -909,6 +910,7 @@ netdev_linux_update__(struct netdev_linux *dev, dev->ifindex = change->if_index; dev->cache_valid |= VALID_IFINDEX; + dev->cache_valid |= VALID_FLAGS; dev->get_ifindex_error = 0; dev->present = true; } else { @@ -3845,7 +3847,11 @@ static int update_flags_local(struct netdev_linux *netdev) OVS_REQUIRES(netdev->mutex) { - return get_flags(&netdev->up, &netdev->ifi_flags); + int error = get_flags(&netdev->up, &netdev->ifi_flags); + if (!error) { + netdev->cache_valid |= VALID_FLAGS; + } + return error; } static int @@ -3884,7 +3890,8 @@ netdev_linux_update_flags(struct netdev *netdev_, enum netdev_flags off, error = modify_flags(netdev, off, on, old_flagsp); } else { /* Try reading flags over netlink, or fall back to ioctl. */ - if (netdev_linux_update_via_netlink(netdev)) { + if (!(netdev->cache_valid & VALID_FLAGS) && + netdev_linux_update_via_netlink(netdev)) { error = update_flags_local(netdev); } *old_flagsp = iff_to_nd_flags(netdev->ifi_flags); @@ -6951,6 +6958,8 @@ netdev_linux_update_via_netlink(struct netdev_linux *netdev) netdev->ifi_flags = change->ifi_flags; changed = true; } + netdev->cache_valid |= VALID_FLAGS; + if (change->mtu && change->mtu != netdev->mtu) { netdev->mtu = change->mtu; netdev->cache_valid |= VALID_MTU; diff --git a/lib/tnl-ports.c b/lib/tnl-ports.c index 56119b300..67b6ebcf7 100644 --- a/lib/tnl-ports.c +++ b/lib/tnl-ports.c @@ -402,13 +402,13 @@ insert_ipdev__(struct netdev *dev, ip_dev = xzalloc(sizeof *ip_dev); ip_dev->dev = netdev_ref(dev); - ip_dev->change_seq = netdev_get_change_seq(dev); error = netdev_get_etheraddr(ip_dev->dev, &ip_dev->mac); if (error) { goto err_free_ipdev; } ip_dev->addr = addr; ip_dev->n_addr = n_addr; + ip_dev->change_seq = netdev_get_change_seq(dev); ovs_strlcpy(ip_dev->dev_name, netdev_get_name(dev), sizeof ip_dev->dev_name); ovs_list_insert(&addr_list, &ip_dev->node); map_insert_ipdev(ip_dev); -- 2.52.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
