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
= devlink_nl_put_u64(msg
, DEVLINK_ATTR_REGION_SIZE
, region
->size
);
150 goto nla_put_failure
;
152 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS
,
153 region
->max_snapshots
);
155 goto nla_put_failure
;
157 err
= devlink_nl_region_snapshots_id_put(msg
, devlink
, region
);
159 goto nla_put_failure
;
161 genlmsg_end(msg
, hdr
);
165 genlmsg_cancel(msg
, hdr
);
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
)
174 struct devlink
*devlink
= region
->devlink
;
179 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
181 return ERR_PTR(-ENOMEM
);
183 hdr
= genlmsg_put(msg
, portid
, seq
, &devlink_nl_family
, 0, cmd
);
189 err
= devlink_nl_put_handle(msg
, devlink
);
194 err
= nla_put_u32(msg
, DEVLINK_ATTR_PORT_INDEX
,
195 region
->port
->index
);
200 err
= nla_put_string(msg
, DEVLINK_ATTR_REGION_NAME
,
206 err
= nla_put_u32(msg
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
,
211 err
= devlink_nl_put_u64(msg
, DEVLINK_ATTR_REGION_SIZE
,
216 genlmsg_end(msg
, hdr
);
221 genlmsg_cancel(msg
, hdr
);
227 static void devlink_nl_region_notify(struct devlink_region
*region
,
228 struct devlink_snapshot
*snapshot
,
229 enum devlink_command cmd
)
231 struct devlink
*devlink
= region
->devlink
;
234 WARN_ON(cmd
!= DEVLINK_CMD_REGION_NEW
&& cmd
!= DEVLINK_CMD_REGION_DEL
);
236 if (!__devl_is_registered(devlink
) || !devlink_nl_notify_need(devlink
))
239 msg
= devlink_nl_region_notify_build(region
, snapshot
, cmd
, 0, 0);
243 devlink_nl_notify_send(devlink
, msg
);
246 void devlink_regions_notify_register(struct devlink
*devlink
)
248 struct devlink_region
*region
;
250 list_for_each_entry(region
, &devlink
->region_list
, list
)
251 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_NEW
);
254 void devlink_regions_notify_unregister(struct devlink
*devlink
)
256 struct devlink_region
*region
;
258 list_for_each_entry_reverse(region
, &devlink
->region_list
, list
)
259 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
263 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
264 * @devlink: devlink instance
265 * @id: the snapshot id
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.
270 * Called when a new snapshot is created with the given id.
272 * The id *must* have been previously allocated by
273 * devlink_region_snapshot_id_get().
275 * Returns 0 on success, or an error on failure.
277 static int __devlink_snapshot_id_increment(struct devlink
*devlink
, u32 id
)
283 xa_lock(&devlink
->snapshot_ids
);
284 p
= xa_load(&devlink
->snapshot_ids
, id
);
290 if (WARN_ON(!xa_is_value(p
))) {
295 count
= xa_to_value(p
);
298 err
= xa_err(__xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
301 xa_unlock(&devlink
->snapshot_ids
);
306 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
307 * @devlink: devlink instance
308 * @id: the snapshot id
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
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().
317 * Called when a snapshot using the given id is deleted, and when the
318 * initial allocator of the id is finished using it.
320 static void __devlink_snapshot_id_decrement(struct devlink
*devlink
, u32 id
)
325 xa_lock(&devlink
->snapshot_ids
);
326 p
= xa_load(&devlink
->snapshot_ids
, id
);
330 if (WARN_ON(!xa_is_value(p
)))
333 count
= xa_to_value(p
);
337 __xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(count
),
340 /* If this was the last user, we can erase this id */
341 __xa_erase(&devlink
->snapshot_ids
, id
);
344 xa_unlock(&devlink
->snapshot_ids
);
348 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
349 * @devlink: devlink instance
350 * @id: the snapshot id
352 * Mark the given snapshot id as used by inserting a zero value into the
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.
360 * Returns zero on success, or an error code if the snapshot id could not
363 static int __devlink_snapshot_id_insert(struct devlink
*devlink
, u32 id
)
367 xa_lock(&devlink
->snapshot_ids
);
368 if (xa_load(&devlink
->snapshot_ids
, id
)) {
369 xa_unlock(&devlink
->snapshot_ids
);
372 err
= xa_err(__xa_store(&devlink
->snapshot_ids
, id
, xa_mk_value(0),
374 xa_unlock(&devlink
->snapshot_ids
);
379 * __devlink_region_snapshot_id_get - get snapshot ID
380 * @devlink: devlink instance
381 * @id: storage to return snapshot id
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
387 * Snapshot IDs are tracked using an xarray which stores the number of
388 * users of the snapshot id.
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.
394 static int __devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
396 return xa_alloc(&devlink
->snapshot_ids
, id
, xa_mk_value(1),
397 xa_limit_32b
, GFP_KERNEL
);
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.
408 * Must be called only while holding the region snapshot lock.
410 * @region: devlink region of the snapshot
411 * @data: snapshot data
412 * @snapshot_id: snapshot id to be created
415 __devlink_region_snapshot_create(struct devlink_region
*region
,
416 u8
*data
, u32 snapshot_id
)
418 struct devlink
*devlink
= region
->devlink
;
419 struct devlink_snapshot
*snapshot
;
422 lockdep_assert_held(®ion
->snapshot_lock
);
424 /* check if region can hold one more snapshot */
425 if (region
->cur_snapshots
== region
->max_snapshots
)
428 if (devlink_region_snapshot_get_by_id(region
, snapshot_id
))
431 snapshot
= kzalloc(sizeof(*snapshot
), GFP_KERNEL
);
435 err
= __devlink_snapshot_id_increment(devlink
, snapshot_id
);
437 goto err_snapshot_id_increment
;
439 snapshot
->id
= snapshot_id
;
440 snapshot
->region
= region
;
441 snapshot
->data
= data
;
443 list_add_tail(&snapshot
->list
, ®ion
->snapshot_list
);
445 region
->cur_snapshots
++;
447 devlink_nl_region_notify(region
, snapshot
, DEVLINK_CMD_REGION_NEW
);
450 err_snapshot_id_increment
:
455 static void devlink_region_snapshot_del(struct devlink_region
*region
,
456 struct devlink_snapshot
*snapshot
)
458 struct devlink
*devlink
= region
->devlink
;
460 lockdep_assert_held(®ion
->snapshot_lock
);
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
);
470 int devlink_nl_region_get_doit(struct sk_buff
*skb
, struct genl_info
*info
)
472 struct devlink
*devlink
= info
->user_ptr
[0];
473 struct devlink_port
*port
= NULL
;
474 struct devlink_region
*region
;
475 const char *region_name
;
480 if (GENL_REQ_ATTR_CHECK(info
, DEVLINK_ATTR_REGION_NAME
))
483 if (info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
484 index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
486 port
= devlink_port_get_by_index(devlink
, index
);
491 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
493 region
= devlink_port_region_get_by_name(port
, region_name
);
495 region
= devlink_region_get_by_name(devlink
, region_name
);
500 msg
= nlmsg_new(NLMSG_DEFAULT_SIZE
, GFP_KERNEL
);
504 err
= devlink_nl_region_fill(msg
, devlink
, DEVLINK_CMD_REGION_GET
,
505 info
->snd_portid
, info
->snd_seq
, 0,
512 return genlmsg_reply(msg
, info
);
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
)
520 struct devlink_region
*region
;
523 list_for_each_entry(region
, &port
->region_list
, list
) {
528 err
= devlink_nl_region_fill(msg
, port
->devlink
,
529 DEVLINK_CMD_REGION_GET
,
530 NETLINK_CB(cb
->skb
).portid
,
542 static int devlink_nl_region_get_dump_one(struct sk_buff
*msg
,
543 struct devlink
*devlink
,
544 struct netlink_callback
*cb
,
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
;
554 list_for_each_entry(region
, &devlink
->region_list
, list
) {
555 if (idx
< state
->idx
) {
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
,
571 xa_for_each(&devlink
->ports
, port_index
, port
) {
572 err
= devlink_nl_cmd_region_get_port_dumpit(msg
, cb
, port
, &idx
,
583 int devlink_nl_region_get_dumpit(struct sk_buff
*skb
,
584 struct netlink_callback
*cb
)
586 return devlink_nl_dumpit(skb
, cb
, devlink_nl_region_get_dump_one
);
589 int devlink_nl_region_del_doit(struct sk_buff
*skb
, struct genl_info
*info
)
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
;
599 if (GENL_REQ_ATTR_CHECK(info
, DEVLINK_ATTR_REGION_NAME
) ||
600 GENL_REQ_ATTR_CHECK(info
, DEVLINK_ATTR_REGION_SNAPSHOT_ID
))
603 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
604 snapshot_id
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_REGION_SNAPSHOT_ID
]);
606 if (info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
607 index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
609 port
= devlink_port_get_by_index(devlink
, index
);
615 region
= devlink_port_region_get_by_name(port
, region_name
);
617 region
= devlink_region_get_by_name(devlink
, region_name
);
622 mutex_lock(®ion
->snapshot_lock
);
623 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
625 mutex_unlock(®ion
->snapshot_lock
);
629 devlink_region_snapshot_del(region
, snapshot
);
630 mutex_unlock(®ion
->snapshot_lock
);
634 int devlink_nl_region_new_doit(struct sk_buff
*skb
, struct genl_info
*info
)
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
;
647 if (GENL_REQ_ATTR_CHECK(info
, DEVLINK_ATTR_REGION_NAME
)) {
648 NL_SET_ERR_MSG(info
->extack
, "No region name provided");
652 region_name
= nla_data(info
->attrs
[DEVLINK_ATTR_REGION_NAME
]);
654 if (info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
655 index
= nla_get_u32(info
->attrs
[DEVLINK_ATTR_PORT_INDEX
]);
657 port
= devlink_port_get_by_index(devlink
, index
);
663 region
= devlink_port_region_get_by_name(port
, region_name
);
665 region
= devlink_region_get_by_name(devlink
, region_name
);
668 NL_SET_ERR_MSG(info
->extack
, "The requested region does not exist");
672 if (!region
->ops
->snapshot
) {
673 NL_SET_ERR_MSG(info
->extack
, "The requested region does not support taking an immediate snapshot");
677 mutex_lock(®ion
->snapshot_lock
);
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");
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
);
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");
695 err
= __devlink_snapshot_id_insert(devlink
, snapshot_id
);
699 err
= __devlink_region_snapshot_id_get(devlink
, &snapshot_id
);
701 NL_SET_ERR_MSG(info
->extack
, "Failed to allocate a new snapshot id");
707 err
= region
->port_ops
->snapshot(port
, region
->port_ops
,
708 info
->extack
, &data
);
710 err
= region
->ops
->snapshot(devlink
, region
->ops
,
711 info
->extack
, &data
);
713 goto err_snapshot_capture
;
715 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
717 goto err_snapshot_create
;
719 if (!snapshot_id_attr
) {
722 snapshot
= devlink_region_snapshot_get_by_id(region
,
724 if (WARN_ON(!snapshot
)) {
729 msg
= devlink_nl_region_notify_build(region
, snapshot
,
730 DEVLINK_CMD_REGION_NEW
,
733 err
= PTR_ERR_OR_ZERO(msg
);
737 err
= genlmsg_reply(msg
, info
);
742 mutex_unlock(®ion
->snapshot_lock
);
746 region
->ops
->destructor(data
);
747 err_snapshot_capture
:
748 __devlink_snapshot_id_decrement(devlink
, snapshot_id
);
749 mutex_unlock(®ion
->snapshot_lock
);
753 devlink_region_snapshot_del(region
, snapshot
);
755 mutex_unlock(®ion
->snapshot_lock
);
759 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff
*msg
,
760 u8
*chunk
, u32 chunk_size
,
763 struct nlattr
*chunk_attr
;
766 chunk_attr
= nla_nest_start_noflag(msg
, DEVLINK_ATTR_REGION_CHUNK
);
770 err
= nla_put(msg
, DEVLINK_ATTR_REGION_CHUNK_DATA
, chunk_size
, chunk
);
772 goto nla_put_failure
;
774 err
= devlink_nl_put_u64(msg
, DEVLINK_ATTR_REGION_CHUNK_ADDR
, addr
);
776 goto nla_put_failure
;
778 nla_nest_end(msg
, chunk_attr
);
782 nla_nest_cancel(msg
, chunk_attr
);
786 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
788 typedef int devlink_chunk_fill_t(void *cb_priv
, u8
*chunk
, u32 chunk_size
,
790 struct netlink_ext_ack
*extack
);
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
)
797 u64 curr_offset
= start_offset
;
801 /* Allocate and re-use a single buffer */
802 data
= kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE
, GFP_KERNEL
);
806 *new_offset
= start_offset
;
808 while (curr_offset
< end_offset
) {
811 data_size
= min_t(u32
, end_offset
- curr_offset
,
812 DEVLINK_REGION_READ_CHUNK_SIZE
);
814 err
= cb(cb_priv
, data
, data_size
, curr_offset
, extack
);
818 err
= devlink_nl_cmd_region_read_chunk_fill(skb
, data
, data_size
, curr_offset
);
822 curr_offset
+= data_size
;
824 *new_offset
= curr_offset
;
832 devlink_region_snapshot_fill(void *cb_priv
, u8
*chunk
, u32 chunk_size
,
834 struct netlink_ext_ack __always_unused
*extack
)
836 struct devlink_snapshot
*snapshot
= cb_priv
;
838 memcpy(chunk
, &snapshot
->data
[curr_offset
], chunk_size
);
844 devlink_region_port_direct_fill(void *cb_priv
, u8
*chunk
, u32 chunk_size
,
845 u64 curr_offset
, struct netlink_ext_ack
*extack
)
847 struct devlink_region
*region
= cb_priv
;
849 return region
->port_ops
->read(region
->port
, region
->port_ops
, extack
,
850 curr_offset
, chunk_size
, chunk
);
854 devlink_region_direct_fill(void *cb_priv
, u8
*chunk
, u32 chunk_size
,
855 u64 curr_offset
, struct netlink_ext_ack
*extack
)
857 struct devlink_region
*region
= cb_priv
;
859 return region
->ops
->read(region
->devlink
, region
->ops
, extack
,
860 curr_offset
, chunk_size
, chunk
);
863 int devlink_nl_region_read_dumpit(struct sk_buff
*skb
,
864 struct netlink_callback
*cb
)
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
;
877 void *region_cb_priv
;
881 start_offset
= state
->start_offset
;
883 devlink
= devlink_get_from_attrs_lock(sock_net(cb
->skb
->sk
), attrs
,
886 return PTR_ERR(devlink
);
888 if (!attrs
[DEVLINK_ATTR_REGION_NAME
]) {
889 NL_SET_ERR_MSG(cb
->extack
, "No region name provided");
894 if (attrs
[DEVLINK_ATTR_PORT_INDEX
]) {
895 index
= nla_get_u32(attrs
[DEVLINK_ATTR_PORT_INDEX
]);
897 port
= devlink_port_get_by_index(devlink
, index
);
904 region_attr
= attrs
[DEVLINK_ATTR_REGION_NAME
];
905 region_name
= nla_data(region_attr
);
908 region
= devlink_port_region_get_by_name(port
, region_name
);
910 region
= devlink_region_get_by_name(devlink
, region_name
);
913 NL_SET_ERR_MSG_ATTR(cb
->extack
, region_attr
, "Requested region does not exist");
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");
926 if (!region
->ops
->read
) {
927 NL_SET_ERR_MSG(cb
->extack
, "Requested region does not support direct read");
933 region_cb
= &devlink_region_port_direct_fill
;
935 region_cb
= &devlink_region_direct_fill
;
936 region_cb_priv
= region
;
938 struct devlink_snapshot
*snapshot
;
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");
947 snapshot_id
= nla_get_u32(snapshot_attr
);
948 snapshot
= devlink_region_snapshot_get_by_id(region
, snapshot_id
);
950 NL_SET_ERR_MSG_ATTR(cb
->extack
, snapshot_attr
, "Requested snapshot does not exist");
954 region_cb
= &devlink_region_snapshot_fill
;
955 region_cb_priv
= snapshot
;
958 if (attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
] &&
959 attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]) {
962 nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
964 end_offset
= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_ADDR
]);
965 end_offset
+= nla_get_u64(attrs
[DEVLINK_ATTR_REGION_CHUNK_LEN
]);
968 if (end_offset
> region
->size
)
969 end_offset
= region
->size
;
971 /* return 0 if there is no further data to read */
972 if (start_offset
== end_offset
) {
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
);
985 err
= devlink_nl_put_handle(skb
, devlink
);
987 goto nla_put_failure
;
990 err
= nla_put_u32(skb
, DEVLINK_ATTR_PORT_INDEX
,
991 region
->port
->index
);
993 goto nla_put_failure
;
996 err
= nla_put_string(skb
, DEVLINK_ATTR_REGION_NAME
, region_name
);
998 goto nla_put_failure
;
1000 chunks_attr
= nla_nest_start_noflag(skb
, DEVLINK_ATTR_REGION_CHUNKS
);
1003 goto nla_put_failure
;
1006 err
= devlink_nl_region_read_fill(skb
, region_cb
, region_cb_priv
,
1007 start_offset
, end_offset
, &ret_offset
,
1010 if (err
&& err
!= -EMSGSIZE
)
1011 goto nla_put_failure
;
1013 /* Check if there was any progress done to prevent infinite loop */
1014 if (ret_offset
== start_offset
) {
1016 goto nla_put_failure
;
1019 state
->start_offset
= ret_offset
;
1021 nla_nest_end(skb
, chunks_attr
);
1022 genlmsg_end(skb
, hdr
);
1023 devl_unlock(devlink
);
1024 devlink_put(devlink
);
1028 genlmsg_cancel(skb
, hdr
);
1030 devl_unlock(devlink
);
1031 devlink_put(devlink
);
1036 * devl_region_create - create a new address region
1039 * @ops: region operations and name
1040 * @region_max_snapshots: Maximum supported number of snapshots for region
1041 * @region_size: size of region
1043 struct devlink_region
*devl_region_create(struct devlink
*devlink
,
1044 const struct devlink_region_ops
*ops
,
1045 u32 region_max_snapshots
,
1048 struct devlink_region
*region
;
1050 devl_assert_locked(devlink
);
1052 if (WARN_ON(!ops
) || WARN_ON(!ops
->destructor
))
1053 return ERR_PTR(-EINVAL
);
1055 if (devlink_region_get_by_name(devlink
, ops
->name
))
1056 return ERR_PTR(-EEXIST
);
1058 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
1060 return ERR_PTR(-ENOMEM
);
1062 region
->devlink
= devlink
;
1063 region
->max_snapshots
= region_max_snapshots
;
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
);
1073 EXPORT_SYMBOL_GPL(devl_region_create
);
1076 * devlink_region_create - create a new address region
1079 * @ops: region operations and name
1080 * @region_max_snapshots: Maximum supported number of snapshots for region
1081 * @region_size: size of region
1083 * Context: Takes and release devlink->lock <mutex>.
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
)
1090 struct devlink_region
*region
;
1093 region
= devl_region_create(devlink
, ops
, region_max_snapshots
,
1095 devl_unlock(devlink
);
1098 EXPORT_SYMBOL_GPL(devlink_region_create
);
1101 * devlink_port_region_create - create a new address region for a port
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
1108 * Context: Takes and release devlink->lock <mutex>.
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
)
1115 struct devlink
*devlink
= port
->devlink
;
1116 struct devlink_region
*region
;
1119 ASSERT_DEVLINK_PORT_INITIALIZED(port
);
1121 if (WARN_ON(!ops
) || WARN_ON(!ops
->destructor
))
1122 return ERR_PTR(-EINVAL
);
1126 if (devlink_port_region_get_by_name(port
, ops
->name
)) {
1131 region
= kzalloc(sizeof(*region
), GFP_KERNEL
);
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
);
1147 devl_unlock(devlink
);
1151 devl_unlock(devlink
);
1152 return ERR_PTR(err
);
1154 EXPORT_SYMBOL_GPL(devlink_port_region_create
);
1157 * devl_region_destroy - destroy address region
1159 * @region: devlink region to destroy
1161 void devl_region_destroy(struct devlink_region
*region
)
1163 struct devlink
*devlink
= region
->devlink
;
1164 struct devlink_snapshot
*snapshot
, *ts
;
1166 devl_assert_locked(devlink
);
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
);
1174 list_del(®ion
->list
);
1175 mutex_destroy(®ion
->snapshot_lock
);
1177 devlink_nl_region_notify(region
, NULL
, DEVLINK_CMD_REGION_DEL
);
1180 EXPORT_SYMBOL_GPL(devl_region_destroy
);
1183 * devlink_region_destroy - destroy address region
1185 * @region: devlink region to destroy
1187 * Context: Takes and release devlink->lock <mutex>.
1189 void devlink_region_destroy(struct devlink_region
*region
)
1191 struct devlink
*devlink
= region
->devlink
;
1194 devl_region_destroy(region
);
1195 devl_unlock(devlink
);
1197 EXPORT_SYMBOL_GPL(devlink_region_destroy
);
1200 * devlink_region_snapshot_id_get - get snapshot ID
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.
1206 * The caller of this function must use devlink_region_snapshot_id_put
1207 * when finished creating regions using this id.
1209 * Returns zero on success, or a negative error code on failure.
1212 * @id: storage to return id
1214 int devlink_region_snapshot_id_get(struct devlink
*devlink
, u32
*id
)
1216 return __devlink_region_snapshot_id_get(devlink
, id
);
1218 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get
);
1221 * devlink_region_snapshot_id_put - put snapshot ID reference
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.
1228 * @id: id to release reference on
1230 void devlink_region_snapshot_id_put(struct devlink
*devlink
, u32 id
)
1232 __devlink_snapshot_id_decrement(devlink
, id
);
1234 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put
);
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.
1244 * @region: devlink region of the snapshot
1245 * @data: snapshot data
1246 * @snapshot_id: snapshot id to be created
1248 int devlink_region_snapshot_create(struct devlink_region
*region
,
1249 u8
*data
, u32 snapshot_id
)
1253 mutex_lock(®ion
->snapshot_lock
);
1254 err
= __devlink_region_snapshot_create(region
, data
, snapshot_id
);
1255 mutex_unlock(®ion
->snapshot_lock
);
1258 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create
);