This patch created on earlier patch "v2 netdev-linux: Use get-stats to check status on linux devices."
--8<--------------------------cut here-------------------------->8- netdev linux devices uses SIOCGIFMTU ioctl to read MTU for a device. By caching error code from ioctl we can reduce number of ioctl calls for device which is unregistered from system. Signed-off-by: Pravin B Shelar <[email protected]> --- lib/netdev-linux.c | 42 ++++++++++++++++++++++++++++++------------ lib/netdev.c | 4 ++-- lib/rtnetlink-link.c | 5 +++++ lib/rtnetlink-link.h | 1 + 4 files changed, 38 insertions(+), 14 deletions(-) diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c index 8de037a..501d1de 100644 --- a/lib/netdev-linux.c +++ b/lib/netdev-linux.c @@ -368,7 +368,8 @@ struct netdev_dev_linux { uint8_t etheraddr[ETH_ADDR_LEN]; struct in_addr address, netmask; struct in6_addr in6; - int mtu; + int mtu; /* Cashed MTU value or error code from + SIOCGIFMTU. */ unsigned int ifi_flags; long long int carrier_resets; uint32_t kbits_rate; /* Policing data. */ @@ -508,27 +509,30 @@ netdev_linux_get_drvinfo(struct netdev_dev_linux *netdev_dev) static void netdev_dev_linux_changed(struct netdev_dev_linux *dev, - unsigned int ifi_flags, - uint16_t change) + const struct rtnetlink_link_change *change) { dev->change_seq++; if (!dev->change_seq) { dev->change_seq++; } - if ((dev->ifi_flags ^ ifi_flags) & IFF_RUNNING) { + if ((dev->ifi_flags ^ change->ifi_flags) & IFF_RUNNING) { dev->carrier_resets++; } - dev->ifi_flags = ifi_flags; + dev->ifi_flags = change->ifi_flags; /* Always cache driver-info. */ dev->cache_valid &= VALID_DRVINFO; - if (change == RTM_NEWLINK) { + if (change->nlmsg_type == RTM_NEWLINK) { /* Required for internal devices. */ netdev_linux_get_drvinfo(dev); } + if (change->nlmsg_type != RTM_DELLINK) { + dev->mtu = change->mtu; + dev->cache_valid |= VALID_MTU; + } } static void @@ -544,12 +548,16 @@ netdev_linux_cache_cb(const struct rtnetlink_link_change *change, if (is_netdev_linux_class(netdev_class)) { dev = netdev_dev_linux_cast(base_dev); - netdev_dev_linux_changed(dev, change->ifi_flags, change->nlmsg_type); + netdev_dev_linux_changed(dev, change); } } } else { struct shash device_shash; struct shash_node *node; + struct rtnetlink_link_change dev_change; + + memset(&dev_change, 0, sizeof(dev_change)); + dev_change.nlmsg_type = change->nlmsg_type; shash_init(&device_shash); netdev_dev_get_devices(&netdev_linux_class, &device_shash); @@ -557,9 +565,9 @@ netdev_linux_cache_cb(const struct rtnetlink_link_change *change, unsigned int flags; dev = node->data; - get_flags(&dev->netdev_dev, &flags); - netdev_dev_linux_changed(dev, flags, change->nlmsg_type); + dev_change.ifi_flags = flags; + netdev_dev_linux_changed(dev, &dev_change); } shash_destroy(&device_shash); } @@ -1060,11 +1068,15 @@ netdev_linux_get_mtu(const struct netdev *netdev_, int *mtup) error = netdev_linux_do_ioctl(netdev_get_name(netdev_), &ifr, SIOCGIFMTU, "SIOCGIFMTU"); if (error) { - return error; + netdev_dev->mtu = -error; + } else { + netdev_dev->mtu = ifr.ifr_mtu; } - netdev_dev->mtu = ifr.ifr_mtu; netdev_dev->cache_valid |= VALID_MTU; } + if (netdev_dev->mtu < 0) { + return -netdev_dev->mtu; + } *mtup = netdev_dev->mtu; return 0; } @@ -1221,8 +1233,14 @@ netdev_linux_miimon_run(void) netdev_linux_get_miimon(dev->netdev_dev.name, &miimon); if (miimon != dev->miimon) { + struct rtnetlink_link_change dev_change; + dev->miimon = miimon; - netdev_dev_linux_changed(dev, dev->ifi_flags, 0); + + memset(&dev_change, 0, sizeof(dev_change)); + dev_change.ifi_flags = dev->ifi_flags; + + netdev_dev_linux_changed(dev, &dev_change); } timer_set_duration(&dev->miimon_timer, dev->miimon_interval); diff --git a/lib/netdev.c b/lib/netdev.c index eff6e4c..407e333 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -516,7 +516,7 @@ netdev_get_mtu(const struct netdev *netdev, int *mtup) if (error) { *mtup = 0; if (error != EOPNOTSUPP) { - VLOG_WARN_RL(&rl, "failed to retrieve MTU for network device %s: " + VLOG_DBG_RL(&rl, "failed to retrieve MTU for network device %s: " "%s", netdev_get_name(netdev), strerror(error)); } } @@ -537,7 +537,7 @@ netdev_set_mtu(const struct netdev *netdev, int mtu) error = class->set_mtu ? class->set_mtu(netdev, mtu) : EOPNOTSUPP; if (error && error != EOPNOTSUPP) { - VLOG_WARN_RL(&rl, "failed to retrieve MTU for network device %s: %s", + VLOG_DBG_RL(&rl, "failed to retrieve MTU for network device %s: %s", netdev_get_name(netdev), strerror(error)); } diff --git a/lib/rtnetlink-link.c b/lib/rtnetlink-link.c index 60b71be..d14f0e3 100644 --- a/lib/rtnetlink-link.c +++ b/lib/rtnetlink-link.c @@ -45,6 +45,7 @@ rtnetlink_link_parse(struct ofpbuf *buf, static const struct nl_policy policy[] = { [IFLA_IFNAME] = { .type = NL_A_STRING, .optional = false }, [IFLA_MASTER] = { .type = NL_A_U32, .optional = true }, + [IFLA_MTU] = { .type = NL_A_U32, .optional = true }, }; static struct nlattr *attrs[ARRAY_SIZE(policy)]; @@ -67,6 +68,10 @@ rtnetlink_link_parse(struct ofpbuf *buf, change->master_ifindex = (attrs[IFLA_MASTER] ? nl_attr_get_u32(attrs[IFLA_MASTER]) : 0); + change->mtu = (attrs[IFLA_MTU] + ? nl_attr_get_u32(attrs[IFLA_MTU]) + : 0); + } return parsed; diff --git a/lib/rtnetlink-link.h b/lib/rtnetlink-link.h index b6ddb21..cfdb24b 100644 --- a/lib/rtnetlink-link.h +++ b/lib/rtnetlink-link.h @@ -37,6 +37,7 @@ struct rtnetlink_link_change { /* Extracted from Netlink attributes. */ const char *ifname; /* Name of network device. */ int master_ifindex; /* Ifindex of datapath master (0 if none). */ + int mtu; /* Current MTU. */ unsigned int ifi_flags; /* Flags of network device. */ }; -- 1.7.1 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
