]> git.baikalelectronics.ru Git - kernel.git/commitdiff
devlink: Add API to register packet trap groups
authorIdo Schimmel <idosch@mellanox.com>
Sun, 22 Mar 2020 18:48:26 +0000 (20:48 +0200)
committerDavid S. Miller <davem@davemloft.net>
Tue, 24 Mar 2020 04:40:40 +0000 (21:40 -0700)
Currently, packet trap groups are implicitly registered by drivers upon
packet trap registration. When the traps are registered, each is
associated with a group and the group is created by devlink, if it does
not exist already.

This makes it difficult for drivers to pass additional attributes for
the groups.

Therefore, as a preparation for future patches that require passing
additional group attributes, add an API to explicitly register /
unregister these groups.

Next patches will convert existing drivers to use this API.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/devlink.h
net/core/devlink.c

index e68781b9b7d4eed06bac8f1ca0f654f5099f66a6..f8bdf43f694c97084940b64626ee8ae3cef9c246 100644 (file)
@@ -1057,6 +1057,12 @@ void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
                         void *trap_ctx, struct devlink_port *in_devlink_port,
                         const struct flow_action_cookie *fa_cookie);
 void *devlink_trap_ctx_priv(void *trap_ctx);
+int devlink_trap_groups_register(struct devlink *devlink,
+                                const struct devlink_trap_group *groups,
+                                size_t groups_count);
+void devlink_trap_groups_unregister(struct devlink *devlink,
+                                   const struct devlink_trap_group *groups,
+                                   size_t groups_count);
 
 #if IS_ENABLED(CONFIG_NET_DEVLINK)
 
index f51bebc8c33ffbeaa7e5cb17669517ac86c83349..089a220aabab38a87800f5ab55a5df838fc45378 100644 (file)
@@ -8278,6 +8278,123 @@ void *devlink_trap_ctx_priv(void *trap_ctx)
 }
 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
 
+static int
+devlink_trap_group_register(struct devlink *devlink,
+                           const struct devlink_trap_group *group)
+{
+       struct devlink_trap_group_item *group_item;
+       int err;
+
+       if (devlink_trap_group_item_lookup(devlink, group->name))
+               return -EEXIST;
+
+       group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
+       if (!group_item)
+               return -ENOMEM;
+
+       group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
+       if (!group_item->stats) {
+               err = -ENOMEM;
+               goto err_stats_alloc;
+       }
+
+       group_item->group = group;
+       refcount_set(&group_item->refcount, 1);
+
+       if (devlink->ops->trap_group_init) {
+               err = devlink->ops->trap_group_init(devlink, group);
+               if (err)
+                       goto err_group_init;
+       }
+
+       list_add_tail(&group_item->list, &devlink->trap_group_list);
+       devlink_trap_group_notify(devlink, group_item,
+                                 DEVLINK_CMD_TRAP_GROUP_NEW);
+
+       return 0;
+
+err_group_init:
+       free_percpu(group_item->stats);
+err_stats_alloc:
+       kfree(group_item);
+       return err;
+}
+
+static void
+devlink_trap_group_unregister(struct devlink *devlink,
+                             const struct devlink_trap_group *group)
+{
+       struct devlink_trap_group_item *group_item;
+
+       group_item = devlink_trap_group_item_lookup(devlink, group->name);
+       if (WARN_ON_ONCE(!group_item))
+               return;
+
+       devlink_trap_group_notify(devlink, group_item,
+                                 DEVLINK_CMD_TRAP_GROUP_DEL);
+       list_del(&group_item->list);
+       free_percpu(group_item->stats);
+       kfree(group_item);
+}
+
+/**
+ * devlink_trap_groups_register - Register packet trap groups with devlink.
+ * @devlink: devlink.
+ * @groups: Packet trap groups.
+ * @groups_count: Count of provided packet trap groups.
+ *
+ * Return: Non-zero value on failure.
+ */
+int devlink_trap_groups_register(struct devlink *devlink,
+                                const struct devlink_trap_group *groups,
+                                size_t groups_count)
+{
+       int i, err;
+
+       mutex_lock(&devlink->lock);
+       for (i = 0; i < groups_count; i++) {
+               const struct devlink_trap_group *group = &groups[i];
+
+               err = devlink_trap_group_verify(group);
+               if (err)
+                       goto err_trap_group_verify;
+
+               err = devlink_trap_group_register(devlink, group);
+               if (err)
+                       goto err_trap_group_register;
+       }
+       mutex_unlock(&devlink->lock);
+
+       return 0;
+
+err_trap_group_register:
+err_trap_group_verify:
+       for (i--; i >= 0; i--)
+               devlink_trap_group_unregister(devlink, &groups[i]);
+       mutex_unlock(&devlink->lock);
+       return err;
+}
+EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
+
+/**
+ * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
+ * @devlink: devlink.
+ * @groups: Packet trap groups.
+ * @groups_count: Count of provided packet trap groups.
+ */
+void devlink_trap_groups_unregister(struct devlink *devlink,
+                                   const struct devlink_trap_group *groups,
+                                   size_t groups_count)
+{
+       int i;
+
+       mutex_lock(&devlink->lock);
+       for (i = groups_count - 1; i >= 0; i--)
+               devlink_trap_group_unregister(devlink, &groups[i]);
+       mutex_unlock(&devlink->lock);
+}
+EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
+
 static void __devlink_compat_running_version(struct devlink *devlink,
                                             char *buf, size_t len)
 {