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 struct devlink_region { 10 struct devlink *devlink; 11 struct devlink_port *port; 12 struct list_head list; 13 union { 14 const struct devlink_region_ops *ops; 15 const struct devlink_port_region_ops *port_ops; 16 }; 17 struct mutex snapshot_lock; /* protects snapshot_list, 18 * max_snapshots and cur_snapshots 19 * consistency. 20 */ 21 struct list_head snapshot_list; 22 u32 max_snapshots; 23 u32 cur_snapshots; 24 u64 size; 25 }; 26 27 struct devlink_snapshot { 28 struct list_head list; 29 struct devlink_region *region; 30 u8 *data; 31 u32 id; 32 }; 33 34 static struct devlink_region * 35 devlink_region_get_by_name(struct devlink *devlink, const char *region_name) 36 { 37 struct devlink_region *region; 38 39 list_for_each_entry(region, &devlink->region_list, list) 40 if (!strcmp(region->ops->name, region_name)) 41 return region; 42 43 return NULL; 44 } 45 46 static struct devlink_region * 47 devlink_port_region_get_by_name(struct devlink_port *port, 48 const char *region_name) 49 { 50 struct devlink_region *region; 51 52 list_for_each_entry(region, &port->region_list, list) 53 if (!strcmp(region->ops->name, region_name)) 54 return region; 55 56 return NULL; 57 } 58 59 static struct devlink_snapshot * 60 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id) 61 { 62 struct devlink_snapshot *snapshot; 63 64 list_for_each_entry(snapshot, ®ion->snapshot_list, list) 65 if (snapshot->id == id) 66 return snapshot; 67 68 return NULL; 69 } 70 71 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg, 72 struct devlink *devlink, 73 struct devlink_snapshot *snapshot) 74 { 75 struct nlattr *snap_attr; 76 int err; 77 78 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT); 79 if (!snap_attr) 80 return -EINVAL; 81 82 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id); 83 if (err) 84 goto nla_put_failure; 85 86 nla_nest_end(msg, snap_attr); 87 return 0; 88 89 nla_put_failure: 90 nla_nest_cancel(msg, snap_attr); 91 return err; 92 } 93 94 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg, 95 struct devlink *devlink, 96 struct devlink_region *region) 97 { 98 struct devlink_snapshot *snapshot; 99 struct nlattr *snapshots_attr; 100 int err; 101 102 snapshots_attr = nla_nest_start_noflag(msg, 103 DEVLINK_ATTR_REGION_SNAPSHOTS); 104 if (!snapshots_attr) 105 return -EINVAL; 106 107 list_for_each_entry(snapshot, ®ion->snapshot_list, list) { 108 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot); 109 if (err) 110 goto nla_put_failure; 111 } 112 113 nla_nest_end(msg, snapshots_attr); 114 return 0; 115 116 nla_put_failure: 117 nla_nest_cancel(msg, snapshots_attr); 118 return err; 119 } 120 121 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink, 122 enum devlink_command cmd, u32 portid, 123 u32 seq, int flags, 124 struct devlink_region *region) 125 { 126 void *hdr; 127 int err; 128 129 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd); 130 if (!hdr) 131 return -EMSGSIZE; 132 133 err = devlink_nl_put_handle(msg, devlink); 134 if (err) 135 goto nla_put_failure; 136 137 if (region->port) { 138 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 139 region->port->index); 140 if (err) 141 goto nla_put_failure; 142 } 143 144 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); 145 if (err) 146 goto nla_put_failure; 147 148 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 149 region->size, 150 DEVLINK_ATTR_PAD); 151 if (err) 152 goto nla_put_failure; 153 154 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS, 155 region->max_snapshots); 156 if (err) 157 goto nla_put_failure; 158 159 err = devlink_nl_region_snapshots_id_put(msg, devlink, region); 160 if (err) 161 goto nla_put_failure; 162 163 genlmsg_end(msg, hdr); 164 return 0; 165 166 nla_put_failure: 167 genlmsg_cancel(msg, hdr); 168 return err; 169 } 170 171 static struct sk_buff * 172 devlink_nl_region_notify_build(struct devlink_region *region, 173 struct devlink_snapshot *snapshot, 174 enum devlink_command cmd, u32 portid, u32 seq) 175 { 176 struct devlink *devlink = region->devlink; 177 struct sk_buff *msg; 178 void *hdr; 179 int err; 180 181 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 182 if (!msg) 183 return ERR_PTR(-ENOMEM); 184 185 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd); 186 if (!hdr) { 187 err = -EMSGSIZE; 188 goto out_free_msg; 189 } 190 191 err = devlink_nl_put_handle(msg, devlink); 192 if (err) 193 goto out_cancel_msg; 194 195 if (region->port) { 196 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, 197 region->port->index); 198 if (err) 199 goto out_cancel_msg; 200 } 201 202 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, 203 region->ops->name); 204 if (err) 205 goto out_cancel_msg; 206 207 if (snapshot) { 208 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, 209 snapshot->id); 210 if (err) 211 goto out_cancel_msg; 212 } else { 213 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE, 214 region->size, DEVLINK_ATTR_PAD); 215 if (err) 216 goto out_cancel_msg; 217 } 218 genlmsg_end(msg, hdr); 219 220 return msg; 221 222 out_cancel_msg: 223 genlmsg_cancel(msg, hdr); 224 out_free_msg: 225 nlmsg_free(msg); 226 return ERR_PTR(err); 227 } 228 229 static void devlink_nl_region_notify(struct devlink_region *region, 230 struct devlink_snapshot *snapshot, 231 enum devlink_command cmd) 232 { 233 struct devlink *devlink = region->devlink; 234 struct sk_buff *msg; 235 236 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL); 237 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED)) 238 return; 239 240 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); 241 if (IS_ERR(msg)) 242 return; 243 244 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg, 245 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL); 246 } 247 248 void devlink_regions_notify_register(struct devlink *devlink) 249 { 250 struct devlink_region *region; 251 252 list_for_each_entry(region, &devlink->region_list, list) 253 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 254 } 255 256 void devlink_regions_notify_unregister(struct devlink *devlink) 257 { 258 struct devlink_region *region; 259 260 list_for_each_entry_reverse(region, &devlink->region_list, list) 261 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 262 } 263 264 /** 265 * __devlink_snapshot_id_increment - Increment number of snapshots using an id 266 * @devlink: devlink instance 267 * @id: the snapshot id 268 * 269 * Track when a new snapshot begins using an id. Load the count for the 270 * given id from the snapshot xarray, increment it, and store it back. 271 * 272 * Called when a new snapshot is created with the given id. 273 * 274 * The id *must* have been previously allocated by 275 * devlink_region_snapshot_id_get(). 276 * 277 * Returns 0 on success, or an error on failure. 278 */ 279 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) 280 { 281 unsigned long count; 282 void *p; 283 int err; 284 285 xa_lock(&devlink->snapshot_ids); 286 p = xa_load(&devlink->snapshot_ids, id); 287 if (WARN_ON(!p)) { 288 err = -EINVAL; 289 goto unlock; 290 } 291 292 if (WARN_ON(!xa_is_value(p))) { 293 err = -EINVAL; 294 goto unlock; 295 } 296 297 count = xa_to_value(p); 298 count++; 299 300 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 301 GFP_ATOMIC)); 302 unlock: 303 xa_unlock(&devlink->snapshot_ids); 304 return err; 305 } 306 307 /** 308 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id 309 * @devlink: devlink instance 310 * @id: the snapshot id 311 * 312 * Track when a snapshot is deleted and stops using an id. Load the count 313 * for the given id from the snapshot xarray, decrement it, and store it 314 * back. 315 * 316 * If the count reaches zero, erase this id from the xarray, freeing it 317 * up for future re-use by devlink_region_snapshot_id_get(). 318 * 319 * Called when a snapshot using the given id is deleted, and when the 320 * initial allocator of the id is finished using it. 321 */ 322 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id) 323 { 324 unsigned long count; 325 void *p; 326 327 xa_lock(&devlink->snapshot_ids); 328 p = xa_load(&devlink->snapshot_ids, id); 329 if (WARN_ON(!p)) 330 goto unlock; 331 332 if (WARN_ON(!xa_is_value(p))) 333 goto unlock; 334 335 count = xa_to_value(p); 336 337 if (count > 1) { 338 count--; 339 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), 340 GFP_ATOMIC); 341 } else { 342 /* If this was the last user, we can erase this id */ 343 __xa_erase(&devlink->snapshot_ids, id); 344 } 345 unlock: 346 xa_unlock(&devlink->snapshot_ids); 347 } 348 349 /** 350 * __devlink_snapshot_id_insert - Insert a specific snapshot ID 351 * @devlink: devlink instance 352 * @id: the snapshot id 353 * 354 * Mark the given snapshot id as used by inserting a zero value into the 355 * snapshot xarray. 356 * 357 * This must be called while holding the devlink instance lock. Unlike 358 * devlink_snapshot_id_get, the initial reference count is zero, not one. 359 * It is expected that the id will immediately be used before 360 * releasing the devlink instance lock. 361 * 362 * Returns zero on success, or an error code if the snapshot id could not 363 * be inserted. 364 */ 365 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id) 366 { 367 int err; 368 369 xa_lock(&devlink->snapshot_ids); 370 if (xa_load(&devlink->snapshot_ids, id)) { 371 xa_unlock(&devlink->snapshot_ids); 372 return -EEXIST; 373 } 374 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), 375 GFP_ATOMIC)); 376 xa_unlock(&devlink->snapshot_ids); 377 return err; 378 } 379 380 /** 381 * __devlink_region_snapshot_id_get - get snapshot ID 382 * @devlink: devlink instance 383 * @id: storage to return snapshot id 384 * 385 * Allocates a new snapshot id. Returns zero on success, or a negative 386 * error on failure. Must be called while holding the devlink instance 387 * lock. 388 * 389 * Snapshot IDs are tracked using an xarray which stores the number of 390 * users of the snapshot id. 391 * 392 * Note that the caller of this function counts as a 'user', in order to 393 * avoid race conditions. The caller must release its hold on the 394 * snapshot by using devlink_region_snapshot_id_put. 395 */ 396 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 397 { 398 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), 399 xa_limit_32b, GFP_KERNEL); 400 } 401 402 /** 403 * __devlink_region_snapshot_create - create a new snapshot 404 * This will add a new snapshot of a region. The snapshot 405 * will be stored on the region struct and can be accessed 406 * from devlink. This is useful for future analyses of snapshots. 407 * Multiple snapshots can be created on a region. 408 * The @snapshot_id should be obtained using the getter function. 409 * 410 * Must be called only while holding the region snapshot lock. 411 * 412 * @region: devlink region of the snapshot 413 * @data: snapshot data 414 * @snapshot_id: snapshot id to be created 415 */ 416 static int 417 __devlink_region_snapshot_create(struct devlink_region *region, 418 u8 *data, u32 snapshot_id) 419 { 420 struct devlink *devlink = region->devlink; 421 struct devlink_snapshot *snapshot; 422 int err; 423 424 lockdep_assert_held(®ion->snapshot_lock); 425 426 /* check if region can hold one more snapshot */ 427 if (region->cur_snapshots == region->max_snapshots) 428 return -ENOSPC; 429 430 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) 431 return -EEXIST; 432 433 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL); 434 if (!snapshot) 435 return -ENOMEM; 436 437 err = __devlink_snapshot_id_increment(devlink, snapshot_id); 438 if (err) 439 goto err_snapshot_id_increment; 440 441 snapshot->id = snapshot_id; 442 snapshot->region = region; 443 snapshot->data = data; 444 445 list_add_tail(&snapshot->list, ®ion->snapshot_list); 446 447 region->cur_snapshots++; 448 449 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW); 450 return 0; 451 452 err_snapshot_id_increment: 453 kfree(snapshot); 454 return err; 455 } 456 457 static void devlink_region_snapshot_del(struct devlink_region *region, 458 struct devlink_snapshot *snapshot) 459 { 460 struct devlink *devlink = region->devlink; 461 462 lockdep_assert_held(®ion->snapshot_lock); 463 464 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL); 465 region->cur_snapshots--; 466 list_del(&snapshot->list); 467 region->ops->destructor(snapshot->data); 468 __devlink_snapshot_id_decrement(devlink, snapshot->id); 469 kfree(snapshot); 470 } 471 472 int devlink_nl_region_get_doit(struct sk_buff *skb, struct genl_info *info) 473 { 474 struct devlink *devlink = info->user_ptr[0]; 475 struct devlink_port *port = NULL; 476 struct devlink_region *region; 477 const char *region_name; 478 struct sk_buff *msg; 479 unsigned int index; 480 int err; 481 482 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) 483 return -EINVAL; 484 485 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 486 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 487 488 port = devlink_port_get_by_index(devlink, index); 489 if (!port) 490 return -ENODEV; 491 } 492 493 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 494 if (port) 495 region = devlink_port_region_get_by_name(port, region_name); 496 else 497 region = devlink_region_get_by_name(devlink, region_name); 498 499 if (!region) 500 return -EINVAL; 501 502 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 503 if (!msg) 504 return -ENOMEM; 505 506 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET, 507 info->snd_portid, info->snd_seq, 0, 508 region); 509 if (err) { 510 nlmsg_free(msg); 511 return err; 512 } 513 514 return genlmsg_reply(msg, info); 515 } 516 517 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg, 518 struct netlink_callback *cb, 519 struct devlink_port *port, 520 int *idx, int start, int flags) 521 { 522 struct devlink_region *region; 523 int err = 0; 524 525 list_for_each_entry(region, &port->region_list, list) { 526 if (*idx < start) { 527 (*idx)++; 528 continue; 529 } 530 err = devlink_nl_region_fill(msg, port->devlink, 531 DEVLINK_CMD_REGION_GET, 532 NETLINK_CB(cb->skb).portid, 533 cb->nlh->nlmsg_seq, 534 flags, region); 535 if (err) 536 goto out; 537 (*idx)++; 538 } 539 540 out: 541 return err; 542 } 543 544 static int devlink_nl_region_get_dump_one(struct sk_buff *msg, 545 struct devlink *devlink, 546 struct netlink_callback *cb, 547 int flags) 548 { 549 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 550 struct devlink_region *region; 551 struct devlink_port *port; 552 unsigned long port_index; 553 int idx = 0; 554 int err; 555 556 list_for_each_entry(region, &devlink->region_list, list) { 557 if (idx < state->idx) { 558 idx++; 559 continue; 560 } 561 err = devlink_nl_region_fill(msg, devlink, 562 DEVLINK_CMD_REGION_GET, 563 NETLINK_CB(cb->skb).portid, 564 cb->nlh->nlmsg_seq, flags, 565 region); 566 if (err) { 567 state->idx = idx; 568 return err; 569 } 570 idx++; 571 } 572 573 xa_for_each(&devlink->ports, port_index, port) { 574 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx, 575 state->idx, flags); 576 if (err) { 577 state->idx = idx; 578 return err; 579 } 580 } 581 582 return 0; 583 } 584 585 int devlink_nl_region_get_dumpit(struct sk_buff *skb, 586 struct netlink_callback *cb) 587 { 588 return devlink_nl_dumpit(skb, cb, devlink_nl_region_get_dump_one); 589 } 590 591 int devlink_nl_cmd_region_del(struct sk_buff *skb, struct genl_info *info) 592 { 593 struct devlink *devlink = info->user_ptr[0]; 594 struct devlink_snapshot *snapshot; 595 struct devlink_port *port = NULL; 596 struct devlink_region *region; 597 const char *region_name; 598 unsigned int index; 599 u32 snapshot_id; 600 601 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) || 602 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID)) 603 return -EINVAL; 604 605 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 606 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); 607 608 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 609 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 610 611 port = devlink_port_get_by_index(devlink, index); 612 if (!port) 613 return -ENODEV; 614 } 615 616 if (port) 617 region = devlink_port_region_get_by_name(port, region_name); 618 else 619 region = devlink_region_get_by_name(devlink, region_name); 620 621 if (!region) 622 return -EINVAL; 623 624 mutex_lock(®ion->snapshot_lock); 625 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 626 if (!snapshot) { 627 mutex_unlock(®ion->snapshot_lock); 628 return -EINVAL; 629 } 630 631 devlink_region_snapshot_del(region, snapshot); 632 mutex_unlock(®ion->snapshot_lock); 633 return 0; 634 } 635 636 int devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info) 637 { 638 struct devlink *devlink = info->user_ptr[0]; 639 struct devlink_snapshot *snapshot; 640 struct devlink_port *port = NULL; 641 struct nlattr *snapshot_id_attr; 642 struct devlink_region *region; 643 const char *region_name; 644 unsigned int index; 645 u32 snapshot_id; 646 u8 *data; 647 int err; 648 649 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) { 650 NL_SET_ERR_MSG(info->extack, "No region name provided"); 651 return -EINVAL; 652 } 653 654 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); 655 656 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { 657 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); 658 659 port = devlink_port_get_by_index(devlink, index); 660 if (!port) 661 return -ENODEV; 662 } 663 664 if (port) 665 region = devlink_port_region_get_by_name(port, region_name); 666 else 667 region = devlink_region_get_by_name(devlink, region_name); 668 669 if (!region) { 670 NL_SET_ERR_MSG(info->extack, "The requested region does not exist"); 671 return -EINVAL; 672 } 673 674 if (!region->ops->snapshot) { 675 NL_SET_ERR_MSG(info->extack, "The requested region does not support taking an immediate snapshot"); 676 return -EOPNOTSUPP; 677 } 678 679 mutex_lock(®ion->snapshot_lock); 680 681 if (region->cur_snapshots == region->max_snapshots) { 682 NL_SET_ERR_MSG(info->extack, "The region has reached the maximum number of stored snapshots"); 683 err = -ENOSPC; 684 goto unlock; 685 } 686 687 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 688 if (snapshot_id_attr) { 689 snapshot_id = nla_get_u32(snapshot_id_attr); 690 691 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) { 692 NL_SET_ERR_MSG(info->extack, "The requested snapshot id is already in use"); 693 err = -EEXIST; 694 goto unlock; 695 } 696 697 err = __devlink_snapshot_id_insert(devlink, snapshot_id); 698 if (err) 699 goto unlock; 700 } else { 701 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id); 702 if (err) { 703 NL_SET_ERR_MSG(info->extack, "Failed to allocate a new snapshot id"); 704 goto unlock; 705 } 706 } 707 708 if (port) 709 err = region->port_ops->snapshot(port, region->port_ops, 710 info->extack, &data); 711 else 712 err = region->ops->snapshot(devlink, region->ops, 713 info->extack, &data); 714 if (err) 715 goto err_snapshot_capture; 716 717 err = __devlink_region_snapshot_create(region, data, snapshot_id); 718 if (err) 719 goto err_snapshot_create; 720 721 if (!snapshot_id_attr) { 722 struct sk_buff *msg; 723 724 snapshot = devlink_region_snapshot_get_by_id(region, 725 snapshot_id); 726 if (WARN_ON(!snapshot)) { 727 err = -EINVAL; 728 goto unlock; 729 } 730 731 msg = devlink_nl_region_notify_build(region, snapshot, 732 DEVLINK_CMD_REGION_NEW, 733 info->snd_portid, 734 info->snd_seq); 735 err = PTR_ERR_OR_ZERO(msg); 736 if (err) 737 goto err_notify; 738 739 err = genlmsg_reply(msg, info); 740 if (err) 741 goto err_notify; 742 } 743 744 mutex_unlock(®ion->snapshot_lock); 745 return 0; 746 747 err_snapshot_create: 748 region->ops->destructor(data); 749 err_snapshot_capture: 750 __devlink_snapshot_id_decrement(devlink, snapshot_id); 751 mutex_unlock(®ion->snapshot_lock); 752 return err; 753 754 err_notify: 755 devlink_region_snapshot_del(region, snapshot); 756 unlock: 757 mutex_unlock(®ion->snapshot_lock); 758 return err; 759 } 760 761 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg, 762 u8 *chunk, u32 chunk_size, 763 u64 addr) 764 { 765 struct nlattr *chunk_attr; 766 int err; 767 768 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK); 769 if (!chunk_attr) 770 return -EINVAL; 771 772 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk); 773 if (err) 774 goto nla_put_failure; 775 776 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr, 777 DEVLINK_ATTR_PAD); 778 if (err) 779 goto nla_put_failure; 780 781 nla_nest_end(msg, chunk_attr); 782 return 0; 783 784 nla_put_failure: 785 nla_nest_cancel(msg, chunk_attr); 786 return err; 787 } 788 789 #define DEVLINK_REGION_READ_CHUNK_SIZE 256 790 791 typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size, 792 u64 curr_offset, 793 struct netlink_ext_ack *extack); 794 795 static int 796 devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb, 797 void *cb_priv, u64 start_offset, u64 end_offset, 798 u64 *new_offset, struct netlink_ext_ack *extack) 799 { 800 u64 curr_offset = start_offset; 801 int err = 0; 802 u8 *data; 803 804 /* Allocate and re-use a single buffer */ 805 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL); 806 if (!data) 807 return -ENOMEM; 808 809 *new_offset = start_offset; 810 811 while (curr_offset < end_offset) { 812 u32 data_size; 813 814 data_size = min_t(u32, end_offset - curr_offset, 815 DEVLINK_REGION_READ_CHUNK_SIZE); 816 817 err = cb(cb_priv, data, data_size, curr_offset, extack); 818 if (err) 819 break; 820 821 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset); 822 if (err) 823 break; 824 825 curr_offset += data_size; 826 } 827 *new_offset = curr_offset; 828 829 kfree(data); 830 831 return err; 832 } 833 834 static int 835 devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size, 836 u64 curr_offset, 837 struct netlink_ext_ack __always_unused *extack) 838 { 839 struct devlink_snapshot *snapshot = cb_priv; 840 841 memcpy(chunk, &snapshot->data[curr_offset], chunk_size); 842 843 return 0; 844 } 845 846 static int 847 devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size, 848 u64 curr_offset, struct netlink_ext_ack *extack) 849 { 850 struct devlink_region *region = cb_priv; 851 852 return region->port_ops->read(region->port, region->port_ops, extack, 853 curr_offset, chunk_size, chunk); 854 } 855 856 static int 857 devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size, 858 u64 curr_offset, struct netlink_ext_ack *extack) 859 { 860 struct devlink_region *region = cb_priv; 861 862 return region->ops->read(region->devlink, region->ops, extack, 863 curr_offset, chunk_size, chunk); 864 } 865 866 int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb, 867 struct netlink_callback *cb) 868 { 869 const struct genl_dumpit_info *info = genl_dumpit_info(cb); 870 struct devlink_nl_dump_state *state = devlink_dump_state(cb); 871 struct nlattr *chunks_attr, *region_attr, *snapshot_attr; 872 u64 ret_offset, start_offset, end_offset = U64_MAX; 873 struct nlattr **attrs = info->info.attrs; 874 struct devlink_port *port = NULL; 875 devlink_chunk_fill_t *region_cb; 876 struct devlink_region *region; 877 const char *region_name; 878 struct devlink *devlink; 879 unsigned int index; 880 void *region_cb_priv; 881 void *hdr; 882 int err; 883 884 start_offset = state->start_offset; 885 886 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs); 887 if (IS_ERR(devlink)) 888 return PTR_ERR(devlink); 889 890 if (!attrs[DEVLINK_ATTR_REGION_NAME]) { 891 NL_SET_ERR_MSG(cb->extack, "No region name provided"); 892 err = -EINVAL; 893 goto out_unlock; 894 } 895 896 if (attrs[DEVLINK_ATTR_PORT_INDEX]) { 897 index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); 898 899 port = devlink_port_get_by_index(devlink, index); 900 if (!port) { 901 err = -ENODEV; 902 goto out_unlock; 903 } 904 } 905 906 region_attr = attrs[DEVLINK_ATTR_REGION_NAME]; 907 region_name = nla_data(region_attr); 908 909 if (port) 910 region = devlink_port_region_get_by_name(port, region_name); 911 else 912 region = devlink_region_get_by_name(devlink, region_name); 913 914 if (!region) { 915 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist"); 916 err = -EINVAL; 917 goto out_unlock; 918 } 919 920 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 921 if (!snapshot_attr) { 922 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) { 923 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided"); 924 err = -EINVAL; 925 goto out_unlock; 926 } 927 928 if (!region->ops->read) { 929 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read"); 930 err = -EOPNOTSUPP; 931 goto out_unlock; 932 } 933 934 if (port) 935 region_cb = &devlink_region_port_direct_fill; 936 else 937 region_cb = &devlink_region_direct_fill; 938 region_cb_priv = region; 939 } else { 940 struct devlink_snapshot *snapshot; 941 u32 snapshot_id; 942 943 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) { 944 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot"); 945 err = -EINVAL; 946 goto out_unlock; 947 } 948 949 snapshot_id = nla_get_u32(snapshot_attr); 950 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 951 if (!snapshot) { 952 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist"); 953 err = -EINVAL; 954 goto out_unlock; 955 } 956 region_cb = &devlink_region_snapshot_fill; 957 region_cb_priv = snapshot; 958 } 959 960 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && 961 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { 962 if (!start_offset) 963 start_offset = 964 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 965 966 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 967 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); 968 } 969 970 if (end_offset > region->size) 971 end_offset = region->size; 972 973 /* return 0 if there is no further data to read */ 974 if (start_offset == end_offset) { 975 err = 0; 976 goto out_unlock; 977 } 978 979 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 980 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, 981 DEVLINK_CMD_REGION_READ); 982 if (!hdr) { 983 err = -EMSGSIZE; 984 goto out_unlock; 985 } 986 987 err = devlink_nl_put_handle(skb, devlink); 988 if (err) 989 goto nla_put_failure; 990 991 if (region->port) { 992 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, 993 region->port->index); 994 if (err) 995 goto nla_put_failure; 996 } 997 998 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); 999 if (err) 1000 goto nla_put_failure; 1001 1002 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); 1003 if (!chunks_attr) { 1004 err = -EMSGSIZE; 1005 goto nla_put_failure; 1006 } 1007 1008 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv, 1009 start_offset, end_offset, &ret_offset, 1010 cb->extack); 1011 1012 if (err && err != -EMSGSIZE) 1013 goto nla_put_failure; 1014 1015 /* Check if there was any progress done to prevent infinite loop */ 1016 if (ret_offset == start_offset) { 1017 err = -EINVAL; 1018 goto nla_put_failure; 1019 } 1020 1021 state->start_offset = ret_offset; 1022 1023 nla_nest_end(skb, chunks_attr); 1024 genlmsg_end(skb, hdr); 1025 devl_unlock(devlink); 1026 devlink_put(devlink); 1027 return skb->len; 1028 1029 nla_put_failure: 1030 genlmsg_cancel(skb, hdr); 1031 out_unlock: 1032 devl_unlock(devlink); 1033 devlink_put(devlink); 1034 return err; 1035 } 1036 1037 /** 1038 * devl_region_create - create a new address region 1039 * 1040 * @devlink: devlink 1041 * @ops: region operations and name 1042 * @region_max_snapshots: Maximum supported number of snapshots for region 1043 * @region_size: size of region 1044 */ 1045 struct devlink_region *devl_region_create(struct devlink *devlink, 1046 const struct devlink_region_ops *ops, 1047 u32 region_max_snapshots, 1048 u64 region_size) 1049 { 1050 struct devlink_region *region; 1051 1052 devl_assert_locked(devlink); 1053 1054 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 1055 return ERR_PTR(-EINVAL); 1056 1057 if (devlink_region_get_by_name(devlink, ops->name)) 1058 return ERR_PTR(-EEXIST); 1059 1060 region = kzalloc(sizeof(*region), GFP_KERNEL); 1061 if (!region) 1062 return ERR_PTR(-ENOMEM); 1063 1064 region->devlink = devlink; 1065 region->max_snapshots = region_max_snapshots; 1066 region->ops = ops; 1067 region->size = region_size; 1068 INIT_LIST_HEAD(®ion->snapshot_list); 1069 mutex_init(®ion->snapshot_lock); 1070 list_add_tail(®ion->list, &devlink->region_list); 1071 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 1072 1073 return region; 1074 } 1075 EXPORT_SYMBOL_GPL(devl_region_create); 1076 1077 /** 1078 * devlink_region_create - create a new address region 1079 * 1080 * @devlink: devlink 1081 * @ops: region operations and name 1082 * @region_max_snapshots: Maximum supported number of snapshots for region 1083 * @region_size: size of region 1084 * 1085 * Context: Takes and release devlink->lock <mutex>. 1086 */ 1087 struct devlink_region * 1088 devlink_region_create(struct devlink *devlink, 1089 const struct devlink_region_ops *ops, 1090 u32 region_max_snapshots, u64 region_size) 1091 { 1092 struct devlink_region *region; 1093 1094 devl_lock(devlink); 1095 region = devl_region_create(devlink, ops, region_max_snapshots, 1096 region_size); 1097 devl_unlock(devlink); 1098 return region; 1099 } 1100 EXPORT_SYMBOL_GPL(devlink_region_create); 1101 1102 /** 1103 * devlink_port_region_create - create a new address region for a port 1104 * 1105 * @port: devlink port 1106 * @ops: region operations and name 1107 * @region_max_snapshots: Maximum supported number of snapshots for region 1108 * @region_size: size of region 1109 * 1110 * Context: Takes and release devlink->lock <mutex>. 1111 */ 1112 struct devlink_region * 1113 devlink_port_region_create(struct devlink_port *port, 1114 const struct devlink_port_region_ops *ops, 1115 u32 region_max_snapshots, u64 region_size) 1116 { 1117 struct devlink *devlink = port->devlink; 1118 struct devlink_region *region; 1119 int err = 0; 1120 1121 ASSERT_DEVLINK_PORT_INITIALIZED(port); 1122 1123 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 1124 return ERR_PTR(-EINVAL); 1125 1126 devl_lock(devlink); 1127 1128 if (devlink_port_region_get_by_name(port, ops->name)) { 1129 err = -EEXIST; 1130 goto unlock; 1131 } 1132 1133 region = kzalloc(sizeof(*region), GFP_KERNEL); 1134 if (!region) { 1135 err = -ENOMEM; 1136 goto unlock; 1137 } 1138 1139 region->devlink = devlink; 1140 region->port = port; 1141 region->max_snapshots = region_max_snapshots; 1142 region->port_ops = ops; 1143 region->size = region_size; 1144 INIT_LIST_HEAD(®ion->snapshot_list); 1145 mutex_init(®ion->snapshot_lock); 1146 list_add_tail(®ion->list, &port->region_list); 1147 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 1148 1149 devl_unlock(devlink); 1150 return region; 1151 1152 unlock: 1153 devl_unlock(devlink); 1154 return ERR_PTR(err); 1155 } 1156 EXPORT_SYMBOL_GPL(devlink_port_region_create); 1157 1158 /** 1159 * devl_region_destroy - destroy address region 1160 * 1161 * @region: devlink region to destroy 1162 */ 1163 void devl_region_destroy(struct devlink_region *region) 1164 { 1165 struct devlink *devlink = region->devlink; 1166 struct devlink_snapshot *snapshot, *ts; 1167 1168 devl_assert_locked(devlink); 1169 1170 /* Free all snapshots of region */ 1171 mutex_lock(®ion->snapshot_lock); 1172 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list) 1173 devlink_region_snapshot_del(region, snapshot); 1174 mutex_unlock(®ion->snapshot_lock); 1175 1176 list_del(®ion->list); 1177 mutex_destroy(®ion->snapshot_lock); 1178 1179 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 1180 kfree(region); 1181 } 1182 EXPORT_SYMBOL_GPL(devl_region_destroy); 1183 1184 /** 1185 * devlink_region_destroy - destroy address region 1186 * 1187 * @region: devlink region to destroy 1188 * 1189 * Context: Takes and release devlink->lock <mutex>. 1190 */ 1191 void devlink_region_destroy(struct devlink_region *region) 1192 { 1193 struct devlink *devlink = region->devlink; 1194 1195 devl_lock(devlink); 1196 devl_region_destroy(region); 1197 devl_unlock(devlink); 1198 } 1199 EXPORT_SYMBOL_GPL(devlink_region_destroy); 1200 1201 /** 1202 * devlink_region_snapshot_id_get - get snapshot ID 1203 * 1204 * This callback should be called when adding a new snapshot, 1205 * Driver should use the same id for multiple snapshots taken 1206 * on multiple regions at the same time/by the same trigger. 1207 * 1208 * The caller of this function must use devlink_region_snapshot_id_put 1209 * when finished creating regions using this id. 1210 * 1211 * Returns zero on success, or a negative error code on failure. 1212 * 1213 * @devlink: devlink 1214 * @id: storage to return id 1215 */ 1216 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 1217 { 1218 return __devlink_region_snapshot_id_get(devlink, id); 1219 } 1220 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); 1221 1222 /** 1223 * devlink_region_snapshot_id_put - put snapshot ID reference 1224 * 1225 * This should be called by a driver after finishing creating snapshots 1226 * with an id. Doing so ensures that the ID can later be released in the 1227 * event that all snapshots using it have been destroyed. 1228 * 1229 * @devlink: devlink 1230 * @id: id to release reference on 1231 */ 1232 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) 1233 { 1234 __devlink_snapshot_id_decrement(devlink, id); 1235 } 1236 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); 1237 1238 /** 1239 * devlink_region_snapshot_create - create a new snapshot 1240 * This will add a new snapshot of a region. The snapshot 1241 * will be stored on the region struct and can be accessed 1242 * from devlink. This is useful for future analyses of snapshots. 1243 * Multiple snapshots can be created on a region. 1244 * The @snapshot_id should be obtained using the getter function. 1245 * 1246 * @region: devlink region of the snapshot 1247 * @data: snapshot data 1248 * @snapshot_id: snapshot id to be created 1249 */ 1250 int devlink_region_snapshot_create(struct devlink_region *region, 1251 u8 *data, u32 snapshot_id) 1252 { 1253 int err; 1254 1255 mutex_lock(®ion->snapshot_lock); 1256 err = __devlink_region_snapshot_create(region, data, snapshot_id); 1257 mutex_unlock(®ion->snapshot_lock); 1258 return err; 1259 } 1260 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); 1261