[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1525864903-32619-2-git-send-email-michael.chan@broadcom.com>
Date: Wed, 9 May 2018 07:21:41 -0400
From: Michael Chan <michael.chan@...adcom.com>
To: davem@...emloft.net
Cc: netdev@...r.kernel.org
Subject: [PATCH net-next RFC 1/3] net: Add support to configure SR-IOV VF minimum and maximum queues.
VF Queue resources are always limited and there is currently no
infrastructure to allow the admin. on the host to add or reduce queue
resources for any particular VF. With ever increasing number of VFs
being supported, it is desirable to allow the admin. to configure queue
resources differently for the VFs. Some VFs may require more or fewer
queues due to different bandwidth requirements or different number of
vCPUs in the VM. This patch adds the infrastructure to do that by
adding IFLA_VF_QUEUES netlink attribute and a new .ndo_set_vf_queues()
to the net_device_ops.
Four parameters are exposed for each VF:
o min_tx_queues - Guaranteed or current tx queues assigned to the VF.
o max_tx_queues - Maximum but not necessarily guaranteed tx queues
available to the VF.
o min_rx_queues - Guaranteed or current rx queues assigned to the VF.
o max_rx_queues - Maximum but not necessarily guaranteed rx queues
available to the VF.
The "ip link set" command will subsequently be patched to support the new
operation to set the above parameters.
After the admin. makes a change to the above parameters, the corresponding
VF will have a new range of channels to set using ethtool -L.
Signed-off-by: Michael Chan <michael.chan@...adcom.com>
---
include/linux/if_link.h | 4 ++++
include/linux/netdevice.h | 6 ++++++
include/uapi/linux/if_link.h | 9 +++++++++
net/core/rtnetlink.c | 28 +++++++++++++++++++++++++---
4 files changed, 44 insertions(+), 3 deletions(-)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 622658d..8e81121 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -29,5 +29,9 @@ struct ifla_vf_info {
__u32 rss_query_en;
__u32 trusted;
__be16 vlan_proto;
+ __u32 min_tx_queues;
+ __u32 max_tx_queues;
+ __u32 min_rx_queues;
+ __u32 max_rx_queues;
};
#endif /* _LINUX_IF_LINK_H */
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 03ed492..30a3caf 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1023,6 +1023,8 @@ struct dev_ifalias {
* with PF and querying it may introduce a theoretical security risk.
* int (*ndo_set_vf_rss_query_en)(struct net_device *dev, int vf, bool setting);
* int (*ndo_get_vf_port)(struct net_device *dev, int vf, struct sk_buff *skb);
+ * int (*ndo_set_vf_queues)(struct net_device *dev, int vf, int min_txq,
+ * int max_txq, int min_rxq, int max_rxq);
* int (*ndo_setup_tc)(struct net_device *dev, enum tc_setup_type type,
* void *type_data);
* Called to setup any 'tc' scheduler, classifier or action on @dev.
@@ -1272,6 +1274,10 @@ struct net_device_ops {
int (*ndo_set_vf_rss_query_en)(
struct net_device *dev,
int vf, bool setting);
+ int (*ndo_set_vf_queues)(struct net_device *dev,
+ int vf,
+ int min_txq, int max_txq,
+ int min_rxq, int max_rxq);
int (*ndo_setup_tc)(struct net_device *dev,
enum tc_setup_type type,
void *type_data);
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index b852664..fc56a47 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -658,6 +658,7 @@ enum {
IFLA_VF_IB_NODE_GUID, /* VF Infiniband node GUID */
IFLA_VF_IB_PORT_GUID, /* VF Infiniband port GUID */
IFLA_VF_VLAN_LIST, /* nested list of vlans, option for QinQ */
+ IFLA_VF_QUEUES, /* Min and Max TX/RX queues */
__IFLA_VF_MAX,
};
@@ -748,6 +749,14 @@ struct ifla_vf_trust {
__u32 setting;
};
+struct ifla_vf_queues {
+ __u32 vf;
+ __u32 min_tx_queues;
+ __u32 max_tx_queues;
+ __u32 min_rx_queues;
+ __u32 max_rx_queues;
+};
+
/* VF ports management section
*
* Nested layout of set/get msg is:
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 8080254..7cf3582 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -921,7 +921,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev,
nla_total_size_64bit(sizeof(__u64)) +
/* IFLA_VF_STATS_TX_DROPPED */
nla_total_size_64bit(sizeof(__u64)) +
- nla_total_size(sizeof(struct ifla_vf_trust)));
+ nla_total_size(sizeof(struct ifla_vf_trust)) +
+ nla_total_size(sizeof(struct ifla_vf_queues)));
return size;
} else
return 0;
@@ -1181,6 +1182,7 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
struct ifla_vf_vlan_info vf_vlan_info;
struct ifla_vf_spoofchk vf_spoofchk;
struct ifla_vf_tx_rate vf_tx_rate;
+ struct ifla_vf_queues vf_queues;
struct ifla_vf_stats vf_stats;
struct ifla_vf_trust vf_trust;
struct ifla_vf_vlan vf_vlan;
@@ -1217,7 +1219,8 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
vf_spoofchk.vf =
vf_linkstate.vf =
vf_rss_query_en.vf =
- vf_trust.vf = ivi.vf;
+ vf_trust.vf =
+ vf_queues.vf = ivi.vf;
memcpy(vf_mac.mac, ivi.mac, sizeof(ivi.mac));
vf_vlan.vlan = ivi.vlan;
@@ -1232,6 +1235,10 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
vf_linkstate.link_state = ivi.linkstate;
vf_rss_query_en.setting = ivi.rss_query_en;
vf_trust.setting = ivi.trusted;
+ vf_queues.min_tx_queues = ivi.min_tx_queues;
+ vf_queues.max_tx_queues = ivi.max_tx_queues;
+ vf_queues.min_rx_queues = ivi.min_rx_queues;
+ vf_queues.max_rx_queues = ivi.max_rx_queues;
vf = nla_nest_start(skb, IFLA_VF_INFO);
if (!vf)
goto nla_put_vfinfo_failure;
@@ -1249,7 +1256,9 @@ static noinline_for_stack int rtnl_fill_vfinfo(struct sk_buff *skb,
sizeof(vf_rss_query_en),
&vf_rss_query_en) ||
nla_put(skb, IFLA_VF_TRUST,
- sizeof(vf_trust), &vf_trust))
+ sizeof(vf_trust), &vf_trust) ||
+ nla_put(skb, IFLA_VF_QUEUES,
+ sizeof(vf_queues), &vf_queues))
goto nla_put_vf_failure;
vfvlanlist = nla_nest_start(skb, IFLA_VF_VLAN_LIST);
if (!vfvlanlist)
@@ -1706,6 +1715,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
[IFLA_VF_TRUST] = { .len = sizeof(struct ifla_vf_trust) },
[IFLA_VF_IB_NODE_GUID] = { .len = sizeof(struct ifla_vf_guid) },
[IFLA_VF_IB_PORT_GUID] = { .len = sizeof(struct ifla_vf_guid) },
+ [IFLA_VF_QUEUES] = { .len = sizeof(struct ifla_vf_queues) },
};
static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
@@ -2208,6 +2218,18 @@ static int do_setvfinfo(struct net_device *dev, struct nlattr **tb)
return handle_vf_guid(dev, ivt, IFLA_VF_IB_PORT_GUID);
}
+ if (tb[IFLA_VF_QUEUES]) {
+ struct ifla_vf_queues *ivq = nla_data(tb[IFLA_VF_QUEUES]);
+
+ err = -EOPNOTSUPP;
+ if (ops->ndo_set_vf_queues)
+ err = ops->ndo_set_vf_queues(dev, ivq->vf,
+ ivq->min_tx_queues, ivq->max_tx_queues,
+ ivq->min_rx_queues, ivq->max_rx_queues);
+ if (err < 0)
+ return err;
+ }
+
return err;
}
--
1.8.3.1
Powered by blists - more mailing lists