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