1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
4 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
7 #include "devl_internal.h"
9 struct devlink_region {
10 struct devlink *devlink;
11 struct devlink_port *port;
12 struct list_head list;
14 const struct devlink_region_ops *ops;
15 const struct devlink_port_region_ops *port_ops;
17 struct mutex snapshot_lock; /* protects snapshot_list,
18 * max_snapshots and cur_snapshots
21 struct list_head snapshot_list;
27 struct devlink_snapshot {
28 struct list_head list;
29 struct devlink_region *region;
34 static struct devlink_region *
35 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
37 struct devlink_region *region;
39 list_for_each_entry(region, &devlink->region_list, list)
40 if (!strcmp(region->ops->name, region_name))
46 static struct devlink_region *
47 devlink_port_region_get_by_name(struct devlink_port *port,
48 const char *region_name)
50 struct devlink_region *region;
52 list_for_each_entry(region, &port->region_list, list)
53 if (!strcmp(region->ops->name, region_name))
59 static struct devlink_snapshot *
60 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
62 struct devlink_snapshot *snapshot;
64 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
65 if (snapshot->id == id)
71 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
72 struct devlink *devlink,
73 struct devlink_snapshot *snapshot)
75 struct nlattr *snap_attr;
78 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
82 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
86 nla_nest_end(msg, snap_attr);
90 nla_nest_cancel(msg, snap_attr);
94 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
95 struct devlink *devlink,
96 struct devlink_region *region)
98 struct devlink_snapshot *snapshot;
99 struct nlattr *snapshots_attr;
102 snapshots_attr = nla_nest_start_noflag(msg,
103 DEVLINK_ATTR_REGION_SNAPSHOTS);
107 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
108 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
110 goto nla_put_failure;
113 nla_nest_end(msg, snapshots_attr);
117 nla_nest_cancel(msg, snapshots_attr);
121 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
122 enum devlink_command cmd, u32 portid,
124 struct devlink_region *region)
129 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
133 err = devlink_nl_put_handle(msg, devlink);
135 goto nla_put_failure;
138 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
139 region->port->index);
141 goto nla_put_failure;
144 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
146 goto nla_put_failure;
148 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
152 goto nla_put_failure;
154 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
155 region->max_snapshots);
157 goto nla_put_failure;
159 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
161 goto nla_put_failure;
163 genlmsg_end(msg, hdr);
167 genlmsg_cancel(msg, hdr);
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)
176 struct devlink *devlink = region->devlink;
181 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
183 return ERR_PTR(-ENOMEM);
185 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
191 err = devlink_nl_put_handle(msg, devlink);
196 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
197 region->port->index);
202 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
208 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
213 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
214 region->size, DEVLINK_ATTR_PAD);
218 genlmsg_end(msg, hdr);
223 genlmsg_cancel(msg, hdr);
229 static void devlink_nl_region_notify(struct devlink_region *region,
230 struct devlink_snapshot *snapshot,
231 enum devlink_command cmd)
233 struct devlink *devlink = region->devlink;
236 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
237 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
240 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
244 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
245 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
248 void devlink_regions_notify_register(struct devlink *devlink)
250 struct devlink_region *region;
252 list_for_each_entry(region, &devlink->region_list, list)
253 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
256 void devlink_regions_notify_unregister(struct devlink *devlink)
258 struct devlink_region *region;
260 list_for_each_entry_reverse(region, &devlink->region_list, list)
261 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
265 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
266 * @devlink: devlink instance
267 * @id: the snapshot id
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.
272 * Called when a new snapshot is created with the given id.
274 * The id *must* have been previously allocated by
275 * devlink_region_snapshot_id_get().
277 * Returns 0 on success, or an error on failure.
279 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
285 xa_lock(&devlink->snapshot_ids);
286 p = xa_load(&devlink->snapshot_ids, id);
292 if (WARN_ON(!xa_is_value(p))) {
297 count = xa_to_value(p);
300 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
303 xa_unlock(&devlink->snapshot_ids);
308 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
309 * @devlink: devlink instance
310 * @id: the snapshot id
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
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().
319 * Called when a snapshot using the given id is deleted, and when the
320 * initial allocator of the id is finished using it.
322 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
327 xa_lock(&devlink->snapshot_ids);
328 p = xa_load(&devlink->snapshot_ids, id);
332 if (WARN_ON(!xa_is_value(p)))
335 count = xa_to_value(p);
339 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
342 /* If this was the last user, we can erase this id */
343 __xa_erase(&devlink->snapshot_ids, id);
346 xa_unlock(&devlink->snapshot_ids);
350 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
351 * @devlink: devlink instance
352 * @id: the snapshot id
354 * Mark the given snapshot id as used by inserting a zero value into the
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.
362 * Returns zero on success, or an error code if the snapshot id could not
365 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
369 xa_lock(&devlink->snapshot_ids);
370 if (xa_load(&devlink->snapshot_ids, id)) {
371 xa_unlock(&devlink->snapshot_ids);
374 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
376 xa_unlock(&devlink->snapshot_ids);
381 * __devlink_region_snapshot_id_get - get snapshot ID
382 * @devlink: devlink instance
383 * @id: storage to return snapshot id
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
389 * Snapshot IDs are tracked using an xarray which stores the number of
390 * users of the snapshot id.
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.
396 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
398 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
399 xa_limit_32b, GFP_KERNEL);
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.
410 * Must be called only while holding the region snapshot lock.
412 * @region: devlink region of the snapshot
413 * @data: snapshot data
414 * @snapshot_id: snapshot id to be created
417 __devlink_region_snapshot_create(struct devlink_region *region,
418 u8 *data, u32 snapshot_id)
420 struct devlink *devlink = region->devlink;
421 struct devlink_snapshot *snapshot;
424 lockdep_assert_held(®ion->snapshot_lock);
426 /* check if region can hold one more snapshot */
427 if (region->cur_snapshots == region->max_snapshots)
430 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
433 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
437 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
439 goto err_snapshot_id_increment;
441 snapshot->id = snapshot_id;
442 snapshot->region = region;
443 snapshot->data = data;
445 list_add_tail(&snapshot->list, ®ion->snapshot_list);
447 region->cur_snapshots++;
449 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
452 err_snapshot_id_increment:
457 static void devlink_region_snapshot_del(struct devlink_region *region,
458 struct devlink_snapshot *snapshot)
460 struct devlink *devlink = region->devlink;
462 lockdep_assert_held(®ion->snapshot_lock);
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);
472 int devlink_nl_region_get_doit(struct sk_buff *skb, struct genl_info *info)
474 struct devlink *devlink = info->user_ptr[0];
475 struct devlink_port *port = NULL;
476 struct devlink_region *region;
477 const char *region_name;
482 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
485 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
486 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
488 port = devlink_port_get_by_index(devlink, index);
493 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
495 region = devlink_port_region_get_by_name(port, region_name);
497 region = devlink_region_get_by_name(devlink, region_name);
502 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
506 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
507 info->snd_portid, info->snd_seq, 0,
514 return genlmsg_reply(msg, info);
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)
522 struct devlink_region *region;
525 list_for_each_entry(region, &port->region_list, list) {
530 err = devlink_nl_region_fill(msg, port->devlink,
531 DEVLINK_CMD_REGION_GET,
532 NETLINK_CB(cb->skb).portid,
544 static int devlink_nl_region_get_dump_one(struct sk_buff *msg,
545 struct devlink *devlink,
546 struct netlink_callback *cb,
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;
556 list_for_each_entry(region, &devlink->region_list, list) {
557 if (idx < state->idx) {
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,
573 xa_for_each(&devlink->ports, port_index, port) {
574 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx,
585 int devlink_nl_region_get_dumpit(struct sk_buff *skb,
586 struct netlink_callback *cb)
588 return devlink_nl_dumpit(skb, cb, devlink_nl_region_get_dump_one);
591 int devlink_nl_cmd_region_del(struct sk_buff *skb, struct genl_info *info)
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;
601 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
602 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
605 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
606 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
608 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
609 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
611 port = devlink_port_get_by_index(devlink, index);
617 region = devlink_port_region_get_by_name(port, region_name);
619 region = devlink_region_get_by_name(devlink, region_name);
624 mutex_lock(®ion->snapshot_lock);
625 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
627 mutex_unlock(®ion->snapshot_lock);
631 devlink_region_snapshot_del(region, snapshot);
632 mutex_unlock(®ion->snapshot_lock);
636 int devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
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;
649 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
650 NL_SET_ERR_MSG(info->extack, "No region name provided");
654 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
656 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
657 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
659 port = devlink_port_get_by_index(devlink, index);
665 region = devlink_port_region_get_by_name(port, region_name);
667 region = devlink_region_get_by_name(devlink, region_name);
670 NL_SET_ERR_MSG(info->extack, "The requested region does not exist");
674 if (!region->ops->snapshot) {
675 NL_SET_ERR_MSG(info->extack, "The requested region does not support taking an immediate snapshot");
679 mutex_lock(®ion->snapshot_lock);
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");
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);
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");
697 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
701 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
703 NL_SET_ERR_MSG(info->extack, "Failed to allocate a new snapshot id");
709 err = region->port_ops->snapshot(port, region->port_ops,
710 info->extack, &data);
712 err = region->ops->snapshot(devlink, region->ops,
713 info->extack, &data);
715 goto err_snapshot_capture;
717 err = __devlink_region_snapshot_create(region, data, snapshot_id);
719 goto err_snapshot_create;
721 if (!snapshot_id_attr) {
724 snapshot = devlink_region_snapshot_get_by_id(region,
726 if (WARN_ON(!snapshot)) {
731 msg = devlink_nl_region_notify_build(region, snapshot,
732 DEVLINK_CMD_REGION_NEW,
735 err = PTR_ERR_OR_ZERO(msg);
739 err = genlmsg_reply(msg, info);
744 mutex_unlock(®ion->snapshot_lock);
748 region->ops->destructor(data);
749 err_snapshot_capture:
750 __devlink_snapshot_id_decrement(devlink, snapshot_id);
751 mutex_unlock(®ion->snapshot_lock);
755 devlink_region_snapshot_del(region, snapshot);
757 mutex_unlock(®ion->snapshot_lock);
761 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
762 u8 *chunk, u32 chunk_size,
765 struct nlattr *chunk_attr;
768 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
772 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
774 goto nla_put_failure;
776 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
779 goto nla_put_failure;
781 nla_nest_end(msg, chunk_attr);
785 nla_nest_cancel(msg, chunk_attr);
789 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
791 typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
793 struct netlink_ext_ack *extack);
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)
800 u64 curr_offset = start_offset;
804 /* Allocate and re-use a single buffer */
805 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
809 *new_offset = start_offset;
811 while (curr_offset < end_offset) {
814 data_size = min_t(u32, end_offset - curr_offset,
815 DEVLINK_REGION_READ_CHUNK_SIZE);
817 err = cb(cb_priv, data, data_size, curr_offset, extack);
821 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
825 curr_offset += data_size;
827 *new_offset = curr_offset;
835 devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
837 struct netlink_ext_ack __always_unused *extack)
839 struct devlink_snapshot *snapshot = cb_priv;
841 memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
847 devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
848 u64 curr_offset, struct netlink_ext_ack *extack)
850 struct devlink_region *region = cb_priv;
852 return region->port_ops->read(region->port, region->port_ops, extack,
853 curr_offset, chunk_size, chunk);
857 devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
858 u64 curr_offset, struct netlink_ext_ack *extack)
860 struct devlink_region *region = cb_priv;
862 return region->ops->read(region->devlink, region->ops, extack,
863 curr_offset, chunk_size, chunk);
866 int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
867 struct netlink_callback *cb)
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;
880 void *region_cb_priv;
884 start_offset = state->start_offset;
886 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
888 return PTR_ERR(devlink);
890 if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
891 NL_SET_ERR_MSG(cb->extack, "No region name provided");
896 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
897 index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
899 port = devlink_port_get_by_index(devlink, index);
906 region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
907 region_name = nla_data(region_attr);
910 region = devlink_port_region_get_by_name(port, region_name);
912 region = devlink_region_get_by_name(devlink, region_name);
915 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
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");
928 if (!region->ops->read) {
929 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
935 region_cb = &devlink_region_port_direct_fill;
937 region_cb = &devlink_region_direct_fill;
938 region_cb_priv = region;
940 struct devlink_snapshot *snapshot;
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");
949 snapshot_id = nla_get_u32(snapshot_attr);
950 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
952 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
956 region_cb = &devlink_region_snapshot_fill;
957 region_cb_priv = snapshot;
960 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
961 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
964 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
966 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
967 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
970 if (end_offset > region->size)
971 end_offset = region->size;
973 /* return 0 if there is no further data to read */
974 if (start_offset == end_offset) {
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);
987 err = devlink_nl_put_handle(skb, devlink);
989 goto nla_put_failure;
992 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
993 region->port->index);
995 goto nla_put_failure;
998 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
1000 goto nla_put_failure;
1002 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
1005 goto nla_put_failure;
1008 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
1009 start_offset, end_offset, &ret_offset,
1012 if (err && err != -EMSGSIZE)
1013 goto nla_put_failure;
1015 /* Check if there was any progress done to prevent infinite loop */
1016 if (ret_offset == start_offset) {
1018 goto nla_put_failure;
1021 state->start_offset = ret_offset;
1023 nla_nest_end(skb, chunks_attr);
1024 genlmsg_end(skb, hdr);
1025 devl_unlock(devlink);
1026 devlink_put(devlink);
1030 genlmsg_cancel(skb, hdr);
1032 devl_unlock(devlink);
1033 devlink_put(devlink);
1038 * devl_region_create - create a new address region
1041 * @ops: region operations and name
1042 * @region_max_snapshots: Maximum supported number of snapshots for region
1043 * @region_size: size of region
1045 struct devlink_region *devl_region_create(struct devlink *devlink,
1046 const struct devlink_region_ops *ops,
1047 u32 region_max_snapshots,
1050 struct devlink_region *region;
1052 devl_assert_locked(devlink);
1054 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1055 return ERR_PTR(-EINVAL);
1057 if (devlink_region_get_by_name(devlink, ops->name))
1058 return ERR_PTR(-EEXIST);
1060 region = kzalloc(sizeof(*region), GFP_KERNEL);
1062 return ERR_PTR(-ENOMEM);
1064 region->devlink = devlink;
1065 region->max_snapshots = region_max_snapshots;
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);
1075 EXPORT_SYMBOL_GPL(devl_region_create);
1078 * devlink_region_create - create a new address region
1081 * @ops: region operations and name
1082 * @region_max_snapshots: Maximum supported number of snapshots for region
1083 * @region_size: size of region
1085 * Context: Takes and release devlink->lock <mutex>.
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)
1092 struct devlink_region *region;
1095 region = devl_region_create(devlink, ops, region_max_snapshots,
1097 devl_unlock(devlink);
1100 EXPORT_SYMBOL_GPL(devlink_region_create);
1103 * devlink_port_region_create - create a new address region for a port
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
1110 * Context: Takes and release devlink->lock <mutex>.
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)
1117 struct devlink *devlink = port->devlink;
1118 struct devlink_region *region;
1121 ASSERT_DEVLINK_PORT_INITIALIZED(port);
1123 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1124 return ERR_PTR(-EINVAL);
1128 if (devlink_port_region_get_by_name(port, ops->name)) {
1133 region = kzalloc(sizeof(*region), GFP_KERNEL);
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);
1149 devl_unlock(devlink);
1153 devl_unlock(devlink);
1154 return ERR_PTR(err);
1156 EXPORT_SYMBOL_GPL(devlink_port_region_create);
1159 * devl_region_destroy - destroy address region
1161 * @region: devlink region to destroy
1163 void devl_region_destroy(struct devlink_region *region)
1165 struct devlink *devlink = region->devlink;
1166 struct devlink_snapshot *snapshot, *ts;
1168 devl_assert_locked(devlink);
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);
1176 list_del(®ion->list);
1177 mutex_destroy(®ion->snapshot_lock);
1179 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
1182 EXPORT_SYMBOL_GPL(devl_region_destroy);
1185 * devlink_region_destroy - destroy address region
1187 * @region: devlink region to destroy
1189 * Context: Takes and release devlink->lock <mutex>.
1191 void devlink_region_destroy(struct devlink_region *region)
1193 struct devlink *devlink = region->devlink;
1196 devl_region_destroy(region);
1197 devl_unlock(devlink);
1199 EXPORT_SYMBOL_GPL(devlink_region_destroy);
1202 * devlink_region_snapshot_id_get - get snapshot ID
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.
1208 * The caller of this function must use devlink_region_snapshot_id_put
1209 * when finished creating regions using this id.
1211 * Returns zero on success, or a negative error code on failure.
1214 * @id: storage to return id
1216 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
1218 return __devlink_region_snapshot_id_get(devlink, id);
1220 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
1223 * devlink_region_snapshot_id_put - put snapshot ID reference
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.
1230 * @id: id to release reference on
1232 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
1234 __devlink_snapshot_id_decrement(devlink, id);
1236 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
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.
1246 * @region: devlink region of the snapshot
1247 * @data: snapshot data
1248 * @snapshot_id: snapshot id to be created
1250 int devlink_region_snapshot_create(struct devlink_region *region,
1251 u8 *data, u32 snapshot_id)
1255 mutex_lock(®ion->snapshot_lock);
1256 err = __devlink_region_snapshot_create(region, data, snapshot_id);
1257 mutex_unlock(®ion->snapshot_lock);
1260 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);