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);
238 if (!__devl_is_registered(devlink) || !devlink_nl_notify_need(devlink))
241 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
245 devlink_nl_notify_send(devlink, msg);
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_region_del_doit(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_region_new_doit(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_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,
889 return PTR_ERR(devlink);
891 if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
892 NL_SET_ERR_MSG(cb->extack, "No region name provided");
897 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
898 index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
900 port = devlink_port_get_by_index(devlink, index);
907 region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
908 region_name = nla_data(region_attr);
911 region = devlink_port_region_get_by_name(port, region_name);
913 region = devlink_region_get_by_name(devlink, region_name);
916 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
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");
929 if (!region->ops->read) {
930 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
936 region_cb = &devlink_region_port_direct_fill;
938 region_cb = &devlink_region_direct_fill;
939 region_cb_priv = region;
941 struct devlink_snapshot *snapshot;
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");
950 snapshot_id = nla_get_u32(snapshot_attr);
951 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
953 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
957 region_cb = &devlink_region_snapshot_fill;
958 region_cb_priv = snapshot;
961 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
962 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
965 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
967 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
968 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
971 if (end_offset > region->size)
972 end_offset = region->size;
974 /* return 0 if there is no further data to read */
975 if (start_offset == end_offset) {
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);
988 err = devlink_nl_put_handle(skb, devlink);
990 goto nla_put_failure;
993 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
994 region->port->index);
996 goto nla_put_failure;
999 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
1001 goto nla_put_failure;
1003 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
1006 goto nla_put_failure;
1009 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
1010 start_offset, end_offset, &ret_offset,
1013 if (err && err != -EMSGSIZE)
1014 goto nla_put_failure;
1016 /* Check if there was any progress done to prevent infinite loop */
1017 if (ret_offset == start_offset) {
1019 goto nla_put_failure;
1022 state->start_offset = ret_offset;
1024 nla_nest_end(skb, chunks_attr);
1025 genlmsg_end(skb, hdr);
1026 devl_unlock(devlink);
1027 devlink_put(devlink);
1031 genlmsg_cancel(skb, hdr);
1033 devl_unlock(devlink);
1034 devlink_put(devlink);
1039 * devl_region_create - create a new address region
1042 * @ops: region operations and name
1043 * @region_max_snapshots: Maximum supported number of snapshots for region
1044 * @region_size: size of region
1046 struct devlink_region *devl_region_create(struct devlink *devlink,
1047 const struct devlink_region_ops *ops,
1048 u32 region_max_snapshots,
1051 struct devlink_region *region;
1053 devl_assert_locked(devlink);
1055 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1056 return ERR_PTR(-EINVAL);
1058 if (devlink_region_get_by_name(devlink, ops->name))
1059 return ERR_PTR(-EEXIST);
1061 region = kzalloc(sizeof(*region), GFP_KERNEL);
1063 return ERR_PTR(-ENOMEM);
1065 region->devlink = devlink;
1066 region->max_snapshots = region_max_snapshots;
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);
1076 EXPORT_SYMBOL_GPL(devl_region_create);
1079 * devlink_region_create - create a new address region
1082 * @ops: region operations and name
1083 * @region_max_snapshots: Maximum supported number of snapshots for region
1084 * @region_size: size of region
1086 * Context: Takes and release devlink->lock <mutex>.
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)
1093 struct devlink_region *region;
1096 region = devl_region_create(devlink, ops, region_max_snapshots,
1098 devl_unlock(devlink);
1101 EXPORT_SYMBOL_GPL(devlink_region_create);
1104 * devlink_port_region_create - create a new address region for a port
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
1111 * Context: Takes and release devlink->lock <mutex>.
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)
1118 struct devlink *devlink = port->devlink;
1119 struct devlink_region *region;
1122 ASSERT_DEVLINK_PORT_INITIALIZED(port);
1124 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1125 return ERR_PTR(-EINVAL);
1129 if (devlink_port_region_get_by_name(port, ops->name)) {
1134 region = kzalloc(sizeof(*region), GFP_KERNEL);
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);
1150 devl_unlock(devlink);
1154 devl_unlock(devlink);
1155 return ERR_PTR(err);
1157 EXPORT_SYMBOL_GPL(devlink_port_region_create);
1160 * devl_region_destroy - destroy address region
1162 * @region: devlink region to destroy
1164 void devl_region_destroy(struct devlink_region *region)
1166 struct devlink *devlink = region->devlink;
1167 struct devlink_snapshot *snapshot, *ts;
1169 devl_assert_locked(devlink);
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);
1177 list_del(®ion->list);
1178 mutex_destroy(®ion->snapshot_lock);
1180 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
1183 EXPORT_SYMBOL_GPL(devl_region_destroy);
1186 * devlink_region_destroy - destroy address region
1188 * @region: devlink region to destroy
1190 * Context: Takes and release devlink->lock <mutex>.
1192 void devlink_region_destroy(struct devlink_region *region)
1194 struct devlink *devlink = region->devlink;
1197 devl_region_destroy(region);
1198 devl_unlock(devlink);
1200 EXPORT_SYMBOL_GPL(devlink_region_destroy);
1203 * devlink_region_snapshot_id_get - get snapshot ID
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.
1209 * The caller of this function must use devlink_region_snapshot_id_put
1210 * when finished creating regions using this id.
1212 * Returns zero on success, or a negative error code on failure.
1215 * @id: storage to return id
1217 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
1219 return __devlink_region_snapshot_id_get(devlink, id);
1221 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
1224 * devlink_region_snapshot_id_put - put snapshot ID reference
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.
1231 * @id: id to release reference on
1233 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
1235 __devlink_snapshot_id_decrement(devlink, id);
1237 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
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.
1247 * @region: devlink region of the snapshot
1248 * @data: snapshot data
1249 * @snapshot_id: snapshot id to be created
1251 int devlink_region_snapshot_create(struct devlink_region *region,
1252 u8 *data, u32 snapshot_id)
1256 mutex_lock(®ion->snapshot_lock);
1257 err = __devlink_region_snapshot_create(region, data, snapshot_id);
1258 mutex_unlock(®ion->snapshot_lock);
1261 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);