Mention branches and keyring.
[releases.git] / 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
238         if (!__devl_is_registered(devlink) || !devlink_nl_notify_need(devlink))
239                 return;
240
241         msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
242         if (IS_ERR(msg))
243                 return;
244
245         devlink_nl_notify_send(devlink, msg);
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_region_del_doit(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_region_new_doit(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_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                                               false);
888         if (IS_ERR(devlink))
889                 return PTR_ERR(devlink);
890
891         if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
892                 NL_SET_ERR_MSG(cb->extack, "No region name provided");
893                 err = -EINVAL;
894                 goto out_unlock;
895         }
896
897         if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
898                 index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
899
900                 port = devlink_port_get_by_index(devlink, index);
901                 if (!port) {
902                         err = -ENODEV;
903                         goto out_unlock;
904                 }
905         }
906
907         region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
908         region_name = nla_data(region_attr);
909
910         if (port)
911                 region = devlink_port_region_get_by_name(port, region_name);
912         else
913                 region = devlink_region_get_by_name(devlink, region_name);
914
915         if (!region) {
916                 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
917                 err = -EINVAL;
918                 goto out_unlock;
919         }
920
921         snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
922         if (!snapshot_attr) {
923                 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
924                         NL_SET_ERR_MSG(cb->extack, "No snapshot id provided");
925                         err = -EINVAL;
926                         goto out_unlock;
927                 }
928
929                 if (!region->ops->read) {
930                         NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
931                         err = -EOPNOTSUPP;
932                         goto out_unlock;
933                 }
934
935                 if (port)
936                         region_cb = &devlink_region_port_direct_fill;
937                 else
938                         region_cb = &devlink_region_direct_fill;
939                 region_cb_priv = region;
940         } else {
941                 struct devlink_snapshot *snapshot;
942                 u32 snapshot_id;
943
944                 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
945                         NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot");
946                         err = -EINVAL;
947                         goto out_unlock;
948                 }
949
950                 snapshot_id = nla_get_u32(snapshot_attr);
951                 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
952                 if (!snapshot) {
953                         NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
954                         err = -EINVAL;
955                         goto out_unlock;
956                 }
957                 region_cb = &devlink_region_snapshot_fill;
958                 region_cb_priv = snapshot;
959         }
960
961         if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
962             attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
963                 if (!start_offset)
964                         start_offset =
965                                 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
966
967                 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
968                 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
969         }
970
971         if (end_offset > region->size)
972                 end_offset = region->size;
973
974         /* return 0 if there is no further data to read */
975         if (start_offset == end_offset) {
976                 err = 0;
977                 goto out_unlock;
978         }
979
980         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
981                           &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
982                           DEVLINK_CMD_REGION_READ);
983         if (!hdr) {
984                 err = -EMSGSIZE;
985                 goto out_unlock;
986         }
987
988         err = devlink_nl_put_handle(skb, devlink);
989         if (err)
990                 goto nla_put_failure;
991
992         if (region->port) {
993                 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
994                                   region->port->index);
995                 if (err)
996                         goto nla_put_failure;
997         }
998
999         err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
1000         if (err)
1001                 goto nla_put_failure;
1002
1003         chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
1004         if (!chunks_attr) {
1005                 err = -EMSGSIZE;
1006                 goto nla_put_failure;
1007         }
1008
1009         err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
1010                                           start_offset, end_offset, &ret_offset,
1011                                           cb->extack);
1012
1013         if (err && err != -EMSGSIZE)
1014                 goto nla_put_failure;
1015
1016         /* Check if there was any progress done to prevent infinite loop */
1017         if (ret_offset == start_offset) {
1018                 err = -EINVAL;
1019                 goto nla_put_failure;
1020         }
1021
1022         state->start_offset = ret_offset;
1023
1024         nla_nest_end(skb, chunks_attr);
1025         genlmsg_end(skb, hdr);
1026         devl_unlock(devlink);
1027         devlink_put(devlink);
1028         return skb->len;
1029
1030 nla_put_failure:
1031         genlmsg_cancel(skb, hdr);
1032 out_unlock:
1033         devl_unlock(devlink);
1034         devlink_put(devlink);
1035         return err;
1036 }
1037
1038 /**
1039  * devl_region_create - create a new address region
1040  *
1041  * @devlink: devlink
1042  * @ops: region operations and name
1043  * @region_max_snapshots: Maximum supported number of snapshots for region
1044  * @region_size: size of region
1045  */
1046 struct devlink_region *devl_region_create(struct devlink *devlink,
1047                                           const struct devlink_region_ops *ops,
1048                                           u32 region_max_snapshots,
1049                                           u64 region_size)
1050 {
1051         struct devlink_region *region;
1052
1053         devl_assert_locked(devlink);
1054
1055         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1056                 return ERR_PTR(-EINVAL);
1057
1058         if (devlink_region_get_by_name(devlink, ops->name))
1059                 return ERR_PTR(-EEXIST);
1060
1061         region = kzalloc(sizeof(*region), GFP_KERNEL);
1062         if (!region)
1063                 return ERR_PTR(-ENOMEM);
1064
1065         region->devlink = devlink;
1066         region->max_snapshots = region_max_snapshots;
1067         region->ops = ops;
1068         region->size = region_size;
1069         INIT_LIST_HEAD(&region->snapshot_list);
1070         mutex_init(&region->snapshot_lock);
1071         list_add_tail(&region->list, &devlink->region_list);
1072         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
1073
1074         return region;
1075 }
1076 EXPORT_SYMBOL_GPL(devl_region_create);
1077
1078 /**
1079  *      devlink_region_create - create a new address region
1080  *
1081  *      @devlink: devlink
1082  *      @ops: region operations and name
1083  *      @region_max_snapshots: Maximum supported number of snapshots for region
1084  *      @region_size: size of region
1085  *
1086  *      Context: Takes and release devlink->lock <mutex>.
1087  */
1088 struct devlink_region *
1089 devlink_region_create(struct devlink *devlink,
1090                       const struct devlink_region_ops *ops,
1091                       u32 region_max_snapshots, u64 region_size)
1092 {
1093         struct devlink_region *region;
1094
1095         devl_lock(devlink);
1096         region = devl_region_create(devlink, ops, region_max_snapshots,
1097                                     region_size);
1098         devl_unlock(devlink);
1099         return region;
1100 }
1101 EXPORT_SYMBOL_GPL(devlink_region_create);
1102
1103 /**
1104  *      devlink_port_region_create - create a new address region for a port
1105  *
1106  *      @port: devlink port
1107  *      @ops: region operations and name
1108  *      @region_max_snapshots: Maximum supported number of snapshots for region
1109  *      @region_size: size of region
1110  *
1111  *      Context: Takes and release devlink->lock <mutex>.
1112  */
1113 struct devlink_region *
1114 devlink_port_region_create(struct devlink_port *port,
1115                            const struct devlink_port_region_ops *ops,
1116                            u32 region_max_snapshots, u64 region_size)
1117 {
1118         struct devlink *devlink = port->devlink;
1119         struct devlink_region *region;
1120         int err = 0;
1121
1122         ASSERT_DEVLINK_PORT_INITIALIZED(port);
1123
1124         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
1125                 return ERR_PTR(-EINVAL);
1126
1127         devl_lock(devlink);
1128
1129         if (devlink_port_region_get_by_name(port, ops->name)) {
1130                 err = -EEXIST;
1131                 goto unlock;
1132         }
1133
1134         region = kzalloc(sizeof(*region), GFP_KERNEL);
1135         if (!region) {
1136                 err = -ENOMEM;
1137                 goto unlock;
1138         }
1139
1140         region->devlink = devlink;
1141         region->port = port;
1142         region->max_snapshots = region_max_snapshots;
1143         region->port_ops = ops;
1144         region->size = region_size;
1145         INIT_LIST_HEAD(&region->snapshot_list);
1146         mutex_init(&region->snapshot_lock);
1147         list_add_tail(&region->list, &port->region_list);
1148         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
1149
1150         devl_unlock(devlink);
1151         return region;
1152
1153 unlock:
1154         devl_unlock(devlink);
1155         return ERR_PTR(err);
1156 }
1157 EXPORT_SYMBOL_GPL(devlink_port_region_create);
1158
1159 /**
1160  * devl_region_destroy - destroy address region
1161  *
1162  * @region: devlink region to destroy
1163  */
1164 void devl_region_destroy(struct devlink_region *region)
1165 {
1166         struct devlink *devlink = region->devlink;
1167         struct devlink_snapshot *snapshot, *ts;
1168
1169         devl_assert_locked(devlink);
1170
1171         /* Free all snapshots of region */
1172         mutex_lock(&region->snapshot_lock);
1173         list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
1174                 devlink_region_snapshot_del(region, snapshot);
1175         mutex_unlock(&region->snapshot_lock);
1176
1177         list_del(&region->list);
1178         mutex_destroy(&region->snapshot_lock);
1179
1180         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
1181         kfree(region);
1182 }
1183 EXPORT_SYMBOL_GPL(devl_region_destroy);
1184
1185 /**
1186  *      devlink_region_destroy - destroy address region
1187  *
1188  *      @region: devlink region to destroy
1189  *
1190  *      Context: Takes and release devlink->lock <mutex>.
1191  */
1192 void devlink_region_destroy(struct devlink_region *region)
1193 {
1194         struct devlink *devlink = region->devlink;
1195
1196         devl_lock(devlink);
1197         devl_region_destroy(region);
1198         devl_unlock(devlink);
1199 }
1200 EXPORT_SYMBOL_GPL(devlink_region_destroy);
1201
1202 /**
1203  *      devlink_region_snapshot_id_get - get snapshot ID
1204  *
1205  *      This callback should be called when adding a new snapshot,
1206  *      Driver should use the same id for multiple snapshots taken
1207  *      on multiple regions at the same time/by the same trigger.
1208  *
1209  *      The caller of this function must use devlink_region_snapshot_id_put
1210  *      when finished creating regions using this id.
1211  *
1212  *      Returns zero on success, or a negative error code on failure.
1213  *
1214  *      @devlink: devlink
1215  *      @id: storage to return id
1216  */
1217 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
1218 {
1219         return __devlink_region_snapshot_id_get(devlink, id);
1220 }
1221 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
1222
1223 /**
1224  *      devlink_region_snapshot_id_put - put snapshot ID reference
1225  *
1226  *      This should be called by a driver after finishing creating snapshots
1227  *      with an id. Doing so ensures that the ID can later be released in the
1228  *      event that all snapshots using it have been destroyed.
1229  *
1230  *      @devlink: devlink
1231  *      @id: id to release reference on
1232  */
1233 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
1234 {
1235         __devlink_snapshot_id_decrement(devlink, id);
1236 }
1237 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
1238
1239 /**
1240  *      devlink_region_snapshot_create - create a new snapshot
1241  *      This will add a new snapshot of a region. The snapshot
1242  *      will be stored on the region struct and can be accessed
1243  *      from devlink. This is useful for future analyses of snapshots.
1244  *      Multiple snapshots can be created on a region.
1245  *      The @snapshot_id should be obtained using the getter function.
1246  *
1247  *      @region: devlink region of the snapshot
1248  *      @data: snapshot data
1249  *      @snapshot_id: snapshot id to be created
1250  */
1251 int devlink_region_snapshot_create(struct devlink_region *region,
1252                                    u8 *data, u32 snapshot_id)
1253 {
1254         int err;
1255
1256         mutex_lock(&region->snapshot_lock);
1257         err = __devlink_region_snapshot_create(region, data, snapshot_id);
1258         mutex_unlock(&region->snapshot_lock);
1259         return err;
1260 }
1261 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);