Lines Matching +full:set +full:- +full:rate +full:- +full:parent
1 // SPDX-License-Identifier: GPL-2.0-or-later
12 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF; in devlink_rate_is_leaf()
18 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE; in devlink_rate_is_node()
27 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs); in devlink_rate_leaf_get_from_info()
30 devlink_rate = devlink_port->devlink_rate; in devlink_rate_leaf_get_from_info()
31 return devlink_rate ?: ERR_PTR(-ENODEV); in devlink_rate_leaf_get_from_info()
39 list_for_each_entry(devlink_rate, &devlink->rate_list, list) { in devlink_rate_node_get_by_name()
41 !strcmp(node_name, devlink_rate->name)) in devlink_rate_node_get_by_name()
44 return ERR_PTR(-ENODEV); in devlink_rate_node_get_by_name()
54 return ERR_PTR(-EINVAL); in devlink_rate_node_get_from_attrs()
59 return ERR_PTR(-EINVAL); in devlink_rate_node_get_from_attrs()
67 return devlink_rate_node_get_from_attrs(devlink, info->attrs); in devlink_rate_node_get_from_info()
73 struct nlattr **attrs = info->attrs; in devlink_rate_get_from_info()
80 return ERR_PTR(-EINVAL); in devlink_rate_get_from_info()
91 return -EMSGSIZE; in devlink_rate_put_tc_bws()
103 return -EMSGSIZE; in devlink_rate_put_tc_bws()
111 struct devlink *devlink = devlink_rate->devlink; in devlink_nl_rate_fill()
116 return -EMSGSIZE; in devlink_nl_rate_fill()
121 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type)) in devlink_nl_rate_fill()
126 devlink_rate->devlink_port->index)) in devlink_nl_rate_fill()
130 devlink_rate->name)) in devlink_nl_rate_fill()
135 devlink_rate->tx_share)) in devlink_nl_rate_fill()
139 devlink_rate->tx_max)) in devlink_nl_rate_fill()
143 devlink_rate->tx_priority)) in devlink_nl_rate_fill()
147 devlink_rate->tx_weight)) in devlink_nl_rate_fill()
150 if (devlink_rate->parent) in devlink_nl_rate_fill()
152 devlink_rate->parent->name)) in devlink_nl_rate_fill()
155 if (devlink_rate_put_tc_bws(msg, devlink_rate->tc_bw)) in devlink_nl_rate_fill()
163 return -EMSGSIZE; in devlink_nl_rate_fill()
169 struct devlink *devlink = devlink_rate->devlink; in devlink_rate_notify()
195 list_for_each_entry(rate_node, &devlink->rate_list, list) in devlink_rates_notify_register()
203 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list) in devlink_rates_notify_unregister()
216 list_for_each_entry(devlink_rate, &devlink->rate_list, list) { in devlink_nl_rate_get_dump_one()
218 u32 id = NETLINK_CB(cb->skb).portid; in devlink_nl_rate_get_dump_one()
220 if (idx < state->idx) { in devlink_nl_rate_get_dump_one()
225 cb->nlh->nlmsg_seq, flags, NULL); in devlink_nl_rate_get_dump_one()
227 state->idx = idx; in devlink_nl_rate_get_dump_one()
243 struct devlink *devlink = info->user_ptr[0]; in devlink_nl_rate_get_doit()
254 return -ENOMEM; in devlink_nl_rate_get_doit()
257 info->snd_portid, info->snd_seq, 0, in devlink_nl_rate_get_doit()
258 info->extack); in devlink_nl_rate_get_doit()
269 struct devlink_rate *parent) in devlink_rate_is_parent_node() argument
271 while (parent) { in devlink_rate_is_parent_node()
272 if (parent == devlink_rate) in devlink_rate_is_parent_node()
274 parent = parent->parent; in devlink_rate_is_parent_node()
284 struct devlink *devlink = devlink_rate->devlink; in devlink_nl_rate_parent_node_set()
286 const struct devlink_ops *ops = devlink->ops; in devlink_nl_rate_parent_node_set()
288 struct devlink_rate *parent; in devlink_nl_rate_parent_node_set() local
289 int err = -EOPNOTSUPP; in devlink_nl_rate_parent_node_set()
291 parent = devlink_rate->parent; in devlink_nl_rate_parent_node_set()
293 if (parent && !len) { in devlink_nl_rate_parent_node_set()
295 err = ops->rate_leaf_parent_set(devlink_rate, NULL, in devlink_nl_rate_parent_node_set()
296 devlink_rate->priv, NULL, in devlink_nl_rate_parent_node_set()
297 info->extack); in devlink_nl_rate_parent_node_set()
299 err = ops->rate_node_parent_set(devlink_rate, NULL, in devlink_nl_rate_parent_node_set()
300 devlink_rate->priv, NULL, in devlink_nl_rate_parent_node_set()
301 info->extack); in devlink_nl_rate_parent_node_set()
305 refcount_dec(&parent->refcnt); in devlink_nl_rate_parent_node_set()
306 devlink_rate->parent = NULL; in devlink_nl_rate_parent_node_set()
308 parent = devlink_rate_node_get_by_name(devlink, parent_name); in devlink_nl_rate_parent_node_set()
309 if (IS_ERR(parent)) in devlink_nl_rate_parent_node_set()
310 return -ENODEV; in devlink_nl_rate_parent_node_set()
312 if (parent == devlink_rate) { in devlink_nl_rate_parent_node_set()
313 NL_SET_ERR_MSG(info->extack, "Parent to self is not allowed"); in devlink_nl_rate_parent_node_set()
314 return -EINVAL; in devlink_nl_rate_parent_node_set()
318 devlink_rate_is_parent_node(devlink_rate, parent->parent)) { in devlink_nl_rate_parent_node_set()
319 NL_SET_ERR_MSG(info->extack, "Node is already a parent of parent node."); in devlink_nl_rate_parent_node_set()
320 return -EEXIST; in devlink_nl_rate_parent_node_set()
324 err = ops->rate_leaf_parent_set(devlink_rate, parent, in devlink_nl_rate_parent_node_set()
325 devlink_rate->priv, parent->priv, in devlink_nl_rate_parent_node_set()
326 info->extack); in devlink_nl_rate_parent_node_set()
328 err = ops->rate_node_parent_set(devlink_rate, parent, in devlink_nl_rate_parent_node_set()
329 devlink_rate->priv, parent->priv, in devlink_nl_rate_parent_node_set()
330 info->extack); in devlink_nl_rate_parent_node_set()
334 if (devlink_rate->parent) in devlink_nl_rate_parent_node_set()
335 /* we're reassigning to other parent in this case */ in devlink_nl_rate_parent_node_set()
336 refcount_dec(&devlink_rate->parent->refcnt); in devlink_nl_rate_parent_node_set()
338 refcount_inc(&parent->refcnt); in devlink_nl_rate_parent_node_set()
339 devlink_rate->parent = parent; in devlink_nl_rate_parent_node_set()
361 return -EINVAL; in devlink_nl_rate_tc_bw_parse()
369 return -EINVAL; in devlink_nl_rate_tc_bw_parse()
376 return -EINVAL; in devlink_nl_rate_tc_bw_parse()
388 struct devlink *devlink = devlink_rate->devlink; in devlink_nl_rate_tc_bw_set()
389 const struct devlink_ops *ops = devlink->ops; in devlink_nl_rate_tc_bw_set()
391 int rem, err = -EOPNOTSUPP, i; in devlink_nl_rate_tc_bw_set()
394 nlmsg_for_each_attr_type(attr, DEVLINK_ATTR_RATE_TC_BWS, info->nlhdr, in devlink_nl_rate_tc_bw_set()
397 info->extack); in devlink_nl_rate_tc_bw_set()
404 NL_SET_ERR_MSG_FMT(info->extack, in devlink_nl_rate_tc_bw_set()
407 return -EINVAL; in devlink_nl_rate_tc_bw_set()
412 err = ops->rate_leaf_tc_bw_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_tc_bw_set()
413 tc_bw, info->extack); in devlink_nl_rate_tc_bw_set()
415 err = ops->rate_node_tc_bw_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_tc_bw_set()
416 tc_bw, info->extack); in devlink_nl_rate_tc_bw_set()
421 memcpy(devlink_rate->tc_bw, tc_bw, sizeof(tc_bw)); in devlink_nl_rate_tc_bw_set()
430 struct nlattr *nla_parent, **attrs = info->attrs; in devlink_nl_rate_set()
431 int err = -EOPNOTSUPP; in devlink_nl_rate_set()
434 u64 rate; in devlink_nl_rate_set() local
437 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]); in devlink_nl_rate_set()
439 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
440 rate, info->extack); in devlink_nl_rate_set()
442 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
443 rate, info->extack); in devlink_nl_rate_set()
446 devlink_rate->tx_share = rate; in devlink_nl_rate_set()
450 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]); in devlink_nl_rate_set()
452 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
453 rate, info->extack); in devlink_nl_rate_set()
455 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
456 rate, info->extack); in devlink_nl_rate_set()
459 devlink_rate->tx_max = rate; in devlink_nl_rate_set()
465 err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
466 priority, info->extack); in devlink_nl_rate_set()
468 err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
469 priority, info->extack); in devlink_nl_rate_set()
473 devlink_rate->tx_priority = priority; in devlink_nl_rate_set()
479 err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
480 weight, info->extack); in devlink_nl_rate_set()
482 err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv, in devlink_nl_rate_set()
483 weight, info->extack); in devlink_nl_rate_set()
487 devlink_rate->tx_weight = weight; in devlink_nl_rate_set()
511 struct nlattr **attrs = info->attrs; in devlink_rate_set_ops_supported()
514 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) { in devlink_rate_set_ops_supported()
515 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the leafs"); in devlink_rate_set_ops_supported()
518 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) { in devlink_rate_set_ops_supported()
519 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the leafs"); in devlink_rate_set_ops_supported()
523 !ops->rate_leaf_parent_set) { in devlink_rate_set_ops_supported()
524 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the leafs"); in devlink_rate_set_ops_supported()
527 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) { in devlink_rate_set_ops_supported()
528 NL_SET_ERR_MSG_ATTR(info->extack, in devlink_rate_set_ops_supported()
530 "TX priority set isn't supported for the leafs"); in devlink_rate_set_ops_supported()
533 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) { in devlink_rate_set_ops_supported()
534 NL_SET_ERR_MSG_ATTR(info->extack, in devlink_rate_set_ops_supported()
536 "TX weight set isn't supported for the leafs"); in devlink_rate_set_ops_supported()
540 !ops->rate_leaf_tc_bw_set) { in devlink_rate_set_ops_supported()
541 NL_SET_ERR_MSG_ATTR(info->extack, in devlink_rate_set_ops_supported()
543 "TC bandwidth set isn't supported for the leafs"); in devlink_rate_set_ops_supported()
547 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) { in devlink_rate_set_ops_supported()
548 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the nodes"); in devlink_rate_set_ops_supported()
551 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) { in devlink_rate_set_ops_supported()
552 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the nodes"); in devlink_rate_set_ops_supported()
556 !ops->rate_node_parent_set) { in devlink_rate_set_ops_supported()
557 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the nodes"); in devlink_rate_set_ops_supported()
560 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) { in devlink_rate_set_ops_supported()
561 NL_SET_ERR_MSG_ATTR(info->extack, in devlink_rate_set_ops_supported()
563 "TX priority set isn't supported for the nodes"); in devlink_rate_set_ops_supported()
566 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) { in devlink_rate_set_ops_supported()
567 NL_SET_ERR_MSG_ATTR(info->extack, in devlink_rate_set_ops_supported()
569 "TX weight set isn't supported for the nodes"); in devlink_rate_set_ops_supported()
573 !ops->rate_node_tc_bw_set) { in devlink_rate_set_ops_supported()
574 NL_SET_ERR_MSG_ATTR(info->extack, in devlink_rate_set_ops_supported()
576 "TC bandwidth set isn't supported for the nodes"); in devlink_rate_set_ops_supported()
580 WARN(1, "Unknown type of rate object"); in devlink_rate_set_ops_supported()
589 struct devlink *devlink = info->user_ptr[0]; in devlink_nl_rate_set_doit()
598 ops = devlink->ops; in devlink_nl_rate_set_doit()
599 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type)) in devlink_nl_rate_set_doit()
600 return -EOPNOTSUPP; in devlink_nl_rate_set_doit()
611 struct devlink *devlink = info->user_ptr[0]; in devlink_nl_rate_new_doit()
616 ops = devlink->ops; in devlink_nl_rate_new_doit()
617 if (!ops || !ops->rate_node_new || !ops->rate_node_del) { in devlink_nl_rate_new_doit()
618 NL_SET_ERR_MSG(info->extack, "Rate nodes aren't supported"); in devlink_nl_rate_new_doit()
619 return -EOPNOTSUPP; in devlink_nl_rate_new_doit()
623 return -EOPNOTSUPP; in devlink_nl_rate_new_doit()
625 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs); in devlink_nl_rate_new_doit()
627 return -EEXIST; in devlink_nl_rate_new_doit()
628 else if (rate_node == ERR_PTR(-EINVAL)) in devlink_nl_rate_new_doit()
629 return -EINVAL; in devlink_nl_rate_new_doit()
633 return -ENOMEM; in devlink_nl_rate_new_doit()
635 rate_node->devlink = devlink; in devlink_nl_rate_new_doit()
636 rate_node->type = DEVLINK_RATE_TYPE_NODE; in devlink_nl_rate_new_doit()
637 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL); in devlink_nl_rate_new_doit()
638 if (!rate_node->name) { in devlink_nl_rate_new_doit()
639 err = -ENOMEM; in devlink_nl_rate_new_doit()
643 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack); in devlink_nl_rate_new_doit()
651 refcount_set(&rate_node->refcnt, 1); in devlink_nl_rate_new_doit()
652 list_add(&rate_node->list, &devlink->rate_list); in devlink_nl_rate_new_doit()
657 ops->rate_node_del(rate_node, rate_node->priv, info->extack); in devlink_nl_rate_new_doit()
659 kfree(rate_node->name); in devlink_nl_rate_new_doit()
667 struct devlink *devlink = info->user_ptr[0]; in devlink_nl_rate_del_doit()
675 if (refcount_read(&rate_node->refcnt) > 1) { in devlink_nl_rate_del_doit()
676 NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node."); in devlink_nl_rate_del_doit()
677 return -EBUSY; in devlink_nl_rate_del_doit()
681 err = devlink->ops->rate_node_del(rate_node, rate_node->priv, in devlink_nl_rate_del_doit()
682 info->extack); in devlink_nl_rate_del_doit()
683 if (rate_node->parent) in devlink_nl_rate_del_doit()
684 refcount_dec(&rate_node->parent->refcnt); in devlink_nl_rate_del_doit()
685 list_del(&rate_node->list); in devlink_nl_rate_del_doit()
686 kfree(rate_node->name); in devlink_nl_rate_del_doit()
696 list_for_each_entry(devlink_rate, &devlink->rate_list, list) in devlink_rate_nodes_check()
698 NL_SET_ERR_MSG(extack, "Rate node(s) exists."); in devlink_rate_nodes_check()
699 return -EBUSY; in devlink_rate_nodes_check()
705 * devl_rate_node_create - create devlink rate node
709 * @parent: parent devlink_rate struct
711 * Create devlink rate object of type node
715 struct devlink_rate *parent) in devl_rate_node_create() argument
721 return ERR_PTR(-EEXIST); in devl_rate_node_create()
725 return ERR_PTR(-ENOMEM); in devl_rate_node_create()
727 if (parent) { in devl_rate_node_create()
728 rate_node->parent = parent; in devl_rate_node_create()
729 refcount_inc(&rate_node->parent->refcnt); in devl_rate_node_create()
732 rate_node->type = DEVLINK_RATE_TYPE_NODE; in devl_rate_node_create()
733 rate_node->devlink = devlink; in devl_rate_node_create()
734 rate_node->priv = priv; in devl_rate_node_create()
736 rate_node->name = kstrdup(node_name, GFP_KERNEL); in devl_rate_node_create()
737 if (!rate_node->name) { in devl_rate_node_create()
739 return ERR_PTR(-ENOMEM); in devl_rate_node_create()
742 refcount_set(&rate_node->refcnt, 1); in devl_rate_node_create()
743 list_add(&rate_node->list, &devlink->rate_list); in devl_rate_node_create()
750 * devl_rate_leaf_create - create devlink rate leaf
751 * @devlink_port: devlink port object to create rate object on
753 * @parent: parent devlink_rate struct
755 * Create devlink rate object of type leaf on provided @devlink_port.
758 struct devlink_rate *parent) in devl_rate_leaf_create() argument
760 struct devlink *devlink = devlink_port->devlink; in devl_rate_leaf_create()
763 devl_assert_locked(devlink_port->devlink); in devl_rate_leaf_create()
765 if (WARN_ON(devlink_port->devlink_rate)) in devl_rate_leaf_create()
766 return -EBUSY; in devl_rate_leaf_create()
770 return -ENOMEM; in devl_rate_leaf_create()
772 if (parent) { in devl_rate_leaf_create()
773 devlink_rate->parent = parent; in devl_rate_leaf_create()
774 refcount_inc(&devlink_rate->parent->refcnt); in devl_rate_leaf_create()
777 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF; in devl_rate_leaf_create()
778 devlink_rate->devlink = devlink; in devl_rate_leaf_create()
779 devlink_rate->devlink_port = devlink_port; in devl_rate_leaf_create()
780 devlink_rate->priv = priv; in devl_rate_leaf_create()
781 list_add_tail(&devlink_rate->list, &devlink->rate_list); in devl_rate_leaf_create()
782 devlink_port->devlink_rate = devlink_rate; in devl_rate_leaf_create()
790 * devl_rate_leaf_destroy - destroy devlink rate leaf
792 * @devlink_port: devlink port linked to the rate object
794 * Destroy the devlink rate object of type leaf on provided @devlink_port.
798 struct devlink_rate *devlink_rate = devlink_port->devlink_rate; in devl_rate_leaf_destroy()
800 devl_assert_locked(devlink_port->devlink); in devl_rate_leaf_destroy()
805 if (devlink_rate->parent) in devl_rate_leaf_destroy()
806 refcount_dec(&devlink_rate->parent->refcnt); in devl_rate_leaf_destroy()
807 list_del(&devlink_rate->list); in devl_rate_leaf_destroy()
808 devlink_port->devlink_rate = NULL; in devl_rate_leaf_destroy()
814 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
817 * Unset parent for all rate objects and destroy all rate nodes
822 const struct devlink_ops *ops = devlink->ops; in devl_rate_nodes_destroy()
827 list_for_each_entry(devlink_rate, &devlink->rate_list, list) { in devl_rate_nodes_destroy()
828 if (!devlink_rate->parent) in devl_rate_nodes_destroy()
831 refcount_dec(&devlink_rate->parent->refcnt); in devl_rate_nodes_destroy()
833 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv, in devl_rate_nodes_destroy()
836 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv, in devl_rate_nodes_destroy()
839 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) { in devl_rate_nodes_destroy()
841 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL); in devl_rate_nodes_destroy()
842 list_del(&devlink_rate->list); in devl_rate_nodes_destroy()
843 kfree(devlink_rate->name); in devl_rate_nodes_destroy()