diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cd46d3d63aa08018f780d3ea8b07631785fc5eea..4c77f39ebd65e60d2b7491065771566aadc12ce5 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -3331,6 +3331,7 @@ int dev_get_alias(const struct net_device *, char *, size_t); int dev_change_net_namespace(struct net_device *, struct net *, const char *); int __dev_set_mtu(struct net_device *, int); int dev_set_mtu(struct net_device *, int); +int dev_change_tx_queue_len(struct net_device *, unsigned long); void dev_set_group(struct net_device *, int); int dev_set_mac_address(struct net_device *, struct sockaddr *); int dev_change_carrier(struct net_device *, bool new_carrier); diff --git a/net/core/dev.c b/net/core/dev.c index 858501b12869e9633fee187ef2ab83301233a4fc..520c24671bc53e3d13abdd463606a7e15ca177d3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -7047,6 +7047,34 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) } EXPORT_SYMBOL(dev_set_mtu); +/** + * dev_change_tx_queue_len - Change TX queue length of a netdevice + * @dev: device + * @new_len: new tx queue length + */ +int dev_change_tx_queue_len(struct net_device *dev, unsigned long new_len) +{ + unsigned int orig_len = dev->tx_queue_len; + int res; + + if (new_len != (unsigned int)new_len) + return -ERANGE; + + if (new_len != orig_len) { + dev->tx_queue_len = new_len; + res = call_netdevice_notifiers(NETDEV_CHANGE_TX_QUEUE_LEN, dev); + res = notifier_to_errno(res); + if (res) { + netdev_err(dev, + "refused to change device tx_queue_len\n"); + dev->tx_queue_len = orig_len; + return res; + } + } + + return 0; +} + /** * dev_set_group - Change group this device belongs to * @dev: device diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index c4a28f4667b691bb98a7ff5e3c6622380727725f..60a5ad2c33ee33a3daf3e951389cb16c7f465867 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c @@ -346,29 +346,6 @@ static ssize_t flags_store(struct device *dev, struct device_attribute *attr, } NETDEVICE_SHOW_RW(flags, fmt_hex); -static int change_tx_queue_len(struct net_device *dev, unsigned long new_len) -{ - unsigned int orig_len = dev->tx_queue_len; - int res; - - if (new_len != (unsigned int)new_len) - return -ERANGE; - - if (new_len != orig_len) { - dev->tx_queue_len = new_len; - res = call_netdevice_notifiers(NETDEV_CHANGE_TX_QUEUE_LEN, dev); - res = notifier_to_errno(res); - if (res) { - netdev_err(dev, - "refused to change device tx_queue_len\n"); - dev->tx_queue_len = orig_len; - return -EFAULT; - } - } - - return 0; -} - static ssize_t tx_queue_len_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t len) @@ -376,7 +353,7 @@ static ssize_t tx_queue_len_store(struct device *dev, if (!capable(CAP_NET_ADMIN)) return -EPERM; - return netdev_store(dev, attr, buf, len, change_tx_queue_len); + return netdev_store(dev, attr, buf, len, dev_change_tx_queue_len); } NETDEVICE_SHOW_RW(tx_queue_len, fmt_dec); diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index e04af7b7f448b8bdc0792545c0a7519d77e3f504..061e27cb6c121249c18d763c0856305e8f32c435 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -2337,19 +2337,11 @@ static int do_setlink(const struct sk_buff *skb, if (tb[IFLA_TXQLEN]) { unsigned int value = nla_get_u32(tb[IFLA_TXQLEN]); - unsigned int orig_len = dev->tx_queue_len; - - if (dev->tx_queue_len ^ value) { - dev->tx_queue_len = value; - err = call_netdevice_notifiers( - NETDEV_CHANGE_TX_QUEUE_LEN, dev); - err = notifier_to_errno(err); - if (err) { - dev->tx_queue_len = orig_len; - goto errout; - } - status |= DO_SETLINK_MODIFIED; - } + + err = dev_change_tx_queue_len(dev, value); + if (err) + goto errout; + status |= DO_SETLINK_MODIFIED; } if (tb[IFLA_GSO_MAX_SIZE]) {