|
@@ -27,6 +27,7 @@
|
|
#include <linux/rtnetlink.h>
|
|
#include <linux/rtnetlink.h>
|
|
#include <linux/sched/signal.h>
|
|
#include <linux/sched/signal.h>
|
|
#include <linux/net.h>
|
|
#include <linux/net.h>
|
|
|
|
+#include <net/xdp_sock.h>
|
|
|
|
|
|
/*
|
|
/*
|
|
* Some useful ethtool_ops methods that're device independent.
|
|
* Some useful ethtool_ops methods that're device independent.
|
|
@@ -1656,7 +1657,9 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
|
|
void __user *useraddr)
|
|
void __user *useraddr)
|
|
{
|
|
{
|
|
struct ethtool_channels channels, curr = { .cmd = ETHTOOL_GCHANNELS };
|
|
struct ethtool_channels channels, curr = { .cmd = ETHTOOL_GCHANNELS };
|
|
|
|
+ u16 from_channel, to_channel;
|
|
u32 max_rx_in_use = 0;
|
|
u32 max_rx_in_use = 0;
|
|
|
|
+ unsigned int i;
|
|
|
|
|
|
if (!dev->ethtool_ops->set_channels || !dev->ethtool_ops->get_channels)
|
|
if (!dev->ethtool_ops->set_channels || !dev->ethtool_ops->get_channels)
|
|
return -EOPNOTSUPP;
|
|
return -EOPNOTSUPP;
|
|
@@ -1680,6 +1683,14 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
|
|
(channels.combined_count + channels.rx_count) <= max_rx_in_use)
|
|
(channels.combined_count + channels.rx_count) <= max_rx_in_use)
|
|
return -EINVAL;
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
+ /* Disabling channels, query zero-copy AF_XDP sockets */
|
|
|
|
+ from_channel = channels.combined_count +
|
|
|
|
+ min(channels.rx_count, channels.tx_count);
|
|
|
|
+ to_channel = curr.combined_count + max(curr.rx_count, curr.tx_count);
|
|
|
|
+ for (i = from_channel; i < to_channel; i++)
|
|
|
|
+ if (xdp_get_umem_from_qid(dev, i))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
return dev->ethtool_ops->set_channels(dev, &channels);
|
|
return dev->ethtool_ops->set_channels(dev, &channels);
|
|
}
|
|
}
|
|
|
|
|