Commit cd502236 authored by Michal Wilczynski's avatar Michal Wilczynski Committed by Jakub Kicinski

devlink: Introduce new attribute 'tx_priority' to devlink-rate

To fully utilize offload capabilities of Intel 100G card QoS capabilities
new attribute 'tx_priority' needs to be introduced. This attribute allows
for usage of strict priority arbiter among siblings. This arbitration
scheme attempts to schedule nodes based on their priority as long as the
nodes remain within their bandwidth limit.

Introduce new attribute in devlink-rate that will allow for configuration
of strict priority. New attribute is optional.
Signed-off-by: default avatarMichal Wilczynski <michal.wilczynski@intel.com>
Reviewed-by: default avatarJiri Pirko <jiri@nvidia.com>
Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 4ab45e97
...@@ -114,6 +114,8 @@ struct devlink_rate { ...@@ -114,6 +114,8 @@ struct devlink_rate {
refcount_t refcnt; refcount_t refcnt;
}; };
}; };
u32 tx_priority;
}; };
struct devlink_port { struct devlink_port {
...@@ -1511,10 +1513,14 @@ struct devlink_ops { ...@@ -1511,10 +1513,14 @@ struct devlink_ops {
u64 tx_share, struct netlink_ext_ack *extack); u64 tx_share, struct netlink_ext_ack *extack);
int (*rate_leaf_tx_max_set)(struct devlink_rate *devlink_rate, void *priv, int (*rate_leaf_tx_max_set)(struct devlink_rate *devlink_rate, void *priv,
u64 tx_max, struct netlink_ext_ack *extack); u64 tx_max, struct netlink_ext_ack *extack);
int (*rate_leaf_tx_priority_set)(struct devlink_rate *devlink_rate, void *priv,
u32 tx_priority, struct netlink_ext_ack *extack);
int (*rate_node_tx_share_set)(struct devlink_rate *devlink_rate, void *priv, int (*rate_node_tx_share_set)(struct devlink_rate *devlink_rate, void *priv,
u64 tx_share, struct netlink_ext_ack *extack); u64 tx_share, struct netlink_ext_ack *extack);
int (*rate_node_tx_max_set)(struct devlink_rate *devlink_rate, void *priv, int (*rate_node_tx_max_set)(struct devlink_rate *devlink_rate, void *priv,
u64 tx_max, struct netlink_ext_ack *extack); u64 tx_max, struct netlink_ext_ack *extack);
int (*rate_node_tx_priority_set)(struct devlink_rate *devlink_rate, void *priv,
u32 tx_priority, struct netlink_ext_ack *extack);
int (*rate_node_new)(struct devlink_rate *rate_node, void **priv, int (*rate_node_new)(struct devlink_rate *rate_node, void **priv,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
int (*rate_node_del)(struct devlink_rate *rate_node, void *priv, int (*rate_node_del)(struct devlink_rate *rate_node, void *priv,
......
...@@ -607,6 +607,7 @@ enum devlink_attr { ...@@ -607,6 +607,7 @@ enum devlink_attr {
DEVLINK_ATTR_SELFTESTS, /* nested */ DEVLINK_ATTR_SELFTESTS, /* nested */
DEVLINK_ATTR_RATE_TX_PRIORITY, /* u32 */
/* add new attributes above here, update the policy in devlink.c */ /* add new attributes above here, update the policy in devlink.c */
__DEVLINK_ATTR_MAX, __DEVLINK_ATTR_MAX,
......
...@@ -1203,6 +1203,9 @@ static int devlink_nl_rate_fill(struct sk_buff *msg, ...@@ -1203,6 +1203,9 @@ static int devlink_nl_rate_fill(struct sk_buff *msg,
devlink_rate->tx_max, DEVLINK_ATTR_PAD)) devlink_rate->tx_max, DEVLINK_ATTR_PAD))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
devlink_rate->tx_priority))
goto nla_put_failure;
if (devlink_rate->parent) if (devlink_rate->parent)
if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME, if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
devlink_rate->parent->name)) devlink_rate->parent->name))
...@@ -1936,6 +1939,7 @@ static int devlink_nl_rate_set(struct devlink_rate *devlink_rate, ...@@ -1936,6 +1939,7 @@ static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
{ {
struct nlattr *nla_parent, **attrs = info->attrs; struct nlattr *nla_parent, **attrs = info->attrs;
int err = -EOPNOTSUPP; int err = -EOPNOTSUPP;
u32 priority;
u64 rate; u64 rate;
if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) { if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
...@@ -1964,6 +1968,20 @@ static int devlink_nl_rate_set(struct devlink_rate *devlink_rate, ...@@ -1964,6 +1968,20 @@ static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
devlink_rate->tx_max = rate; devlink_rate->tx_max = rate;
} }
if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) {
priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]);
if (devlink_rate_is_leaf(devlink_rate))
err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv,
priority, info->extack);
else if (devlink_rate_is_node(devlink_rate))
err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv,
priority, info->extack);
if (err)
return err;
devlink_rate->tx_priority = priority;
}
nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME]; nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
if (nla_parent) { if (nla_parent) {
err = devlink_nl_rate_parent_node_set(devlink_rate, info, err = devlink_nl_rate_parent_node_set(devlink_rate, info,
...@@ -1995,6 +2013,12 @@ static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops, ...@@ -1995,6 +2013,12 @@ static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs"); NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs");
return false; return false;
} }
if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) {
NL_SET_ERR_MSG_ATTR(info->extack,
attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
"TX priority set isn't supported for the leafs");
return false;
}
} else if (type == DEVLINK_RATE_TYPE_NODE) { } else if (type == DEVLINK_RATE_TYPE_NODE) {
if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) { if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes"); NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes");
...@@ -2009,6 +2033,12 @@ static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops, ...@@ -2009,6 +2033,12 @@ static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes"); NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes");
return false; return false;
} }
if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) {
NL_SET_ERR_MSG_ATTR(info->extack,
attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
"TX priority set isn't supported for the nodes");
return false;
}
} else { } else {
WARN(1, "Unknown type of rate object"); WARN(1, "Unknown type of rate object");
return false; return false;
...@@ -9187,6 +9217,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = { ...@@ -9187,6 +9217,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
[DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 }, [DEVLINK_ATTR_LINECARD_INDEX] = { .type = NLA_U32 },
[DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING }, [DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING },
[DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED }, [DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED },
[DEVLINK_ATTR_RATE_TX_PRIORITY] = { .type = NLA_U32 },
}; };
static const struct genl_small_ops devlink_nl_ops[] = { static const struct genl_small_ops devlink_nl_ops[] = {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment