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 238 if (!__devl_is_registered(devlink) || !devlink_nl_notify_need(devlink)) 239 return; 240 241 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0); 242 if (IS_ERR(msg)) 243 return; 244 245 devlink_nl_notify_send(devlink, msg); 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_region_del_doit(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_region_new_doit(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_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 false); 888 if (IS_ERR(devlink)) 889 return PTR_ERR(devlink); 890 891 if (!attrs[DEVLINK_ATTR_REGION_NAME]) { 892 NL_SET_ERR_MSG(cb->extack, "No region name provided"); 893 err = -EINVAL; 894 goto out_unlock; 895 } 896 897 if (attrs[DEVLINK_ATTR_PORT_INDEX]) { 898 index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]); 899 900 port = devlink_port_get_by_index(devlink, index); 901 if (!port) { 902 err = -ENODEV; 903 goto out_unlock; 904 } 905 } 906 907 region_attr = attrs[DEVLINK_ATTR_REGION_NAME]; 908 region_name = nla_data(region_attr); 909 910 if (port) 911 region = devlink_port_region_get_by_name(port, region_name); 912 else 913 region = devlink_region_get_by_name(devlink, region_name); 914 915 if (!region) { 916 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist"); 917 err = -EINVAL; 918 goto out_unlock; 919 } 920 921 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; 922 if (!snapshot_attr) { 923 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) { 924 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided"); 925 err = -EINVAL; 926 goto out_unlock; 927 } 928 929 if (!region->ops->read) { 930 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read"); 931 err = -EOPNOTSUPP; 932 goto out_unlock; 933 } 934 935 if (port) 936 region_cb = &devlink_region_port_direct_fill; 937 else 938 region_cb = &devlink_region_direct_fill; 939 region_cb_priv = region; 940 } else { 941 struct devlink_snapshot *snapshot; 942 u32 snapshot_id; 943 944 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) { 945 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot"); 946 err = -EINVAL; 947 goto out_unlock; 948 } 949 950 snapshot_id = nla_get_u32(snapshot_attr); 951 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id); 952 if (!snapshot) { 953 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist"); 954 err = -EINVAL; 955 goto out_unlock; 956 } 957 region_cb = &devlink_region_snapshot_fill; 958 region_cb_priv = snapshot; 959 } 960 961 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] && 962 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) { 963 if (!start_offset) 964 start_offset = 965 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 966 967 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]); 968 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]); 969 } 970 971 if (end_offset > region->size) 972 end_offset = region->size; 973 974 /* return 0 if there is no further data to read */ 975 if (start_offset == end_offset) { 976 err = 0; 977 goto out_unlock; 978 } 979 980 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, 981 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, 982 DEVLINK_CMD_REGION_READ); 983 if (!hdr) { 984 err = -EMSGSIZE; 985 goto out_unlock; 986 } 987 988 err = devlink_nl_put_handle(skb, devlink); 989 if (err) 990 goto nla_put_failure; 991 992 if (region->port) { 993 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX, 994 region->port->index); 995 if (err) 996 goto nla_put_failure; 997 } 998 999 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name); 1000 if (err) 1001 goto nla_put_failure; 1002 1003 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS); 1004 if (!chunks_attr) { 1005 err = -EMSGSIZE; 1006 goto nla_put_failure; 1007 } 1008 1009 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv, 1010 start_offset, end_offset, &ret_offset, 1011 cb->extack); 1012 1013 if (err && err != -EMSGSIZE) 1014 goto nla_put_failure; 1015 1016 /* Check if there was any progress done to prevent infinite loop */ 1017 if (ret_offset == start_offset) { 1018 err = -EINVAL; 1019 goto nla_put_failure; 1020 } 1021 1022 state->start_offset = ret_offset; 1023 1024 nla_nest_end(skb, chunks_attr); 1025 genlmsg_end(skb, hdr); 1026 devl_unlock(devlink); 1027 devlink_put(devlink); 1028 return skb->len; 1029 1030 nla_put_failure: 1031 genlmsg_cancel(skb, hdr); 1032 out_unlock: 1033 devl_unlock(devlink); 1034 devlink_put(devlink); 1035 return err; 1036 } 1037 1038 /** 1039 * devl_region_create - create a new address region 1040 * 1041 * @devlink: devlink 1042 * @ops: region operations and name 1043 * @region_max_snapshots: Maximum supported number of snapshots for region 1044 * @region_size: size of region 1045 */ 1046 struct devlink_region *devl_region_create(struct devlink *devlink, 1047 const struct devlink_region_ops *ops, 1048 u32 region_max_snapshots, 1049 u64 region_size) 1050 { 1051 struct devlink_region *region; 1052 1053 devl_assert_locked(devlink); 1054 1055 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 1056 return ERR_PTR(-EINVAL); 1057 1058 if (devlink_region_get_by_name(devlink, ops->name)) 1059 return ERR_PTR(-EEXIST); 1060 1061 region = kzalloc(sizeof(*region), GFP_KERNEL); 1062 if (!region) 1063 return ERR_PTR(-ENOMEM); 1064 1065 region->devlink = devlink; 1066 region->max_snapshots = region_max_snapshots; 1067 region->ops = ops; 1068 region->size = region_size; 1069 INIT_LIST_HEAD(®ion->snapshot_list); 1070 mutex_init(®ion->snapshot_lock); 1071 list_add_tail(®ion->list, &devlink->region_list); 1072 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 1073 1074 return region; 1075 } 1076 EXPORT_SYMBOL_GPL(devl_region_create); 1077 1078 /** 1079 * devlink_region_create - create a new address region 1080 * 1081 * @devlink: devlink 1082 * @ops: region operations and name 1083 * @region_max_snapshots: Maximum supported number of snapshots for region 1084 * @region_size: size of region 1085 * 1086 * Context: Takes and release devlink->lock <mutex>. 1087 */ 1088 struct devlink_region * 1089 devlink_region_create(struct devlink *devlink, 1090 const struct devlink_region_ops *ops, 1091 u32 region_max_snapshots, u64 region_size) 1092 { 1093 struct devlink_region *region; 1094 1095 devl_lock(devlink); 1096 region = devl_region_create(devlink, ops, region_max_snapshots, 1097 region_size); 1098 devl_unlock(devlink); 1099 return region; 1100 } 1101 EXPORT_SYMBOL_GPL(devlink_region_create); 1102 1103 /** 1104 * devlink_port_region_create - create a new address region for a port 1105 * 1106 * @port: devlink port 1107 * @ops: region operations and name 1108 * @region_max_snapshots: Maximum supported number of snapshots for region 1109 * @region_size: size of region 1110 * 1111 * Context: Takes and release devlink->lock <mutex>. 1112 */ 1113 struct devlink_region * 1114 devlink_port_region_create(struct devlink_port *port, 1115 const struct devlink_port_region_ops *ops, 1116 u32 region_max_snapshots, u64 region_size) 1117 { 1118 struct devlink *devlink = port->devlink; 1119 struct devlink_region *region; 1120 int err = 0; 1121 1122 ASSERT_DEVLINK_PORT_INITIALIZED(port); 1123 1124 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) 1125 return ERR_PTR(-EINVAL); 1126 1127 devl_lock(devlink); 1128 1129 if (devlink_port_region_get_by_name(port, ops->name)) { 1130 err = -EEXIST; 1131 goto unlock; 1132 } 1133 1134 region = kzalloc(sizeof(*region), GFP_KERNEL); 1135 if (!region) { 1136 err = -ENOMEM; 1137 goto unlock; 1138 } 1139 1140 region->devlink = devlink; 1141 region->port = port; 1142 region->max_snapshots = region_max_snapshots; 1143 region->port_ops = ops; 1144 region->size = region_size; 1145 INIT_LIST_HEAD(®ion->snapshot_list); 1146 mutex_init(®ion->snapshot_lock); 1147 list_add_tail(®ion->list, &port->region_list); 1148 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW); 1149 1150 devl_unlock(devlink); 1151 return region; 1152 1153 unlock: 1154 devl_unlock(devlink); 1155 return ERR_PTR(err); 1156 } 1157 EXPORT_SYMBOL_GPL(devlink_port_region_create); 1158 1159 /** 1160 * devl_region_destroy - destroy address region 1161 * 1162 * @region: devlink region to destroy 1163 */ 1164 void devl_region_destroy(struct devlink_region *region) 1165 { 1166 struct devlink *devlink = region->devlink; 1167 struct devlink_snapshot *snapshot, *ts; 1168 1169 devl_assert_locked(devlink); 1170 1171 /* Free all snapshots of region */ 1172 mutex_lock(®ion->snapshot_lock); 1173 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list) 1174 devlink_region_snapshot_del(region, snapshot); 1175 mutex_unlock(®ion->snapshot_lock); 1176 1177 list_del(®ion->list); 1178 mutex_destroy(®ion->snapshot_lock); 1179 1180 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL); 1181 kfree(region); 1182 } 1183 EXPORT_SYMBOL_GPL(devl_region_destroy); 1184 1185 /** 1186 * devlink_region_destroy - destroy address region 1187 * 1188 * @region: devlink region to destroy 1189 * 1190 * Context: Takes and release devlink->lock <mutex>. 1191 */ 1192 void devlink_region_destroy(struct devlink_region *region) 1193 { 1194 struct devlink *devlink = region->devlink; 1195 1196 devl_lock(devlink); 1197 devl_region_destroy(region); 1198 devl_unlock(devlink); 1199 } 1200 EXPORT_SYMBOL_GPL(devlink_region_destroy); 1201 1202 /** 1203 * devlink_region_snapshot_id_get - get snapshot ID 1204 * 1205 * This callback should be called when adding a new snapshot, 1206 * Driver should use the same id for multiple snapshots taken 1207 * on multiple regions at the same time/by the same trigger. 1208 * 1209 * The caller of this function must use devlink_region_snapshot_id_put 1210 * when finished creating regions using this id. 1211 * 1212 * Returns zero on success, or a negative error code on failure. 1213 * 1214 * @devlink: devlink 1215 * @id: storage to return id 1216 */ 1217 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) 1218 { 1219 return __devlink_region_snapshot_id_get(devlink, id); 1220 } 1221 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get); 1222 1223 /** 1224 * devlink_region_snapshot_id_put - put snapshot ID reference 1225 * 1226 * This should be called by a driver after finishing creating snapshots 1227 * with an id. Doing so ensures that the ID can later be released in the 1228 * event that all snapshots using it have been destroyed. 1229 * 1230 * @devlink: devlink 1231 * @id: id to release reference on 1232 */ 1233 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) 1234 { 1235 __devlink_snapshot_id_decrement(devlink, id); 1236 } 1237 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put); 1238 1239 /** 1240 * devlink_region_snapshot_create - create a new snapshot 1241 * This will add a new snapshot of a region. The snapshot 1242 * will be stored on the region struct and can be accessed 1243 * from devlink. This is useful for future analyses of snapshots. 1244 * Multiple snapshots can be created on a region. 1245 * The @snapshot_id should be obtained using the getter function. 1246 * 1247 * @region: devlink region of the snapshot 1248 * @data: snapshot data 1249 * @snapshot_id: snapshot id to be created 1250 */ 1251 int devlink_region_snapshot_create(struct devlink_region *region, 1252 u8 *data, u32 snapshot_id) 1253 { 1254 int err; 1255 1256 mutex_lock(®ion->snapshot_lock); 1257 err = __devlink_region_snapshot_create(region, data, snapshot_id); 1258 mutex_unlock(®ion->snapshot_lock); 1259 return err; 1260 } 1261 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create); 1262
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.