Merge tag 'powerpc-6.6-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc...
[platform/kernel/linux-rpi.git] / net / devlink / region.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
4  * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
5  */
6
7 #include "devl_internal.h"
8
9 struct devlink_region {
10         struct devlink *devlink;
11         struct devlink_port *port;
12         struct list_head list;
13         union {
14                 const struct devlink_region_ops *ops;
15                 const struct devlink_port_region_ops *port_ops;
16         };
17         struct mutex snapshot_lock; /* protects snapshot_list,
18                                      * max_snapshots and cur_snapshots
19                                      * consistency.
20                                      */
21         struct list_head snapshot_list;
22         u32 max_snapshots;
23         u32 cur_snapshots;
24         u64 size;
25 };
26
27 struct devlink_snapshot {
28         struct list_head list;
29         struct devlink_region *region;
30         u8 *data;
31         u32 id;
32 };
33
34 static struct devlink_region *
35 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
36 {
37         struct devlink_region *region;
38
39         list_for_each_entry(region, &devlink->region_list, list)
40                 if (!strcmp(region->ops->name, region_name))
41                         return region;
42
43         return NULL;
44 }
45
46 static struct devlink_region *
47 devlink_port_region_get_by_name(struct devlink_port *port,
48                                 const char *region_name)
49 {
50         struct devlink_region *region;
51
52         list_for_each_entry(region, &port->region_list, list)
53                 if (!strcmp(region->ops->name, region_name))
54                         return region;
55
56         return NULL;
57 }
58
59 static struct devlink_snapshot *
60 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
61 {
62         struct devlink_snapshot *snapshot;
63
64         list_for_each_entry(snapshot, &region->snapshot_list, list)
65                 if (snapshot->id == id)
66                         return snapshot;
67
68         return NULL;
69 }
70
71 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
72                                              struct devlink *devlink,
73                                              struct devlink_snapshot *snapshot)
74 {
75         struct nlattr *snap_attr;
76         int err;
77
78         snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
79         if (!snap_attr)
80                 return -EINVAL;
81
82         err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
83         if (err)
84                 goto nla_put_failure;
85
86         nla_nest_end(msg, snap_attr);
87         return 0;
88
89 nla_put_failure:
90         nla_nest_cancel(msg, snap_attr);
91         return err;
92 }
93
94 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
95                                               struct devlink *devlink,
96                                               struct devlink_region *region)
97 {
98         struct devlink_snapshot *snapshot;
99         struct nlattr *snapshots_attr;
100         int err;
101
102         snapshots_attr = nla_nest_start_noflag(msg,
103                                                DEVLINK_ATTR_REGION_SNAPSHOTS);
104         if (!snapshots_attr)
105                 return -EINVAL;
106
107         list_for_each_entry(snapshot, &region->snapshot_list, list) {
108                 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
109                 if (err)
110                         goto nla_put_failure;
111         }
112
113         nla_nest_end(msg, snapshots_attr);
114         return 0;
115
116 nla_put_failure:
117         nla_nest_cancel(msg, snapshots_attr);
118         return err;
119 }
120
121 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
122                                   enum devlink_command cmd, u32 portid,
123                                   u32 seq, int flags,
124                                   struct devlink_region *region)
125 {
126         void *hdr;
127         int err;
128
129         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
130         if (!hdr)
131                 return -EMSGSIZE;
132
133         err = devlink_nl_put_handle(msg, devlink);
134         if (err)
135                 goto nla_put_failure;
136
137         if (region->port) {
138                 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
139                                   region->port->index);
140                 if (err)
141                         goto nla_put_failure;
142         }
143
144         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
145         if (err)
146                 goto nla_put_failure;
147
148         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
149                                 region->size,
150                                 DEVLINK_ATTR_PAD);
151         if (err)
152                 goto nla_put_failure;
153
154         err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
155                           region->max_snapshots);
156         if (err)
157                 goto nla_put_failure;
158
159         err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
160         if (err)
161                 goto nla_put_failure;
162
163         genlmsg_end(msg, hdr);
164         return 0;
165
166 nla_put_failure:
167         genlmsg_cancel(msg, hdr);
168         return err;
169 }
170
171 static struct sk_buff *
172 devlink_nl_region_notify_build(struct devlink_region *region,
173                                struct devlink_snapshot *snapshot,
174                                enum devlink_command cmd, u32 portid, u32 seq)
175 {
176         struct devlink *devlink = region->devlink;
177         struct sk_buff *msg;
178         void *hdr;
179         int err;
180
181         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
182         if (!msg)
183                 return ERR_PTR(-ENOMEM);
184
185         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
186         if (!hdr) {
187                 err = -EMSGSIZE;
188                 goto out_free_msg;
189         }
190
191         err = devlink_nl_put_handle(msg, devlink);
192         if (err)
193                 goto out_cancel_msg;
194
195         if (region->port) {
196                 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
197                                   region->port->index);
198                 if (err)
199                         goto out_cancel_msg;
200         }
201
202         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
203                              region->ops->name);
204         if (err)
205                 goto out_cancel_msg;
206
207         if (snapshot) {
208                 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
209                                   snapshot->id);
210                 if (err)
211                         goto out_cancel_msg;
212         } else {
213                 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
214                                         region->size, DEVLINK_ATTR_PAD);
215                 if (err)
216                         goto out_cancel_msg;
217         }
218         genlmsg_end(msg, hdr);
219
220         return msg;
221
222 out_cancel_msg:
223         genlmsg_cancel(msg, hdr);
224 out_free_msg:
225         nlmsg_free(msg);
226         return ERR_PTR(err);
227 }
228
229 static void devlink_nl_region_notify(struct devlink_region *region,
230                                      struct devlink_snapshot *snapshot,
231                                      enum devlink_command cmd)
232 {
233         struct devlink *devlink = region->devlink;
234         struct sk_buff *msg;
235
236         WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
237         if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
238                 return;
239
240         msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
241         if (IS_ERR(msg))
242                 return;
243
244         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
245                                 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
246 }
247
248 void devlink_regions_notify_register(struct devlink *devlink)
249 {
250         struct devlink_region *region;
251
252         list_for_each_entry(region, &devlink->region_list, list)
253                 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
254 }
255
256 void devlink_regions_notify_unregister(struct devlink *devlink)
257 {
258         struct devlink_region *region;
259
260         list_for_each_entry_reverse(region, &devlink->region_list, list)
261                 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
262 }
263
264 /**
265  * __devlink_snapshot_id_increment - Increment number of snapshots using an id
266  *      @devlink: devlink instance
267  *      @id: the snapshot id
268  *
269  *      Track when a new snapshot begins using an id. Load the count for the
270  *      given id from the snapshot xarray, increment it, and store it back.
271  *
272  *      Called when a new snapshot is created with the given id.
273  *
274  *      The id *must* have been previously allocated by
275  *      devlink_region_snapshot_id_get().
276  *
277  *      Returns 0 on success, or an error on failure.
278  */
279 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
280 {
281         unsigned long count;
282         void *p;
283         int err;
284
285         xa_lock(&devlink->snapshot_ids);
286         p = xa_load(&devlink->snapshot_ids, id);
287         if (WARN_ON(!p)) {
288                 err = -EINVAL;
289                 goto unlock;
290         }
291
292         if (WARN_ON(!xa_is_value(p))) {
293                 err = -EINVAL;
294                 goto unlock;
295         }
296
297         count = xa_to_value(p);
298         count++;
299
300         err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
301                                 GFP_ATOMIC));
302 unlock:
303         xa_unlock(&devlink->snapshot_ids);
304         return err;
305 }
306
307 /**
308  * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
309  *      @devlink: devlink instance
310  *      @id: the snapshot id
311  *
312  *      Track when a snapshot is deleted and stops using an id. Load the count
313  *      for the given id from the snapshot xarray, decrement it, and store it
314  *      back.
315  *
316  *      If the count reaches zero, erase this id from the xarray, freeing it
317  *      up for future re-use by devlink_region_snapshot_id_get().
318  *
319  *      Called when a snapshot using the given id is deleted, and when the
320  *      initial allocator of the id is finished using it.
321  */
322 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
323 {
324         unsigned long count;
325         void *p;
326
327         xa_lock(&devlink->snapshot_ids);
328         p = xa_load(&devlink->snapshot_ids, id);
329         if (WARN_ON(!p))
330                 goto unlock;
331
332         if (WARN_ON(!xa_is_value(p)))
333                 goto unlock;
334
335         count = xa_to_value(p);
336
337         if (count > 1) {
338                 count--;
339                 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
340                            GFP_ATOMIC);
341         } else {
342                 /* If this was the last user, we can erase this id */
343                 __xa_erase(&devlink->snapshot_ids, id);
344         }
345 unlock:
346         xa_unlock(&devlink->snapshot_ids);
347 }
348
349 /**
350  *      __devlink_snapshot_id_insert - Insert a specific snapshot ID
351  *      @devlink: devlink instance
352  *      @id: the snapshot id
353  *
354  *      Mark the given snapshot id as used by inserting a zero value into the
355  *      snapshot xarray.
356  *
357  *      This must be called while holding the devlink instance lock. Unlike
358  *      devlink_snapshot_id_get, the initial reference count is zero, not one.
359  *      It is expected that the id will immediately be used before
360  *      releasing the devlink instance lock.
361  *
362  *      Returns zero on success, or an error code if the snapshot id could not
363  *      be inserted.
364  */
365 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
366 {
367         int err;
368
369         xa_lock(&devlink->snapshot_ids);
370         if (xa_load(&devlink->snapshot_ids, id)) {
371                 xa_unlock(&devlink->snapshot_ids);
372                 return -EEXIST;
373         }
374         err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
375                                 GFP_ATOMIC));
376         xa_unlock(&devlink->snapshot_ids);
377         return err;
378 }
379
380 /**
381  *      __devlink_region_snapshot_id_get - get snapshot ID
382  *      @devlink: devlink instance
383  *      @id: storage to return snapshot id
384  *
385  *      Allocates a new snapshot id. Returns zero on success, or a negative
386  *      error on failure. Must be called while holding the devlink instance
387  *      lock.
388  *
389  *      Snapshot IDs are tracked using an xarray which stores the number of
390  *      users of the snapshot id.
391  *
392  *      Note that the caller of this function counts as a 'user', in order to
393  *      avoid race conditions. The caller must release its hold on the
394  *      snapshot by using devlink_region_snapshot_id_put.
395  */
396 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
397 {
398         return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
399                         xa_limit_32b, GFP_KERNEL);
400 }
401
402 /**
403  *      __devlink_region_snapshot_create - create a new snapshot
404  *      This will add a new snapshot of a region. The snapshot
405  *      will be stored on the region struct and can be accessed
406  *      from devlink. This is useful for future analyses of snapshots.
407  *      Multiple snapshots can be created on a region.
408  *      The @snapshot_id should be obtained using the getter function.
409  *
410  *      Must be called only while holding the region snapshot lock.
411  *
412  *      @region: devlink region of the snapshot
413  *      @data: snapshot data
414  *      @snapshot_id: snapshot id to be created
415  */
416 static int
417 __devlink_region_snapshot_create(struct devlink_region *region,
418                                  u8 *data, u32 snapshot_id)
419 {
420         struct devlink *devlink = region->devlink;
421         struct devlink_snapshot *snapshot;
422         int err;
423
424         lockdep_assert_held(&region->snapshot_lock);
425
426         /* check if region can hold one more snapshot */
427         if (region->cur_snapshots == region->max_snapshots)
428                 return -ENOSPC;
429
430         if (devlink_region_snapshot_get_by_id(region, snapshot_id))
431                 return -EEXIST;
432
433         snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
434         if (!snapshot)
435                 return -ENOMEM;
436
437         err = __devlink_snapshot_id_increment(devlink, snapshot_id);
438         if (err)
439                 goto err_snapshot_id_increment;
440
441         snapshot->id = snapshot_id;
442         snapshot->region = region;
443         snapshot->data = data;
444
445         list_add_tail(&snapshot->list, &region->snapshot_list);
446
447         region->cur_snapshots++;
448
449         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
450         return 0;
451
452 err_snapshot_id_increment:
453         kfree(snapshot);
454         return err;
455 }
456
457 static void devlink_region_snapshot_del(struct devlink_region *region,
458                                         struct devlink_snapshot *snapshot)
459 {
460         struct devlink *devlink = region->devlink;
461
462         lockdep_assert_held(&region->snapshot_lock);
463
464         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
465         region->cur_snapshots--;
466         list_del(&snapshot->list);
467         region->ops->destructor(snapshot->data);
468         __devlink_snapshot_id_decrement(devlink, snapshot->id);
469         kfree(snapshot);
470 }
471
472 int devlink_nl_region_get_doit(struct sk_buff *skb, struct genl_info *info)
473 {
474         struct devlink *devlink = info->user_ptr[0];
475         struct devlink_port *port = NULL;
476         struct devlink_region *region;
477         const char *region_name;
478         struct sk_buff *msg;
479         unsigned int index;
480         int err;
481
482         if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
483                 return -EINVAL;
484
485         if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
486                 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
487
488                 port = devlink_port_get_by_index(devlink, index);
489                 if (!port)
490                         return -ENODEV;
491         }
492
493         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
494         if (port)
495                 region = devlink_port_region_get_by_name(port, region_name);
496         else
497                 region = devlink_region_get_by_name(devlink, region_name);
498
499         if (!region)
500                 return -EINVAL;
501
502         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
503         if (!msg)
504                 return -ENOMEM;
505
506         err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
507                                      info->snd_portid, info->snd_seq, 0,
508                                      region);
509         if (err) {
510                 nlmsg_free(msg);
511                 return err;
512         }
513
514         return genlmsg_reply(msg, info);
515 }
516
517 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
518                                                  struct netlink_callback *cb,
519                                                  struct devlink_port *port,
520                                                  int *idx, int start, int flags)
521 {
522         struct devlink_region *region;
523         int err = 0;
524
525         list_for_each_entry(region, &port->region_list, list) {
526                 if (*idx < start) {
527                         (*idx)++;
528                         continue;
529                 }
530                 err = devlink_nl_region_fill(msg, port->devlink,
531                                              DEVLINK_CMD_REGION_GET,
532                                              NETLINK_CB(cb->skb).portid,
533                                              cb->nlh->nlmsg_seq,
534                                              flags, region);
535                 if (err)
536                         goto out;
537                 (*idx)++;
538         }
539
540 out:
541         return err;
542 }
543
544 static int devlink_nl_region_get_dump_one(struct sk_buff *msg,
545                                           struct devlink *devlink,
546                                           struct netlink_callback *cb,
547                                           int flags)
548 {
549         struct devlink_nl_dump_state *state = devlink_dump_state(cb);
550         struct devlink_region *region;
551         struct devlink_port *port;
552         unsigned long port_index;
553         int idx = 0;
554         int err;
555
556         list_for_each_entry(region, &devlink->region_list, list) {
557                 if (idx < state->idx) {
558                         idx++;
559                         continue;
560                 }
561                 err = devlink_nl_region_fill(msg, devlink,
562                                              DEVLINK_CMD_REGION_GET,
563                                              NETLINK_CB(cb->skb).portid,
564                                              cb->nlh->nlmsg_seq, flags,
565                                              region);
566                 if (err) {
567                         state->idx = idx;
568                         return err;
569                 }
570                 idx++;
571         }
572
573         xa_for_each(&devlink->ports, port_index, port) {
574                 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx,
575                                                             state->idx, flags);
576                 if (err) {
577                         state->idx = idx;
578                         return err;
579                 }
580         }
581
582         return 0;
583 }
584
585 int devlink_nl_region_get_dumpit(struct sk_buff *skb,
586                                  struct netlink_callback *cb)
587 {
588         return devlink_nl_dumpit(skb, cb, devlink_nl_region_get_dump_one);
589 }
590
591 int devlink_nl_cmd_region_del(struct sk_buff *skb, struct genl_info *info)
592 {
593         struct devlink *devlink = info->user_ptr[0];
594         struct devlink_snapshot *snapshot;
595         struct devlink_port *port = NULL;
596         struct devlink_region *region;
597         const char *region_name;
598         unsigned int index;
599         u32 snapshot_id;
600
601         if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
602             GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
603                 return -EINVAL;
604
605         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
606         snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
607
608         if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
609                 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
610
611                 port = devlink_port_get_by_index(devlink, index);
612                 if (!port)
613                         return -ENODEV;
614         }
615
616         if (port)
617                 region = devlink_port_region_get_by_name(port, region_name);
618         else
619                 region = devlink_region_get_by_name(devlink, region_name);
620
621         if (!region)
622                 return -EINVAL;
623
624         mutex_lock(&region->snapshot_lock);
625         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
626         if (!snapshot) {
627                 mutex_unlock(&region->snapshot_lock);
628                 return -EINVAL;
629         }
630
631         devlink_region_snapshot_del(region, snapshot);
632         mutex_unlock(&region->snapshot_lock);
633         return 0;
634 }
635
636 int devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
637 {
638         struct devlink *devlink = info->user_ptr[0];
639         struct devlink_snapshot *snapshot;
640         struct devlink_port *port = NULL;
641         struct nlattr *snapshot_id_attr;
642         struct devlink_region *region;
643         const char *region_name;
644         unsigned int index;
645         u32 snapshot_id;
646         u8 *data;
647         int err;
648
649         if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
650                 NL_SET_ERR_MSG(info->extack, "No region name provided");
651                 return -EINVAL;
652         }
653
654         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
655
656         if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
657                 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
658
659                 port = devlink_port_get_by_index(devlink, index);
660                 if (!port)
661                         return -ENODEV;
662         }
663
664         if (port)
665                 region = devlink_port_region_get_by_name(port, region_name);
666         else
667                 region = devlink_region_get_by_name(devlink, region_name);
668
669         if (!region) {
670                 NL_SET_ERR_MSG(info->extack, "The requested region does not exist");
671                 return -EINVAL;
672         }
673
674         if (!region->ops->snapshot) {
675                 NL_SET_ERR_MSG(info->extack, "The requested region does not support taking an immediate snapshot");
676                 return -EOPNOTSUPP;
677         }
678
679         mutex_lock(&region->snapshot_lock);
680
681         if (region->cur_snapshots == region->max_snapshots) {
682                 NL_SET_ERR_MSG(info->extack, "The region has reached the maximum number of stored snapshots");
683                 err = -ENOSPC;
684                 goto unlock;
685         }
686
687         snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
688         if (snapshot_id_attr) {
689                 snapshot_id = nla_get_u32(snapshot_id_attr);
690
691                 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
692                         NL_SET_ERR_MSG(info->extack, "The requested snapshot id is already in use");
693                         err = -EEXIST;
694                         goto unlock;
695                 }
696
697                 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
698                 if (err)
699                         goto unlock;
700         } else {
701                 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
702                 if (err) {
703                         NL_SET_ERR_MSG(info->extack, "Failed to allocate a new snapshot id");
704                         goto unlock;
705                 }
706         }
707
708         if (port)
709                 err = region->port_ops->snapshot(port, region->port_ops,
710                                                  info->extack, &data);
711         else
712                 err = region->ops->snapshot(devlink, region->ops,
713                                             info->extack, &data);
714         if (err)
715                 goto err_snapshot_capture;
716
717         err = __devlink_region_snapshot_create(region, data, snapshot_id);
718         if (err)
719                 goto err_snapshot_create;
720
721         if (!snapshot_id_attr) {
722                 struct sk_buff *msg;
723
724                 snapshot = devlink_region_snapshot_get_by_id(region,
725                                                              snapshot_id);
726                 if (WARN_ON(!snapshot)) {
727                         err = -EINVAL;
728                         goto unlock;
729                 }
730
731                 msg = devlink_nl_region_notify_build(region, snapshot,
732                                                      DEVLINK_CMD_REGION_NEW,
733                                                      info->snd_portid,
734                                                      info->snd_seq);
735                 err = PTR_ERR_OR_ZERO(msg);
736                 if (err)
737                         goto err_notify;
738
739                 err = genlmsg_reply(msg, info);
740                 if (err)
741                         goto err_notify;
742         }
743
744         mutex_unlock(&region->snapshot_lock);
745         return 0;
746
747 err_snapshot_create:
748         region->ops->destructor(data);
749 err_snapshot_capture:
750         __devlink_snapshot_id_decrement(devlink, snapshot_id);
751         mutex_unlock(&region->snapshot_lock);
752         return err;
753
754 err_notify:
755         devlink_region_snapshot_del(region, snapshot);
756 unlock:
757         mutex_unlock(&region->snapshot_lock);
758         return err;
759 }
760
761 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
762                                                  u8 *chunk, u32 chunk_size,
763                                                  u64 addr)
764 {
765         struct nlattr *chunk_attr;
766         int err;
767
768         chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
769         if (!chunk_attr)
770                 return -EINVAL;
771
772         err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
773         if (err)
774                 goto nla_put_failure;
775
776         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
777                                 DEVLINK_ATTR_PAD);
778         if (err)
779                 goto nla_put_failure;
780
781         nla_nest_end(msg, chunk_attr);
782         return 0;
783
784 nla_put_failure:
785         nla_nest_cancel(msg, chunk_attr);
786         return err;
787 }
788
789 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
790
791 typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
792                                  u64 curr_offset,
793                                  struct netlink_ext_ack *extack);
794
795 static int
796 devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb,
797                             void *cb_priv, u64 start_offset, u64 end_offset,
798                             u64 *new_offset, struct netlink_ext_ack *extack)
799 {
800         u64 curr_offset = start_offset;
801         int err = 0;
802         u8 *data;
803
804         /* Allocate and re-use a single buffer */
805         data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
806         if (!data)
807                 return -ENOMEM;
808
809         *new_offset = start_offset;
810
811         while (curr_offset < end_offset) {
812                 u32 data_size;
813
814                 data_size = min_t(u32, end_offset - curr_offset,
815                                   DEVLINK_REGION_READ_CHUNK_SIZE);
816
817                 err = cb(cb_priv, data, data_size, curr_offset, extack);
818                 if (err)
819                         break;
820
821                 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
822                 if (err)
823                         break;
824
825                 curr_offset += data_size;
826         }
827         *new_offset = curr_offset;
828
829         kfree(data);
830
831         return err;
832 }
833
834 static int
835 devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
836                              u64 curr_offset,
837                              struct netlink_ext_ack __always_unused *extack)
838 {
839         struct devlink_snapshot *snapshot = cb_priv;
840
841         memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
842
843         return 0;
844 }
845
846 static int
847 devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
848                                 u64 curr_offset, struct netlink_ext_ack *extack)
849 {
850         struct devlink_region *region = cb_priv;
851
852         return region->port_ops->read(region->port, region->port_ops, extack,
853                                       curr_offset, chunk_size, chunk);
854 }
855
856 static int
857 devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
858                            u64 curr_offset, struct netlink_ext_ack *extack)
859 {
860         struct devlink_region *region = cb_priv;
861
862         return region->ops->read(region->devlink, region->ops, extack,
863                                  curr_offset, chunk_size, chunk);
864 }
865
866 int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
867                                       struct netlink_callback *cb)
868 {
869         const struct genl_dumpit_info *info = genl_dumpit_info(cb);
870         struct devlink_nl_dump_state *state = devlink_dump_state(cb);
871         struct nlattr *chunks_attr, *region_attr, *snapshot_attr;
872         u64 ret_offset, start_offset, end_offset = U64_MAX;
873         struct nlattr **attrs = info->info.attrs;
874         struct devlink_port *port = NULL;
875         devlink_chunk_fill_t *region_cb;
876         struct devlink_region *region;
877         const char *region_name;
878         struct devlink *devlink;
879         unsigned int index;
880         void *region_cb_priv;
881         void *hdr;
882         int err;
883
884         start_offset = state->start_offset;
885
886         devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
887         if (IS_ERR(devlink))
888                 return PTR_ERR(devlink);
889
890         if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
891                 NL_SET_ERR_MSG(cb->extack, "No region name provided");
892                 err = -EINVAL;
893                 goto out_unlock;
894         }
895
896         if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
897                 index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
898
899                 port = devlink_port_get_by_index(devlink, index);
900                 if (!port) {
901                         err = -ENODEV;
902                         goto out_unlock;
903                 }
904         }
905
906         region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
907         region_name = nla_data(region_attr);
908
909         if (port)
910                 region = devlink_port_region_get_by_name(port, region_name);
911         else
912                 region = devlink_region_get_by_name(devlink, region_name);
913
914         if (!region) {
915                 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
916                 err = -EINVAL;
917                 goto out_unlock;
918         }
919
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");
924                         err = -EINVAL;
925                         goto out_unlock;
926                 }
927
928                 if (!region->ops->read) {
929                         NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
930                         err = -EOPNOTSUPP;
931                         goto out_unlock;
932                 }
933
934                 if (port)
935                         region_cb = &devlink_region_port_direct_fill;
936                 else
937                         region_cb = &devlink_region_direct_fill;
938                 region_cb_priv = region;
939         } else {
940                 struct devlink_snapshot *snapshot;
941                 u32 snapshot_id;
942
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");
945                         err = -EINVAL;
946                         goto out_unlock;
947                 }
948
949                 snapshot_id = nla_get_u32(snapshot_attr);
950                 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
951                 if (!snapshot) {
952                         NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
953                         err = -EINVAL;
954                         goto out_unlock;
955                 }
956                 region_cb = &devlink_region_snapshot_fill;
957                 region_cb_priv = snapshot;
958         }
959
960         if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
961             attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
962                 if (!start_offset)
963                         start_offset =
964                                 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
965
966                 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
967                 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
968         }
969
970         if (end_offset > region->size)
971                 end_offset = region->size;
972
973         /* return 0 if there is no further data to read */
974         if (start_offset == end_offset) {
975                 err = 0;
976                 goto out_unlock;
977         }
978
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);
982         if (!hdr) {
983                 err = -EMSGSIZE;
984                 goto out_unlock;
985         }
986
987         err = devlink_nl_put_handle(skb, devlink);
988         if (err)
989                 goto nla_put_failure;
990
991         if (region->port) {
992                 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
993                                   region->port->index);
994                 if (err)
995                         goto nla_put_failure;
996         }
997
998         err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
999         if (err)
1000                 goto nla_put_failure;
1001
1002         chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
1003         if (!chunks_attr) {
1004                 err = -EMSGSIZE;
1005                 goto nla_put_failure;
1006         }
1007
1008         err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
1009                                           start_offset, end_offset, &ret_offset,
1010                                           cb->extack);
1011
1012         if (err && err != -EMSGSIZE)
1013                 goto nla_put_failure;
1014
1015         /* Check if there was any progress done to prevent infinite loop */
1016         if (ret_offset == start_offset) {
1017                 err = -EINVAL;
1018                 goto nla_put_failure;
1019         }
1020
1021         state->start_offset = ret_offset;
1022
1023         nla_nest_end(skb, chunks_attr);
1024         genlmsg_end(skb, hdr);
1025         devl_unlock(devlink);
1026         devlink_put(devlink);
1027         return skb->len;
1028
1029 nla_put_failure:
1030         genlmsg_cancel(skb, hdr);
1031 out_unlock:
1032         devl_unlock(devlink);
1033         devlink_put(devlink);
1034         return err;
1035 }
1036
1037 /**
1038  * devl_region_create - create a new address region
1039  *
1040  * @devlink: devlink
1041  * @ops: region operations and name
1042  * @region_max_snapshots: Maximum supported number of snapshots for region
1043  * @region_size: size of region
1044  */
1045 struct devlink_region *devl_region_create(struct devlink *devlink,
1046                                           const struct devlink_region_ops *ops,
1047                                           u32 region_max_snapshots,
1048                                           u64 region_size)
1049 {
1050         struct devlink_region *region;
1051
1052         devl_assert_locked(devlink);
1053
1054         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1055                 return ERR_PTR(-EINVAL);
1056
1057         if (devlink_region_get_by_name(devlink, ops->name))
1058                 return ERR_PTR(-EEXIST);
1059
1060         region = kzalloc(sizeof(*region), GFP_KERNEL);
1061         if (!region)
1062                 return ERR_PTR(-ENOMEM);
1063
1064         region->devlink = devlink;
1065         region->max_snapshots = region_max_snapshots;
1066         region->ops = ops;
1067         region->size = region_size;
1068         INIT_LIST_HEAD(&region->snapshot_list);
1069         mutex_init(&region->snapshot_lock);
1070         list_add_tail(&region->list, &devlink->region_list);
1071         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
1072
1073         return region;
1074 }
1075 EXPORT_SYMBOL_GPL(devl_region_create);
1076
1077 /**
1078  *      devlink_region_create - create a new address region
1079  *
1080  *      @devlink: devlink
1081  *      @ops: region operations and name
1082  *      @region_max_snapshots: Maximum supported number of snapshots for region
1083  *      @region_size: size of region
1084  *
1085  *      Context: Takes and release devlink->lock <mutex>.
1086  */
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)
1091 {
1092         struct devlink_region *region;
1093
1094         devl_lock(devlink);
1095         region = devl_region_create(devlink, ops, region_max_snapshots,
1096                                     region_size);
1097         devl_unlock(devlink);
1098         return region;
1099 }
1100 EXPORT_SYMBOL_GPL(devlink_region_create);
1101
1102 /**
1103  *      devlink_port_region_create - create a new address region for a port
1104  *
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
1109  *
1110  *      Context: Takes and release devlink->lock <mutex>.
1111  */
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)
1116 {
1117         struct devlink *devlink = port->devlink;
1118         struct devlink_region *region;
1119         int err = 0;
1120
1121         ASSERT_DEVLINK_PORT_INITIALIZED(port);
1122
1123         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1124                 return ERR_PTR(-EINVAL);
1125
1126         devl_lock(devlink);
1127
1128         if (devlink_port_region_get_by_name(port, ops->name)) {
1129                 err = -EEXIST;
1130                 goto unlock;
1131         }
1132
1133         region = kzalloc(sizeof(*region), GFP_KERNEL);
1134         if (!region) {
1135                 err = -ENOMEM;
1136                 goto unlock;
1137         }
1138
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(&region->snapshot_list);
1145         mutex_init(&region->snapshot_lock);
1146         list_add_tail(&region->list, &port->region_list);
1147         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
1148
1149         devl_unlock(devlink);
1150         return region;
1151
1152 unlock:
1153         devl_unlock(devlink);
1154         return ERR_PTR(err);
1155 }
1156 EXPORT_SYMBOL_GPL(devlink_port_region_create);
1157
1158 /**
1159  * devl_region_destroy - destroy address region
1160  *
1161  * @region: devlink region to destroy
1162  */
1163 void devl_region_destroy(struct devlink_region *region)
1164 {
1165         struct devlink *devlink = region->devlink;
1166         struct devlink_snapshot *snapshot, *ts;
1167
1168         devl_assert_locked(devlink);
1169
1170         /* Free all snapshots of region */
1171         mutex_lock(&region->snapshot_lock);
1172         list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
1173                 devlink_region_snapshot_del(region, snapshot);
1174         mutex_unlock(&region->snapshot_lock);
1175
1176         list_del(&region->list);
1177         mutex_destroy(&region->snapshot_lock);
1178
1179         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
1180         kfree(region);
1181 }
1182 EXPORT_SYMBOL_GPL(devl_region_destroy);
1183
1184 /**
1185  *      devlink_region_destroy - destroy address region
1186  *
1187  *      @region: devlink region to destroy
1188  *
1189  *      Context: Takes and release devlink->lock <mutex>.
1190  */
1191 void devlink_region_destroy(struct devlink_region *region)
1192 {
1193         struct devlink *devlink = region->devlink;
1194
1195         devl_lock(devlink);
1196         devl_region_destroy(region);
1197         devl_unlock(devlink);
1198 }
1199 EXPORT_SYMBOL_GPL(devlink_region_destroy);
1200
1201 /**
1202  *      devlink_region_snapshot_id_get - get snapshot ID
1203  *
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.
1207  *
1208  *      The caller of this function must use devlink_region_snapshot_id_put
1209  *      when finished creating regions using this id.
1210  *
1211  *      Returns zero on success, or a negative error code on failure.
1212  *
1213  *      @devlink: devlink
1214  *      @id: storage to return id
1215  */
1216 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
1217 {
1218         return __devlink_region_snapshot_id_get(devlink, id);
1219 }
1220 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
1221
1222 /**
1223  *      devlink_region_snapshot_id_put - put snapshot ID reference
1224  *
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.
1228  *
1229  *      @devlink: devlink
1230  *      @id: id to release reference on
1231  */
1232 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
1233 {
1234         __devlink_snapshot_id_decrement(devlink, id);
1235 }
1236 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
1237
1238 /**
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.
1245  *
1246  *      @region: devlink region of the snapshot
1247  *      @data: snapshot data
1248  *      @snapshot_id: snapshot id to be created
1249  */
1250 int devlink_region_snapshot_create(struct devlink_region *region,
1251                                    u8 *data, u32 snapshot_id)
1252 {
1253         int err;
1254
1255         mutex_lock(&region->snapshot_lock);
1256         err = __devlink_region_snapshot_create(region, data, snapshot_id);
1257         mutex_unlock(&region->snapshot_lock);
1258         return err;
1259 }
1260 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);