diff options
author | Veaceslav Falico <vfalico@redhat.com> | 2014-01-16 00:02:18 +0100 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-01-16 17:15:41 -0800 |
commit | 1d486bfb66971ebacc2a46a23431ace9af70dc66 (patch) | |
tree | b280bfff1e11a8857f9a2e967e92e6442a9d043b | |
parent | 31cf344caf444ca7411d89c8ac907d886eeab1a7 (diff) |
net: add NETDEV_PRECHANGEMTU to notify before mtu change happens
Currently, if a device changes its mtu, first the change happens (invloving
all the side effects), and after that the NETDEV_CHANGEMTU is sent so that
other devices can catch up with the new mtu. However, if they return
NOTIFY_BAD, then the change is reverted and error returned.
This is a really long and costy operation (sometimes). To fix this, add
NETDEV_PRECHANGEMTU notification which is called prior to any change
actually happening, and if any callee returns NOTIFY_BAD - the change is
aborted. This way we're skipping all the playing with apply/revert the mtu.
CC: "David S. Miller" <davem@davemloft.net>
CC: Jiri Pirko <jiri@resnulli.us>
CC: Eric Dumazet <edumazet@google.com>
CC: Nicolas Dichtel <nicolas.dichtel@6wind.com>
CC: Cong Wang <amwang@redhat.com>
Signed-off-by: Veaceslav Falico <vfalico@redhat.com>
Acked-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/netdevice.h | 3 | ||||
-rw-r--r-- | net/core/dev.c | 5 |
2 files changed, 7 insertions, 1 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 30f6513f3b4d..d7668b881d08 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1718,7 +1718,7 @@ struct pcpu_sw_netstats { #define NETDEV_CHANGE 0x0004 /* Notify device state change */ #define NETDEV_REGISTER 0x0005 #define NETDEV_UNREGISTER 0x0006 -#define NETDEV_CHANGEMTU 0x0007 +#define NETDEV_CHANGEMTU 0x0007 /* notify after mtu change happened */ #define NETDEV_CHANGEADDR 0x0008 #define NETDEV_GOING_DOWN 0x0009 #define NETDEV_CHANGENAME 0x000A @@ -1734,6 +1734,7 @@ struct pcpu_sw_netstats { #define NETDEV_JOIN 0x0014 #define NETDEV_CHANGEUPPER 0x0015 #define NETDEV_RESEND_IGMP 0x0016 +#define NETDEV_PRECHANGEMTU 0x0017 /* notify before mtu change happened */ int register_netdevice_notifier(struct notifier_block *nb); int unregister_netdevice_notifier(struct notifier_block *nb); diff --git a/net/core/dev.c b/net/core/dev.c index b2c1869b04e3..f87bedd51eed 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -5392,6 +5392,11 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) if (!netif_device_present(dev)) return -ENODEV; + err = call_netdevice_notifiers(NETDEV_PRECHANGEMTU, dev); + err = notifier_to_errno(err); + if (err) + return err; + orig_mtu = dev->mtu; err = __dev_set_mtu(dev, new_mtu); |