Skip to content

Commit

Permalink
ethtool: don't allow disabling queues with umem installed
Browse files Browse the repository at this point in the history
We already check the RSS indirection table does not use queues which
would be disabled by channel reconfiguration. Make sure user does not
try to disable queues which have a UMEM and zero-copy AF_XDP socket
installed.

Signed-off-by: Jakub Kicinski <[email protected]>
Reviewed-by: Quentin Monnet <[email protected]>
Signed-off-by: Daniel Borkmann <[email protected]>
  • Loading branch information
Jakub Kicinski authored and borkmann committed Oct 5, 2018
1 parent b8c8a2e commit 1661d34
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 2 deletions.
7 changes: 7 additions & 0 deletions include/net/xdp_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct xdp_umem_fq_reuse *xsk_reuseq_prepare(u32 nentries);
struct xdp_umem_fq_reuse *xsk_reuseq_swap(struct xdp_umem *umem,
struct xdp_umem_fq_reuse *newq);
void xsk_reuseq_free(struct xdp_umem_fq_reuse *rq);
struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev, u16 queue_id);

static inline char *xdp_umem_get_data(struct xdp_umem *umem, u64 addr)
{
Expand Down Expand Up @@ -183,6 +184,12 @@ static inline void xsk_reuseq_free(struct xdp_umem_fq_reuse *rq)
{
}

static inline struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
u16 queue_id)
{
return NULL;
}

static inline char *xdp_umem_get_data(struct xdp_umem *umem, u64 addr)
{
return NULL;
Expand Down
11 changes: 11 additions & 0 deletions net/core/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <linux/rtnetlink.h>
#include <linux/sched/signal.h>
#include <linux/net.h>
#include <net/xdp_sock.h>

/*
* Some useful ethtool_ops methods that're device independent.
Expand Down Expand Up @@ -1656,7 +1657,9 @@ static noinline_for_stack int ethtool_set_channels(struct net_device *dev,
void __user *useraddr)
{
struct ethtool_channels channels, curr = { .cmd = ETHTOOL_GCHANNELS };
u16 from_channel, to_channel;
u32 max_rx_in_use = 0;
unsigned int i;

if (!dev->ethtool_ops->set_channels || !dev->ethtool_ops->get_channels)
return -EOPNOTSUPP;
Expand All @@ -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)
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);
}

Expand Down
4 changes: 2 additions & 2 deletions net/xdp/xdp_umem.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ static void xdp_reg_umem_at_qid(struct net_device *dev, struct xdp_umem *umem,
dev->_tx[queue_id].umem = umem;
}

static struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
u16 queue_id)
struct xdp_umem *xdp_get_umem_from_qid(struct net_device *dev,
u16 queue_id)
{
if (queue_id < dev->real_num_rx_queues)
return dev->_rx[queue_id].umem;
Expand Down

0 comments on commit 1661d34

Please sign in to comment.