1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved. 4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com> 5 */ 6 7 #include "devl_internal.h" 8 9 static inline bool 10 devlink_rate_is_leaf(struct devlink_rate *devlink_rate) 11 { 12 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF; 13 } 14 15 bool devlink_rate_is_node(const struct devlink_rate *devlink_rate) 16 { 17 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE; 18 } 19 20 static struct devlink_rate * 21 devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info) 22 { 23 struct devlink_rate *devlink_rate; 24 struct devlink_port *devlink_port; 25 26 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs); 27 if (IS_ERR(devlink_port)) 28 return ERR_CAST(devlink_port); 29 devlink_rate = devlink_port->devlink_rate; 30 return devlink_rate ?: ERR_PTR(-ENODEV); 31 } 32 33 /* Repeatedly walks the nested devlink chain while cross device rate nodes are 34 * supported and finds the topmost instance where rates should be stored. 35 * That instance is locked, referenced and returned. 36 * When cross device rate nodes aren't supported the original devlink instance 37 * is returned. 38 */ 39 static struct devlink *devl_rate_lock(struct devlink *devlink) 40 { 41 struct devlink *rate_devlink = devlink, *parent; 42 43 devl_assert_locked(devlink); 44 45 while (rate_devlink->ops && 46 rate_devlink->ops->supported_cross_device_rate_nodes) { 47 parent = devlink_nested_in_get_lock(rate_devlink); 48 if (!parent) 49 break; 50 if (rate_devlink != devlink) { 51 /* Unlock intermediate instances. */ 52 devl_unlock(rate_devlink); 53 devlink_put(rate_devlink); 54 } 55 rate_devlink = parent; 56 } 57 return rate_devlink; 58 } 59 60 /* Unlocks and puts 'rate devlink' if different than 'devlink'. */ 61 static void devl_rate_unlock(struct devlink *devlink, 62 struct devlink *rate_devlink) 63 { 64 if (devlink == rate_devlink) 65 return; 66 67 devl_unlock(rate_devlink); 68 devlink_put(rate_devlink); 69 } 70 71 static struct devlink_rate * 72 devlink_rate_node_get_by_name(struct devlink *rate_devlink, 73 struct devlink *devlink, const char *node_name) 74 { 75 struct devlink_rate *devlink_rate; 76 77 list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) { 78 if (devlink_rate->devlink == devlink && 79 devlink_rate_is_node(devlink_rate) && 80 !strcmp(node_name, devlink_rate->name)) 81 return devlink_rate; 82 } 83 return ERR_PTR(-ENODEV); 84 } 85 86 static struct devlink_rate * 87 devlink_rate_node_get_from_attrs(struct devlink *rate_devlink, 88 struct devlink *devlink, struct nlattr **attrs) 89 { 90 const char *rate_node_name; 91 size_t len; 92 93 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME]) 94 return ERR_PTR(-EINVAL); 95 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]); 96 len = strlen(rate_node_name); 97 /* Name cannot be empty or decimal number */ 98 if (!len || strspn(rate_node_name, "0123456789") == len) 99 return ERR_PTR(-EINVAL); 100 101 return devlink_rate_node_get_by_name(rate_devlink, devlink, 102 rate_node_name); 103 } 104 105 static struct devlink_rate * 106 devlink_rate_node_get_from_info(struct devlink *rate_devlink, 107 struct devlink *devlink, 108 struct genl_info *info) 109 { 110 return devlink_rate_node_get_from_attrs(rate_devlink, devlink, 111 info->attrs); 112 } 113 114 static struct devlink_rate * 115 devlink_rate_get_from_info(struct devlink *rate_devlink, 116 struct devlink *devlink, struct genl_info *info) 117 { 118 struct nlattr **attrs = info->attrs; 119 120 if (attrs[DEVLINK_ATTR_PORT_INDEX]) 121 return devlink_rate_leaf_get_from_info(devlink, info); 122 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME]) 123 return devlink_rate_node_get_from_info(rate_devlink, devlink, 124 info); 125 else 126 return ERR_PTR(-EINVAL); 127 } 128 129 static int devlink_rate_put_tc_bws(struct sk_buff *msg, u32 *tc_bw) 130 { 131 struct nlattr *nla_tc_bw; 132 int i; 133 134 for (i = 0; i < DEVLINK_RATE_TCS_MAX; i++) { 135 nla_tc_bw = nla_nest_start(msg, DEVLINK_ATTR_RATE_TC_BWS); 136 if (!nla_tc_bw) 137 return -EMSGSIZE; 138 139 if (nla_put_u8(msg, DEVLINK_RATE_TC_ATTR_INDEX, i) || 140 nla_put_u32(msg, DEVLINK_RATE_TC_ATTR_BW, tc_bw[i])) 141 goto nla_put_failure; 142 143 nla_nest_end(msg, nla_tc_bw); 144 } 145 return 0; 146 147 nla_put_failure: 148 nla_nest_cancel(msg, nla_tc_bw); 149 return -EMSGSIZE; 150 } 151 152 static int devlink_nl_rate_parent_fill(struct sk_buff *msg, 153 struct devlink_rate *devlink_rate) 154 { 155 struct devlink_rate *parent = devlink_rate->parent; 156 struct devlink *devlink = parent->devlink; 157 158 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME, 159 parent->name)) 160 return -EMSGSIZE; 161 162 if (devlink != devlink_rate->devlink && 163 devlink_nl_put_nested_handle(msg, 164 devlink_net(devlink_rate->devlink), 165 devlink, DEVLINK_ATTR_PARENT_DEV)) 166 return -EMSGSIZE; 167 168 return 0; 169 } 170 171 static int devlink_nl_rate_fill(struct sk_buff *msg, 172 struct devlink_rate *devlink_rate, 173 enum devlink_command cmd, u32 portid, u32 seq, 174 int flags, struct netlink_ext_ack *extack) 175 { 176 struct devlink *devlink = devlink_rate->devlink; 177 void *hdr; 178 179 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 180 if (!hdr) 181 return -EMSGSIZE; 182 183 if (devlink_nl_put_handle(msg, devlink)) 184 goto nla_put_failure; 185 186 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type)) 187 goto nla_put_failure; 188 189 if (devlink_rate_is_leaf(devlink_rate)) { 190 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 191 devlink_rate->devlink_port->index)) 192 goto nla_put_failure; 193 } else if (devlink_rate_is_node(devlink_rate)) { 194 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME, 195 devlink_rate->name)) 196 goto nla_put_failure; 197 } 198 199 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_RATE_TX_SHARE, 200 devlink_rate->tx_share)) 201 goto nla_put_failure; 202 203 if (devlink_nl_put_u64(msg, DEVLINK_ATTR_RATE_TX_MAX, 204 devlink_rate->tx_max)) 205 goto nla_put_failure; 206 207 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY, 208 devlink_rate->tx_priority)) 209 goto nla_put_failure; 210 211 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT, 212 devlink_rate->tx_weight)) 213 goto nla_put_failure; 214 215 if (devlink_rate->parent && 216 devlink_nl_rate_parent_fill(msg, devlink_rate)) 217 goto nla_put_failure; 218 219 if (devlink_rate_put_tc_bws(msg, devlink_rate->tc_bw)) 220 goto nla_put_failure; 221 222 genlmsg_end(msg, hdr); 223 return 0; 224 225 nla_put_failure: 226 genlmsg_cancel(msg, hdr); 227 return -EMSGSIZE; 228 } 229 230 static void devlink_rate_notify(struct devlink_rate *devlink_rate, 231 enum devlink_command cmd) 232 { 233 struct devlink *devlink = devlink_rate->devlink; 234 struct sk_buff *msg; 235 int err; 236 237 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL); 238 239 if (!devl_is_registered(devlink) || !devlink_nl_notify_need(devlink)) 240 return; 241 242 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 243 if (!msg) 244 return; 245 246 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL); 247 if (err) { 248 nlmsg_free(msg); 249 return; 250 } 251 252 devlink_nl_notify_send(devlink, msg); 253 } 254 255 void devlink_rates_notify_register(struct devlink *devlink) 256 { 257 struct devlink_rate *rate_node; 258 struct devlink *rate_devlink; 259 260 rate_devlink = devl_rate_lock(devlink); 261 list_for_each_entry(rate_node, &rate_devlink->rate_list, list) 262 if (rate_node->devlink == devlink) 263 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); 264 devl_rate_unlock(devlink, rate_devlink); 265 } 266 267 void devlink_rates_notify_unregister(struct devlink *devlink) 268 { 269 struct devlink_rate *rate_node; 270 struct devlink *rate_devlink; 271 272 rate_devlink = devl_rate_lock(devlink); 273 list_for_each_entry_reverse(rate_node, &rate_devlink->rate_list, list) 274 if (rate_node->devlink == devlink) 275 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); 276 devl_rate_unlock(devlink, rate_devlink); 277 } 278 279 static int 280 devlink_nl_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink, 281 struct netlink_callback *cb, int flags) 282 { 283 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 284 struct devlink_rate *devlink_rate; 285 struct devlink *rate_devlink; 286 int idx = 0; 287 int err = 0; 288 289 rate_devlink = devl_rate_lock(devlink); 290 list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) { 291 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW; 292 u32 id = NETLINK_CB(cb->skb).portid; 293 294 if (idx < state->idx || devlink_rate->devlink != devlink) { 295 idx++; 296 continue; 297 } 298 299 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id, 300 cb->nlh->nlmsg_seq, flags, NULL); 301 if (err) { 302 state->idx = idx; 303 break; 304 } 305 idx++; 306 } 307 devl_rate_unlock(devlink, rate_devlink); 308 309 return err; 310 } 311 312 int devlink_nl_rate_get_dumpit(struct sk_buff *skb, struct netlink_callback *cb) 313 { 314 return devlink_nl_dumpit(skb, cb, devlink_nl_rate_get_dump_one); 315 } 316 317 int devlink_nl_rate_get_doit(struct sk_buff *skb, struct genl_info *info) 318 { 319 struct devlink *rate_devlink, *devlink = devlink_nl_ctx(info)->devlink; 320 struct devlink_rate *devlink_rate; 321 struct sk_buff *msg; 322 int err; 323 324 rate_devlink = devl_rate_lock(devlink); 325 devlink_rate = devlink_rate_get_from_info(rate_devlink, devlink, info); 326 if (IS_ERR(devlink_rate)) { 327 err = PTR_ERR(devlink_rate); 328 goto unlock; 329 } 330 331 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 332 if (!msg) { 333 err = -ENOMEM; 334 goto unlock; 335 } 336 337 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW, 338 info->snd_portid, info->snd_seq, 0, 339 info->extack); 340 if (err) 341 goto err_fill; 342 343 devl_rate_unlock(devlink, rate_devlink); 344 return genlmsg_reply(msg, info); 345 346 err_fill: 347 nlmsg_free(msg); 348 unlock: 349 devl_rate_unlock(devlink, rate_devlink); 350 return err; 351 } 352 353 static bool 354 devlink_rate_is_parent_node(struct devlink_rate *devlink_rate, 355 struct devlink_rate *parent) 356 { 357 while (parent) { 358 if (parent == devlink_rate) 359 return true; 360 parent = parent->parent; 361 } 362 return false; 363 } 364 365 static int 366 devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate, 367 struct devlink *rate_devlink, 368 struct genl_info *info, 369 struct nlattr *nla_parent) 370 { 371 struct devlink *devlink = devlink_rate->devlink, *parent_devlink; 372 const char *parent_name = nla_data(nla_parent); 373 const struct devlink_ops *ops = devlink->ops; 374 size_t len = strlen(parent_name); 375 struct devlink_rate *parent; 376 int err = -EOPNOTSUPP; 377 378 parent_devlink = devlink_nl_ctx(info)->parent_devlink ? : devlink; 379 parent = devlink_rate->parent; 380 381 if (parent && !len) { 382 if (devlink_rate_is_leaf(devlink_rate)) 383 err = ops->rate_leaf_parent_set(devlink_rate, NULL, 384 devlink_rate->priv, NULL, 385 info->extack); 386 else if (devlink_rate_is_node(devlink_rate)) 387 err = ops->rate_node_parent_set(devlink_rate, NULL, 388 devlink_rate->priv, NULL, 389 info->extack); 390 if (err) 391 return err; 392 393 refcount_dec(&parent->refcnt); 394 devlink_rate->parent = NULL; 395 } else if (len) { 396 /* parent_devlink (when different than devlink) isn't locked, 397 * but the rate node devlink instance is, so nobody from the 398 * same group of devices sharing rates could change the used 399 * fields or unregister the parent. 400 */ 401 parent = devlink_rate_node_get_by_name(rate_devlink, 402 parent_devlink, 403 parent_name); 404 if (IS_ERR(parent)) 405 return -ENODEV; 406 407 if (parent == devlink_rate) { 408 NL_SET_ERR_MSG(info->extack, "Parent to self is not allowed"); 409 return -EINVAL; 410 } 411 412 if (devlink_rate_is_node(devlink_rate) && 413 devlink_rate_is_parent_node(devlink_rate, parent->parent)) { 414 NL_SET_ERR_MSG(info->extack, "Node is already a parent of parent node."); 415 return -EEXIST; 416 } 417 418 if (devlink_rate_is_leaf(devlink_rate)) 419 err = ops->rate_leaf_parent_set(devlink_rate, parent, 420 devlink_rate->priv, parent->priv, 421 info->extack); 422 else if (devlink_rate_is_node(devlink_rate)) 423 err = ops->rate_node_parent_set(devlink_rate, parent, 424 devlink_rate->priv, parent->priv, 425 info->extack); 426 if (err) 427 return err; 428 429 if (devlink_rate->parent) 430 /* we're reassigning to other parent in this case */ 431 refcount_dec(&devlink_rate->parent->refcnt); 432 433 refcount_inc(&parent->refcnt); 434 devlink_rate->parent = parent; 435 } 436 437 return 0; 438 } 439 440 static int devlink_nl_rate_tc_bw_parse(struct nlattr *parent_nest, u32 *tc_bw, 441 unsigned long *bitmap, 442 struct netlink_ext_ack *extack) 443 { 444 struct nlattr *tb[DEVLINK_RATE_TC_ATTR_MAX + 1]; 445 u8 tc_index; 446 int err; 447 448 err = nla_parse_nested(tb, DEVLINK_RATE_TC_ATTR_MAX, parent_nest, 449 devlink_dl_rate_tc_bws_nl_policy, extack); 450 if (err) 451 return err; 452 453 if (!tb[DEVLINK_RATE_TC_ATTR_INDEX]) { 454 NL_SET_ERR_ATTR_MISS(extack, parent_nest, 455 DEVLINK_RATE_TC_ATTR_INDEX); 456 return -EINVAL; 457 } 458 459 tc_index = nla_get_u8(tb[DEVLINK_RATE_TC_ATTR_INDEX]); 460 461 if (!tb[DEVLINK_RATE_TC_ATTR_BW]) { 462 NL_SET_ERR_ATTR_MISS(extack, parent_nest, 463 DEVLINK_RATE_TC_ATTR_BW); 464 return -EINVAL; 465 } 466 467 if (test_and_set_bit(tc_index, bitmap)) { 468 NL_SET_ERR_MSG_FMT(extack, 469 "Duplicate traffic class index specified (%u)", 470 tc_index); 471 return -EINVAL; 472 } 473 474 tc_bw[tc_index] = nla_get_u32(tb[DEVLINK_RATE_TC_ATTR_BW]); 475 476 return 0; 477 } 478 479 static int devlink_nl_rate_tc_bw_set(struct devlink_rate *devlink_rate, 480 struct genl_info *info) 481 { 482 DECLARE_BITMAP(bitmap, DEVLINK_RATE_TCS_MAX) = {}; 483 struct devlink *devlink = devlink_rate->devlink; 484 const struct devlink_ops *ops = devlink->ops; 485 u32 tc_bw[DEVLINK_RATE_TCS_MAX] = {}; 486 int rem, err = -EOPNOTSUPP, i; 487 struct nlattr *attr; 488 489 nlmsg_for_each_attr_type(attr, DEVLINK_ATTR_RATE_TC_BWS, info->nlhdr, 490 GENL_HDRLEN, rem) { 491 err = devlink_nl_rate_tc_bw_parse(attr, tc_bw, bitmap, 492 info->extack); 493 if (err) 494 return err; 495 } 496 497 for (i = 0; i < DEVLINK_RATE_TCS_MAX; i++) { 498 if (!test_bit(i, bitmap)) { 499 NL_SET_ERR_MSG_FMT(info->extack, 500 "Bandwidth values must be specified for all %u traffic classes", 501 DEVLINK_RATE_TCS_MAX); 502 return -EINVAL; 503 } 504 } 505 506 if (devlink_rate_is_leaf(devlink_rate)) 507 err = ops->rate_leaf_tc_bw_set(devlink_rate, devlink_rate->priv, 508 tc_bw, info->extack); 509 else if (devlink_rate_is_node(devlink_rate)) 510 err = ops->rate_node_tc_bw_set(devlink_rate, devlink_rate->priv, 511 tc_bw, info->extack); 512 513 if (err) 514 return err; 515 516 memcpy(devlink_rate->tc_bw, tc_bw, sizeof(tc_bw)); 517 518 return 0; 519 } 520 521 static int devlink_nl_rate_set(struct devlink_rate *devlink_rate, 522 struct devlink *rate_devlink, 523 const struct devlink_ops *ops, 524 struct genl_info *info) 525 { 526 struct nlattr *nla_parent, **attrs = info->attrs; 527 int err = -EOPNOTSUPP; 528 u32 priority; 529 u32 weight; 530 u64 rate; 531 532 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) { 533 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]); 534 if (devlink_rate_is_leaf(devlink_rate)) 535 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv, 536 rate, info->extack); 537 else if (devlink_rate_is_node(devlink_rate)) 538 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv, 539 rate, info->extack); 540 if (err) 541 return err; 542 devlink_rate->tx_share = rate; 543 } 544 545 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) { 546 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]); 547 if (devlink_rate_is_leaf(devlink_rate)) 548 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv, 549 rate, info->extack); 550 else if (devlink_rate_is_node(devlink_rate)) 551 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv, 552 rate, info->extack); 553 if (err) 554 return err; 555 devlink_rate->tx_max = rate; 556 } 557 558 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) { 559 priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]); 560 if (devlink_rate_is_leaf(devlink_rate)) 561 err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv, 562 priority, info->extack); 563 else if (devlink_rate_is_node(devlink_rate)) 564 err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv, 565 priority, info->extack); 566 567 if (err) 568 return err; 569 devlink_rate->tx_priority = priority; 570 } 571 572 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) { 573 weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]); 574 if (devlink_rate_is_leaf(devlink_rate)) 575 err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv, 576 weight, info->extack); 577 else if (devlink_rate_is_node(devlink_rate)) 578 err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv, 579 weight, info->extack); 580 581 if (err) 582 return err; 583 devlink_rate->tx_weight = weight; 584 } 585 586 if (attrs[DEVLINK_ATTR_RATE_TC_BWS]) { 587 err = devlink_nl_rate_tc_bw_set(devlink_rate, info); 588 if (err) 589 return err; 590 } 591 592 /* Keep parent setting last because it takes a reference. This function 593 * has no rollback, so failing after taking the ref would leak it. 594 */ 595 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME]; 596 if (nla_parent) { 597 err = devlink_nl_rate_parent_node_set(devlink_rate, 598 rate_devlink, info, 599 nla_parent); 600 if (err) 601 return err; 602 } 603 604 return 0; 605 } 606 607 static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops, 608 struct genl_info *info, 609 enum devlink_rate_type type) 610 { 611 struct nlattr **attrs = info->attrs; 612 613 if (type == DEVLINK_RATE_TYPE_LEAF) { 614 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) { 615 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the leafs"); 616 return false; 617 } 618 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) { 619 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the leafs"); 620 return false; 621 } 622 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && 623 !ops->rate_leaf_parent_set) { 624 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the leafs"); 625 return false; 626 } 627 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) { 628 NL_SET_ERR_MSG_ATTR(info->extack, 629 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY], 630 "TX priority set isn't supported for the leafs"); 631 return false; 632 } 633 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) { 634 NL_SET_ERR_MSG_ATTR(info->extack, 635 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT], 636 "TX weight set isn't supported for the leafs"); 637 return false; 638 } 639 if (attrs[DEVLINK_ATTR_RATE_TC_BWS] && 640 !ops->rate_leaf_tc_bw_set) { 641 NL_SET_ERR_MSG_ATTR(info->extack, 642 attrs[DEVLINK_ATTR_RATE_TC_BWS], 643 "TC bandwidth set isn't supported for the leafs"); 644 return false; 645 } 646 } else if (type == DEVLINK_RATE_TYPE_NODE) { 647 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) { 648 NL_SET_ERR_MSG(info->extack, "TX share set isn't supported for the nodes"); 649 return false; 650 } 651 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) { 652 NL_SET_ERR_MSG(info->extack, "TX max set isn't supported for the nodes"); 653 return false; 654 } 655 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] && 656 !ops->rate_node_parent_set) { 657 NL_SET_ERR_MSG(info->extack, "Parent set isn't supported for the nodes"); 658 return false; 659 } 660 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_tx_priority_set) { 661 NL_SET_ERR_MSG_ATTR(info->extack, 662 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY], 663 "TX priority set isn't supported for the nodes"); 664 return false; 665 } 666 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_tx_weight_set) { 667 NL_SET_ERR_MSG_ATTR(info->extack, 668 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT], 669 "TX weight set isn't supported for the nodes"); 670 return false; 671 } 672 if (attrs[DEVLINK_ATTR_RATE_TC_BWS] && 673 !ops->rate_node_tc_bw_set) { 674 NL_SET_ERR_MSG_ATTR(info->extack, 675 attrs[DEVLINK_ATTR_RATE_TC_BWS], 676 "TC bandwidth set isn't supported for the nodes"); 677 return false; 678 } 679 } else { 680 WARN(1, "Unknown type of rate object"); 681 return false; 682 } 683 684 return true; 685 } 686 687 int devlink_nl_rate_set_doit(struct sk_buff *skb, struct genl_info *info) 688 { 689 struct devlink_nl_ctx *ctx = devlink_nl_ctx(info); 690 struct devlink *devlink = ctx->devlink; 691 struct devlink_rate *devlink_rate; 692 const struct devlink_ops *ops; 693 struct devlink *rate_devlink; 694 int err; 695 696 rate_devlink = devl_rate_lock(devlink); 697 devlink_rate = devlink_rate_get_from_info(rate_devlink, devlink, info); 698 if (IS_ERR(devlink_rate)) { 699 err = PTR_ERR(devlink_rate); 700 goto unlock; 701 } 702 703 ops = devlink->ops; 704 if (!ops || 705 !devlink_rate_set_ops_supported(ops, info, devlink_rate->type)) { 706 err = -EOPNOTSUPP; 707 goto unlock; 708 } 709 710 if (ctx->parent_devlink && ctx->parent_devlink != devlink && 711 !ops->supported_cross_device_rate_nodes) { 712 NL_SET_ERR_MSG(info->extack, 713 "Cross-device rate parents aren't supported"); 714 err = -EOPNOTSUPP; 715 goto unlock; 716 } 717 718 err = devlink_nl_rate_set(devlink_rate, rate_devlink, ops, info); 719 720 if (!err) 721 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); 722 unlock: 723 devl_rate_unlock(devlink, rate_devlink); 724 return err; 725 } 726 727 int devlink_nl_rate_new_doit(struct sk_buff *skb, struct genl_info *info) 728 { 729 struct devlink_nl_ctx *ctx = devlink_nl_ctx(info); 730 struct devlink *devlink = ctx->devlink; 731 struct devlink_rate *rate_node; 732 const struct devlink_ops *ops; 733 struct devlink *rate_devlink; 734 int err; 735 736 ops = devlink->ops; 737 if (!ops || !ops->rate_node_new || !ops->rate_node_del) { 738 NL_SET_ERR_MSG(info->extack, "Rate nodes aren't supported"); 739 return -EOPNOTSUPP; 740 } 741 742 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE)) 743 return -EOPNOTSUPP; 744 745 if (ctx->parent_devlink && ctx->parent_devlink != devlink && 746 !ops->supported_cross_device_rate_nodes) { 747 NL_SET_ERR_MSG(info->extack, 748 "Cross-device rate parents aren't supported"); 749 return -EOPNOTSUPP; 750 } 751 752 rate_devlink = devl_rate_lock(devlink); 753 rate_node = devlink_rate_node_get_from_attrs(rate_devlink, devlink, 754 info->attrs); 755 if (!IS_ERR(rate_node)) { 756 err = -EEXIST; 757 goto unlock; 758 } else if (rate_node == ERR_PTR(-EINVAL)) { 759 err = -EINVAL; 760 goto unlock; 761 } 762 763 rate_node = kzalloc_obj(*rate_node); 764 if (!rate_node) { 765 err = -ENOMEM; 766 goto unlock; 767 } 768 769 rate_node->devlink = devlink; 770 rate_node->type = DEVLINK_RATE_TYPE_NODE; 771 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL); 772 if (!rate_node->name) { 773 err = -ENOMEM; 774 goto err_strdup; 775 } 776 777 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack); 778 if (err) 779 goto err_node_new; 780 781 err = devlink_nl_rate_set(rate_node, rate_devlink, ops, info); 782 if (err) 783 goto err_rate_set; 784 785 refcount_set(&rate_node->refcnt, 1); 786 list_add(&rate_node->list, &rate_devlink->rate_list); 787 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); 788 devl_rate_unlock(devlink, rate_devlink); 789 return 0; 790 791 err_rate_set: 792 ops->rate_node_del(rate_node, rate_node->priv, info->extack); 793 err_node_new: 794 kfree(rate_node->name); 795 err_strdup: 796 kfree(rate_node); 797 unlock: 798 devl_rate_unlock(devlink, rate_devlink); 799 return err; 800 } 801 802 int devlink_nl_rate_del_doit(struct sk_buff *skb, struct genl_info *info) 803 { 804 struct devlink *rate_devlink, *devlink = devlink_nl_ctx(info)->devlink; 805 struct devlink_rate *rate_node; 806 int err; 807 808 rate_devlink = devl_rate_lock(devlink); 809 rate_node = devlink_rate_node_get_from_info(rate_devlink, devlink, 810 info); 811 if (IS_ERR(rate_node)) { 812 err = PTR_ERR(rate_node); 813 goto unlock; 814 } 815 816 if (refcount_read(&rate_node->refcnt) > 1) { 817 NL_SET_ERR_MSG(info->extack, "Node has children. Cannot delete node."); 818 err = -EBUSY; 819 goto unlock; 820 } 821 822 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL); 823 err = devlink->ops->rate_node_del(rate_node, rate_node->priv, 824 info->extack); 825 if (rate_node->parent) 826 refcount_dec(&rate_node->parent->refcnt); 827 list_del(&rate_node->list); 828 kfree(rate_node->name); 829 kfree(rate_node); 830 unlock: 831 devl_rate_unlock(devlink, rate_devlink); 832 return err; 833 } 834 835 int devlink_rates_check(struct devlink *devlink, 836 bool (*rate_filter)(const struct devlink_rate *), 837 struct netlink_ext_ack *extack) 838 { 839 struct devlink_rate *devlink_rate; 840 struct devlink *rate_devlink; 841 int err = 0; 842 843 rate_devlink = devl_rate_lock(devlink); 844 list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) 845 if (devlink_rate->devlink == devlink && 846 (!rate_filter || rate_filter(devlink_rate))) { 847 if (extack) 848 NL_SET_ERR_MSG(extack, "Rate node(s) exists."); 849 err = -EBUSY; 850 break; 851 } 852 devl_rate_unlock(devlink, rate_devlink); 853 return err; 854 } 855 856 /** 857 * devl_rate_node_create - create devlink rate node 858 * @devlink: devlink instance 859 * @priv: driver private data 860 * @node_name: name of the resulting node 861 * @parent: parent devlink_rate struct 862 * 863 * Create devlink rate object of type node 864 */ 865 struct devlink_rate * 866 devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name, 867 struct devlink_rate *parent) 868 { 869 struct devlink_rate *rate_node; 870 struct devlink *rate_devlink; 871 872 rate_devlink = devl_rate_lock(devlink); 873 rate_node = devlink_rate_node_get_by_name(rate_devlink, devlink, 874 node_name); 875 if (!IS_ERR(rate_node)) { 876 rate_node = ERR_PTR(-EEXIST); 877 goto unlock; 878 } 879 880 rate_node = kzalloc_obj(*rate_node); 881 if (!rate_node) { 882 rate_node = ERR_PTR(-ENOMEM); 883 goto unlock; 884 } 885 886 rate_node->type = DEVLINK_RATE_TYPE_NODE; 887 rate_node->devlink = devlink; 888 rate_node->priv = priv; 889 890 rate_node->name = kstrdup(node_name, GFP_KERNEL); 891 if (!rate_node->name) { 892 kfree(rate_node); 893 rate_node = ERR_PTR(-ENOMEM); 894 goto unlock; 895 } 896 897 if (parent) { 898 rate_node->parent = parent; 899 refcount_inc(&rate_node->parent->refcnt); 900 } 901 902 refcount_set(&rate_node->refcnt, 1); 903 list_add(&rate_node->list, &rate_devlink->rate_list); 904 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW); 905 unlock: 906 devl_rate_unlock(devlink, rate_devlink); 907 return rate_node; 908 } 909 EXPORT_SYMBOL_GPL(devl_rate_node_create); 910 911 /** 912 * devl_rate_leaf_create - create devlink rate leaf 913 * @devlink_port: devlink port object to create rate object on 914 * @priv: driver private data 915 * @parent: parent devlink_rate struct 916 * 917 * Create devlink rate object of type leaf on provided @devlink_port. 918 */ 919 int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv, 920 struct devlink_rate *parent) 921 { 922 struct devlink *rate_devlink, *devlink = devlink_port->devlink; 923 struct devlink_rate *devlink_rate; 924 925 devl_assert_locked(devlink); 926 927 if (WARN_ON(devlink_port->devlink_rate)) 928 return -EBUSY; 929 930 devlink_rate = kzalloc_obj(*devlink_rate); 931 if (!devlink_rate) 932 return -ENOMEM; 933 934 rate_devlink = devl_rate_lock(devlink); 935 if (parent) { 936 devlink_rate->parent = parent; 937 refcount_inc(&devlink_rate->parent->refcnt); 938 } 939 940 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF; 941 devlink_rate->devlink = devlink; 942 devlink_rate->devlink_port = devlink_port; 943 devlink_rate->priv = priv; 944 list_add_tail(&devlink_rate->list, &rate_devlink->rate_list); 945 devlink_port->devlink_rate = devlink_rate; 946 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW); 947 devl_rate_unlock(devlink, rate_devlink); 948 949 return 0; 950 } 951 EXPORT_SYMBOL_GPL(devl_rate_leaf_create); 952 953 /** 954 * devl_rate_leaf_destroy - destroy devlink rate leaf 955 * 956 * @devlink_port: devlink port linked to the rate object 957 * 958 * Destroy the devlink rate object of type leaf on provided @devlink_port. 959 */ 960 void devl_rate_leaf_destroy(struct devlink_port *devlink_port) 961 { 962 struct devlink_rate *devlink_rate = devlink_port->devlink_rate; 963 struct devlink *rate_devlink, *devlink = devlink_port->devlink; 964 965 devl_assert_locked(devlink); 966 if (!devlink_rate) 967 return; 968 969 rate_devlink = devl_rate_lock(devlink); 970 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL); 971 if (devlink_rate->parent) 972 refcount_dec(&devlink_rate->parent->refcnt); 973 list_del(&devlink_rate->list); 974 devlink_port->devlink_rate = NULL; 975 devl_rate_unlock(devlink, rate_devlink); 976 kfree(devlink_rate); 977 } 978 EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy); 979 980 /** 981 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device 982 * @devlink: devlink instance 983 * 984 * Unset parent for all rate objects involving this device and destroy all rate 985 * nodes on it. 986 */ 987 void devl_rate_nodes_destroy(struct devlink *devlink) 988 { 989 struct devlink_rate *devlink_rate, *tmp; 990 const struct devlink_ops *ops; 991 struct devlink *rate_devlink; 992 993 devl_assert_locked(devlink); 994 rate_devlink = devl_rate_lock(devlink); 995 996 list_for_each_entry(devlink_rate, &rate_devlink->rate_list, list) { 997 if (!devlink_rate->parent || 998 (devlink_rate->devlink != devlink && 999 devlink_rate->parent->devlink != devlink)) 1000 continue; 1001 1002 /* This could destroy rate objects on other devlinks in the 1003 * same hierarchy under 'rate_devlink'. This is safe because 1004 * the shared common ancestor is locked so there can be no 1005 * other concurrent rate operations on devlink_rate->devlink. 1006 */ 1007 ops = devlink_rate->devlink->ops; 1008 if (devlink_rate_is_leaf(devlink_rate)) 1009 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv, 1010 NULL, NULL); 1011 else if (devlink_rate_is_node(devlink_rate)) 1012 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv, 1013 NULL, NULL); 1014 1015 refcount_dec(&devlink_rate->parent->refcnt); 1016 devlink_rate->parent = NULL; 1017 } 1018 ops = devlink->ops; 1019 list_for_each_entry_safe(devlink_rate, tmp, &rate_devlink->rate_list, 1020 list) { 1021 if (devlink_rate->devlink == devlink && 1022 devlink_rate_is_node(devlink_rate)) { 1023 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL); 1024 list_del(&devlink_rate->list); 1025 kfree(devlink_rate->name); 1026 kfree(devlink_rate); 1027 } 1028 } 1029 devl_rate_unlock(devlink, rate_devlink); 1030 } 1031 EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy); 1032