Lines Matching +full:port +full:- +full:id

1 // SPDX-License-Identifier: GPL-2.0-or-later
11 struct devlink_port *port; member
31 u32 id; member
39 list_for_each_entry(region, &devlink->region_list, list) in devlink_region_get_by_name()
40 if (!strcmp(region->ops->name, region_name)) in devlink_region_get_by_name()
47 devlink_port_region_get_by_name(struct devlink_port *port, in devlink_port_region_get_by_name() argument
52 list_for_each_entry(region, &port->region_list, list) in devlink_port_region_get_by_name()
53 if (!strcmp(region->ops->name, region_name)) in devlink_port_region_get_by_name()
60 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id) in devlink_region_snapshot_get_by_id() argument
64 list_for_each_entry(snapshot, &region->snapshot_list, list) in devlink_region_snapshot_get_by_id()
65 if (snapshot->id == id) in devlink_region_snapshot_get_by_id()
80 return -EMSGSIZE; in devlink_nl_region_snapshot_id_put()
82 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id); in devlink_nl_region_snapshot_id_put()
105 return -EMSGSIZE; in devlink_nl_region_snapshots_id_put()
107 list_for_each_entry(snapshot, &region->snapshot_list, list) { in devlink_nl_region_snapshots_id_put()
131 return -EMSGSIZE; in devlink_nl_region_fill()
137 if (region->port) { in devlink_nl_region_fill()
139 region->port->index); in devlink_nl_region_fill()
144 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name); in devlink_nl_region_fill()
148 err = devlink_nl_put_u64(msg, DEVLINK_ATTR_REGION_SIZE, region->size); in devlink_nl_region_fill()
153 region->max_snapshots); in devlink_nl_region_fill()
174 struct devlink *devlink = region->devlink; in devlink_nl_region_notify_build()
181 return ERR_PTR(-ENOMEM); in devlink_nl_region_notify_build()
185 err = -EMSGSIZE; in devlink_nl_region_notify_build()
193 if (region->port) { in devlink_nl_region_notify_build()
195 region->port->index); in devlink_nl_region_notify_build()
201 region->ops->name); in devlink_nl_region_notify_build()
207 snapshot->id); in devlink_nl_region_notify_build()
212 region->size); in devlink_nl_region_notify_build()
231 struct devlink *devlink = region->devlink; in devlink_nl_region_notify()
250 list_for_each_entry(region, &devlink->region_list, list) in devlink_regions_notify_register()
258 list_for_each_entry_reverse(region, &devlink->region_list, list) in devlink_regions_notify_unregister()
263 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
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
277 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id) in __devlink_snapshot_id_increment() argument
283 xa_lock(&devlink->snapshot_ids); in __devlink_snapshot_id_increment()
284 p = xa_load(&devlink->snapshot_ids, id); in __devlink_snapshot_id_increment()
286 err = -EINVAL; in __devlink_snapshot_id_increment()
291 err = -EINVAL; in __devlink_snapshot_id_increment()
298 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), in __devlink_snapshot_id_increment()
301 xa_unlock(&devlink->snapshot_ids); in __devlink_snapshot_id_increment()
306 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
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) in __devlink_snapshot_id_decrement() argument
325 xa_lock(&devlink->snapshot_ids); in __devlink_snapshot_id_decrement()
326 p = xa_load(&devlink->snapshot_ids, id); in __devlink_snapshot_id_decrement()
336 count--; in __devlink_snapshot_id_decrement()
337 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count), in __devlink_snapshot_id_decrement()
340 /* If this was the last user, we can erase this id */ in __devlink_snapshot_id_decrement()
341 __xa_erase(&devlink->snapshot_ids, id); in __devlink_snapshot_id_decrement()
344 xa_unlock(&devlink->snapshot_ids); in __devlink_snapshot_id_decrement()
348 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
350 * @id: the snapshot id
352 * Mark the given snapshot id as used by inserting a zero value into the
357 * It is expected that the id will immediately be used before
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) in __devlink_snapshot_id_insert() argument
367 xa_lock(&devlink->snapshot_ids); in __devlink_snapshot_id_insert()
368 if (xa_load(&devlink->snapshot_ids, id)) { in __devlink_snapshot_id_insert()
369 xa_unlock(&devlink->snapshot_ids); in __devlink_snapshot_id_insert()
370 return -EEXIST; in __devlink_snapshot_id_insert()
372 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0), in __devlink_snapshot_id_insert()
374 xa_unlock(&devlink->snapshot_ids); in __devlink_snapshot_id_insert()
379 * __devlink_region_snapshot_id_get - get snapshot ID
381 * @id: storage to return snapshot id
383 * Allocates a new snapshot id. Returns zero on success, or a negative
388 * users of the snapshot id.
394 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) in __devlink_region_snapshot_id_get() argument
396 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1), in __devlink_region_snapshot_id_get()
401 * __devlink_region_snapshot_create - create a new snapshot
412 * @snapshot_id: snapshot id to be created
418 struct devlink *devlink = region->devlink; in __devlink_region_snapshot_create()
422 lockdep_assert_held(&region->snapshot_lock); in __devlink_region_snapshot_create()
425 if (region->cur_snapshots == region->max_snapshots) in __devlink_region_snapshot_create()
426 return -ENOSPC; in __devlink_region_snapshot_create()
429 return -EEXIST; in __devlink_region_snapshot_create()
433 return -ENOMEM; in __devlink_region_snapshot_create()
439 snapshot->id = snapshot_id; in __devlink_region_snapshot_create()
440 snapshot->region = region; in __devlink_region_snapshot_create()
441 snapshot->data = data; in __devlink_region_snapshot_create()
443 list_add_tail(&snapshot->list, &region->snapshot_list); in __devlink_region_snapshot_create()
445 region->cur_snapshots++; in __devlink_region_snapshot_create()
458 struct devlink *devlink = region->devlink; in devlink_region_snapshot_del()
460 lockdep_assert_held(&region->snapshot_lock); in devlink_region_snapshot_del()
463 region->cur_snapshots--; in devlink_region_snapshot_del()
464 list_del(&snapshot->list); in devlink_region_snapshot_del()
465 region->ops->destructor(snapshot->data); in devlink_region_snapshot_del()
466 __devlink_snapshot_id_decrement(devlink, snapshot->id); in devlink_region_snapshot_del()
472 struct devlink *devlink = info->user_ptr[0]; in devlink_nl_region_get_doit()
473 struct devlink_port *port = NULL; in devlink_nl_region_get_doit() local
481 return -EINVAL; in devlink_nl_region_get_doit()
483 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { in devlink_nl_region_get_doit()
484 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); in devlink_nl_region_get_doit()
486 port = devlink_port_get_by_index(devlink, index); in devlink_nl_region_get_doit()
487 if (!port) in devlink_nl_region_get_doit()
488 return -ENODEV; in devlink_nl_region_get_doit()
491 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); in devlink_nl_region_get_doit()
492 if (port) in devlink_nl_region_get_doit()
493 region = devlink_port_region_get_by_name(port, region_name); in devlink_nl_region_get_doit()
498 return -EINVAL; in devlink_nl_region_get_doit()
502 return -ENOMEM; in devlink_nl_region_get_doit()
505 info->snd_portid, info->snd_seq, 0, in devlink_nl_region_get_doit()
517 struct devlink_port *port, in devlink_nl_cmd_region_get_port_dumpit() argument
523 list_for_each_entry(region, &port->region_list, list) { in devlink_nl_cmd_region_get_port_dumpit()
528 err = devlink_nl_region_fill(msg, port->devlink, in devlink_nl_cmd_region_get_port_dumpit()
530 NETLINK_CB(cb->skb).portid, in devlink_nl_cmd_region_get_port_dumpit()
531 cb->nlh->nlmsg_seq, in devlink_nl_cmd_region_get_port_dumpit()
549 struct devlink_port *port; in devlink_nl_region_get_dump_one() local
554 list_for_each_entry(region, &devlink->region_list, list) { in devlink_nl_region_get_dump_one()
555 if (idx < state->idx) { in devlink_nl_region_get_dump_one()
561 NETLINK_CB(cb->skb).portid, in devlink_nl_region_get_dump_one()
562 cb->nlh->nlmsg_seq, flags, in devlink_nl_region_get_dump_one()
565 state->idx = idx; in devlink_nl_region_get_dump_one()
571 xa_for_each(&devlink->ports, port_index, port) { in devlink_nl_region_get_dump_one()
572 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx, in devlink_nl_region_get_dump_one()
573 state->idx, flags); in devlink_nl_region_get_dump_one()
575 state->idx = idx; in devlink_nl_region_get_dump_one()
591 struct devlink *devlink = info->user_ptr[0]; in devlink_nl_region_del_doit()
593 struct devlink_port *port = NULL; in devlink_nl_region_del_doit() local
601 return -EINVAL; in devlink_nl_region_del_doit()
603 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); in devlink_nl_region_del_doit()
604 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]); in devlink_nl_region_del_doit()
606 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { in devlink_nl_region_del_doit()
607 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); in devlink_nl_region_del_doit()
609 port = devlink_port_get_by_index(devlink, index); in devlink_nl_region_del_doit()
610 if (!port) in devlink_nl_region_del_doit()
611 return -ENODEV; in devlink_nl_region_del_doit()
614 if (port) in devlink_nl_region_del_doit()
615 region = devlink_port_region_get_by_name(port, region_name); in devlink_nl_region_del_doit()
620 return -EINVAL; in devlink_nl_region_del_doit()
622 mutex_lock(&region->snapshot_lock); in devlink_nl_region_del_doit()
625 mutex_unlock(&region->snapshot_lock); in devlink_nl_region_del_doit()
626 return -EINVAL; in devlink_nl_region_del_doit()
630 mutex_unlock(&region->snapshot_lock); in devlink_nl_region_del_doit()
636 struct devlink *devlink = info->user_ptr[0]; in devlink_nl_region_new_doit()
638 struct devlink_port *port = NULL; in devlink_nl_region_new_doit() local
648 NL_SET_ERR_MSG(info->extack, "No region name provided"); in devlink_nl_region_new_doit()
649 return -EINVAL; in devlink_nl_region_new_doit()
652 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]); in devlink_nl_region_new_doit()
654 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) { in devlink_nl_region_new_doit()
655 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]); in devlink_nl_region_new_doit()
657 port = devlink_port_get_by_index(devlink, index); in devlink_nl_region_new_doit()
658 if (!port) in devlink_nl_region_new_doit()
659 return -ENODEV; in devlink_nl_region_new_doit()
662 if (port) in devlink_nl_region_new_doit()
663 region = devlink_port_region_get_by_name(port, region_name); in devlink_nl_region_new_doit()
668 NL_SET_ERR_MSG(info->extack, "The requested region does not exist"); in devlink_nl_region_new_doit()
669 return -EINVAL; in devlink_nl_region_new_doit()
672 if (!region->ops->snapshot) { in devlink_nl_region_new_doit()
673 …NL_SET_ERR_MSG(info->extack, "The requested region does not support taking an immediate snapshot"); in devlink_nl_region_new_doit()
674 return -EOPNOTSUPP; in devlink_nl_region_new_doit()
677 mutex_lock(&region->snapshot_lock); in devlink_nl_region_new_doit()
679 if (region->cur_snapshots == region->max_snapshots) { in devlink_nl_region_new_doit()
680 NL_SET_ERR_MSG(info->extack, "The region has reached the maximum number of stored snapshots"); in devlink_nl_region_new_doit()
681 err = -ENOSPC; in devlink_nl_region_new_doit()
685 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]; in devlink_nl_region_new_doit()
690 NL_SET_ERR_MSG(info->extack, "The requested snapshot id is already in use"); in devlink_nl_region_new_doit()
691 err = -EEXIST; in devlink_nl_region_new_doit()
701 NL_SET_ERR_MSG(info->extack, "Failed to allocate a new snapshot id"); in devlink_nl_region_new_doit()
706 if (port) in devlink_nl_region_new_doit()
707 err = region->port_ops->snapshot(port, region->port_ops, in devlink_nl_region_new_doit()
708 info->extack, &data); in devlink_nl_region_new_doit()
710 err = region->ops->snapshot(devlink, region->ops, in devlink_nl_region_new_doit()
711 info->extack, &data); in devlink_nl_region_new_doit()
725 err = -EINVAL; in devlink_nl_region_new_doit()
731 info->snd_portid, in devlink_nl_region_new_doit()
732 info->snd_seq); in devlink_nl_region_new_doit()
742 mutex_unlock(&region->snapshot_lock); in devlink_nl_region_new_doit()
746 region->ops->destructor(data); in devlink_nl_region_new_doit()
749 mutex_unlock(&region->snapshot_lock); in devlink_nl_region_new_doit()
755 mutex_unlock(&region->snapshot_lock); in devlink_nl_region_new_doit()
768 return -EINVAL; in devlink_nl_cmd_region_read_chunk_fill()
801 /* Allocate and re-use a single buffer */ in devlink_nl_region_read_fill()
804 return -ENOMEM; in devlink_nl_region_read_fill()
811 data_size = min_t(u32, end_offset - curr_offset, in devlink_nl_region_read_fill()
838 memcpy(chunk, &snapshot->data[curr_offset], chunk_size); in devlink_region_snapshot_fill()
849 return region->port_ops->read(region->port, region->port_ops, extack, in devlink_region_port_direct_fill()
859 return region->ops->read(region->devlink, region->ops, extack, in devlink_region_direct_fill()
870 struct nlattr **attrs = info->info.attrs; in devlink_nl_region_read_dumpit()
871 struct devlink_port *port = NULL; in devlink_nl_region_read_dumpit() local
881 start_offset = state->start_offset; in devlink_nl_region_read_dumpit()
883 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs, in devlink_nl_region_read_dumpit()
889 NL_SET_ERR_MSG(cb->extack, "No region name provided"); in devlink_nl_region_read_dumpit()
890 err = -EINVAL; in devlink_nl_region_read_dumpit()
897 port = devlink_port_get_by_index(devlink, index); in devlink_nl_region_read_dumpit()
898 if (!port) { in devlink_nl_region_read_dumpit()
899 err = -ENODEV; in devlink_nl_region_read_dumpit()
907 if (port) in devlink_nl_region_read_dumpit()
908 region = devlink_port_region_get_by_name(port, region_name); in devlink_nl_region_read_dumpit()
913 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist"); in devlink_nl_region_read_dumpit()
914 err = -EINVAL; in devlink_nl_region_read_dumpit()
921 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided"); in devlink_nl_region_read_dumpit()
922 err = -EINVAL; in devlink_nl_region_read_dumpit()
926 if (!region->ops->read) { in devlink_nl_region_read_dumpit()
927 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read"); in devlink_nl_region_read_dumpit()
928 err = -EOPNOTSUPP; in devlink_nl_region_read_dumpit()
932 if (port) in devlink_nl_region_read_dumpit()
942 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot"); in devlink_nl_region_read_dumpit()
943 err = -EINVAL; in devlink_nl_region_read_dumpit()
950 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist"); in devlink_nl_region_read_dumpit()
951 err = -EINVAL; in devlink_nl_region_read_dumpit()
968 if (end_offset > region->size) in devlink_nl_region_read_dumpit()
969 end_offset = region->size; in devlink_nl_region_read_dumpit()
977 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq, in devlink_nl_region_read_dumpit()
981 err = -EMSGSIZE; in devlink_nl_region_read_dumpit()
989 if (region->port) { in devlink_nl_region_read_dumpit()
991 region->port->index); in devlink_nl_region_read_dumpit()
1002 err = -EMSGSIZE; in devlink_nl_region_read_dumpit()
1008 cb->extack); in devlink_nl_region_read_dumpit()
1010 if (err && err != -EMSGSIZE) in devlink_nl_region_read_dumpit()
1015 err = -EINVAL; in devlink_nl_region_read_dumpit()
1019 state->start_offset = ret_offset; in devlink_nl_region_read_dumpit()
1025 return skb->len; in devlink_nl_region_read_dumpit()
1036 * devl_region_create - create a new address region
1052 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) in devl_region_create()
1053 return ERR_PTR(-EINVAL); in devl_region_create()
1055 if (devlink_region_get_by_name(devlink, ops->name)) in devl_region_create()
1056 return ERR_PTR(-EEXIST); in devl_region_create()
1060 return ERR_PTR(-ENOMEM); in devl_region_create()
1062 region->devlink = devlink; in devl_region_create()
1063 region->max_snapshots = region_max_snapshots; in devl_region_create()
1064 region->ops = ops; in devl_region_create()
1065 region->size = region_size; in devl_region_create()
1066 INIT_LIST_HEAD(&region->snapshot_list); in devl_region_create()
1067 mutex_init(&region->snapshot_lock); in devl_region_create()
1068 list_add_tail(&region->list, &devlink->region_list); in devl_region_create()
1076 * devlink_region_create - create a new address region
1083 * Context: Takes and release devlink->lock <mutex>.
1101 * devlink_port_region_create - create a new address region for a port
1103 * @port: devlink port
1108 * Context: Takes and release devlink->lock <mutex>.
1111 devlink_port_region_create(struct devlink_port *port, in devlink_port_region_create() argument
1115 struct devlink *devlink = port->devlink; in devlink_port_region_create()
1119 ASSERT_DEVLINK_PORT_INITIALIZED(port); in devlink_port_region_create()
1121 if (WARN_ON(!ops) || WARN_ON(!ops->destructor)) in devlink_port_region_create()
1122 return ERR_PTR(-EINVAL); in devlink_port_region_create()
1126 if (devlink_port_region_get_by_name(port, ops->name)) { in devlink_port_region_create()
1127 err = -EEXIST; in devlink_port_region_create()
1133 err = -ENOMEM; in devlink_port_region_create()
1137 region->devlink = devlink; in devlink_port_region_create()
1138 region->port = port; in devlink_port_region_create()
1139 region->max_snapshots = region_max_snapshots; in devlink_port_region_create()
1140 region->port_ops = ops; in devlink_port_region_create()
1141 region->size = region_size; in devlink_port_region_create()
1142 INIT_LIST_HEAD(&region->snapshot_list); in devlink_port_region_create()
1143 mutex_init(&region->snapshot_lock); in devlink_port_region_create()
1144 list_add_tail(&region->list, &port->region_list); in devlink_port_region_create()
1157 * devl_region_destroy - destroy address region
1163 struct devlink *devlink = region->devlink; in devl_region_destroy()
1169 mutex_lock(&region->snapshot_lock); in devl_region_destroy()
1170 list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list) in devl_region_destroy()
1172 mutex_unlock(&region->snapshot_lock); in devl_region_destroy()
1174 list_del(&region->list); in devl_region_destroy()
1175 mutex_destroy(&region->snapshot_lock); in devl_region_destroy()
1183 * devlink_region_destroy - destroy address region
1187 * Context: Takes and release devlink->lock <mutex>.
1191 struct devlink *devlink = region->devlink; in devlink_region_destroy()
1200 * devlink_region_snapshot_id_get - get snapshot ID
1203 * Driver should use the same id for multiple snapshots taken
1207 * when finished creating regions using this id.
1212 * @id: storage to return id
1214 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id) in devlink_region_snapshot_id_get() argument
1216 return __devlink_region_snapshot_id_get(devlink, id); in devlink_region_snapshot_id_get()
1221 * devlink_region_snapshot_id_put - put snapshot ID reference
1224 * with an id. Doing so ensures that the ID can later be released in the
1228 * @id: id to release reference on
1230 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id) in devlink_region_snapshot_id_put() argument
1232 __devlink_snapshot_id_decrement(devlink, id); in devlink_region_snapshot_id_put()
1237 * devlink_region_snapshot_create - create a new snapshot
1246 * @snapshot_id: snapshot id to be created
1253 mutex_lock(&region->snapshot_lock); in devlink_region_snapshot_create()
1255 mutex_unlock(&region->snapshot_lock); in devlink_region_snapshot_create()