devlink: Introduce new attribute 'tx_weight' to devlink-rate
authorMichal Wilczynski <michal.wilczynski@intel.com>
Tue, 15 Nov 2022 10:48:16 +0000 (11:48 +0100)
committerJakub Kicinski <kuba@kernel.org>
Fri, 18 Nov 2022 05:41:26 +0000 (21:41 -0800)
To fully utilize offload capabilities of Intel 100G card QoS capabilities
new attribute 'tx_weight' needs to be introduced. This attribute allows
for usage of Weighted Fair Queuing arbitration scheme among siblings.
This arbitration scheme can be used simultaneously with the strict
priority.

Introduce new attribute in devlink-rate that will allow for configuration
of Weighted Fair Queueing. New attribute is optional.

Signed-off-by: Michal Wilczynski <michal.wilczynski@intel.com>
Reviewed-by: Jiri Pirko <jiri@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
include/net/devlink.h
include/uapi/linux/devlink.h
net/core/devlink.c

index 90d59d673cb14806acc504dce3ac4c36e9fbecc5..366b23d3f973eb64aa7f2776a5ee4f65272f6d50 100644 (file)
@@ -116,6 +116,7 @@ struct devlink_rate {
        };
 
        u32 tx_priority;
+       u32 tx_weight;
 };
 
 struct devlink_port {
@@ -1515,12 +1516,16 @@ struct devlink_ops {
                                    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_leaf_tx_weight_set)(struct devlink_rate *devlink_rate, void *priv,
+                                      u32 tx_weight, struct netlink_ext_ack *extack);
        int (*rate_node_tx_share_set)(struct devlink_rate *devlink_rate, void *priv,
                                      u64 tx_share, struct netlink_ext_ack *extack);
        int (*rate_node_tx_max_set)(struct devlink_rate *devlink_rate, void *priv,
                                    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_tx_weight_set)(struct devlink_rate *devlink_rate, void *priv,
+                                      u32 tx_weight, struct netlink_ext_ack *extack);
        int (*rate_node_new)(struct devlink_rate *rate_node, void **priv,
                             struct netlink_ext_ack *extack);
        int (*rate_node_del)(struct devlink_rate *rate_node, void *priv,
index 1a9214d35ef52bbebee4ba4608a8fa9f6efc9d00..498d0d5d0957735aef2e260b6103ff63608f2f77 100644 (file)
@@ -608,6 +608,8 @@ enum devlink_attr {
        DEVLINK_ATTR_SELFTESTS,                 /* nested */
 
        DEVLINK_ATTR_RATE_TX_PRIORITY,          /* u32 */
+       DEVLINK_ATTR_RATE_TX_WEIGHT,            /* u32 */
+
        /* add new attributes above here, update the policy in devlink.c */
 
        __DEVLINK_ATTR_MAX,
index bf6d3a3c28bbf4b7eebc12db942a5eb6acc3f191..525bdf42616374c1c534bd504bc99fe11b5f7776 100644 (file)
@@ -1206,6 +1206,11 @@ static int devlink_nl_rate_fill(struct sk_buff *msg,
        if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
                        devlink_rate->tx_priority))
                goto nla_put_failure;
+
+       if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
+                       devlink_rate->tx_weight))
+               goto nla_put_failure;
+
        if (devlink_rate->parent)
                if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
                                   devlink_rate->parent->name))
@@ -1940,6 +1945,7 @@ static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
        struct nlattr *nla_parent, **attrs = info->attrs;
        int err = -EOPNOTSUPP;
        u32 priority;
+       u32 weight;
        u64 rate;
 
        if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
@@ -1982,6 +1988,20 @@ static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
                devlink_rate->tx_priority = priority;
        }
 
+       if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) {
+               weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]);
+               if (devlink_rate_is_leaf(devlink_rate))
+                       err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv,
+                                                          weight, info->extack);
+               else if (devlink_rate_is_node(devlink_rate))
+                       err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv,
+                                                          weight, info->extack);
+
+               if (err)
+                       return err;
+               devlink_rate->tx_weight = weight;
+       }
+
        nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
        if (nla_parent) {
                err = devlink_nl_rate_parent_node_set(devlink_rate, info,
@@ -2019,6 +2039,12 @@ static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
                                            "TX priority set isn't supported for the leafs");
                        return false;
                }
+               if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) {
+                       NL_SET_ERR_MSG_ATTR(info->extack,
+                                           attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
+                                           "TX weight set isn't supported for the leafs");
+                       return false;
+               }
        } else if (type == DEVLINK_RATE_TYPE_NODE) {
                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");
@@ -2039,6 +2065,12 @@ static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
                                            "TX priority set isn't supported for the nodes");
                        return false;
                }
+               if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) {
+                       NL_SET_ERR_MSG_ATTR(info->extack,
+                                           attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
+                                           "TX weight set isn't supported for the nodes");
+                       return false;
+               }
        } else {
                WARN(1, "Unknown type of rate object");
                return false;
@@ -9218,6 +9250,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
        [DEVLINK_ATTR_LINECARD_TYPE] = { .type = NLA_NUL_STRING },
        [DEVLINK_ATTR_SELFTESTS] = { .type = NLA_NESTED },
        [DEVLINK_ATTR_RATE_TX_PRIORITY] = { .type = NLA_U32 },
+       [DEVLINK_ATTR_RATE_TX_WEIGHT] = { .type = NLA_U32 },
 };
 
 static const struct genl_small_ops devlink_nl_ops[] = {