]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
net: page_pool: add netlink notifications for state changes
authorJakub Kicinski <kuba@kernel.org>
Sun, 26 Nov 2023 23:07:35 +0000 (15:07 -0800)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 28 Nov 2023 14:48:39 +0000 (15:48 +0100)
Generate netlink notifications about page pool state changes.

Reviewed-by: Eric Dumazet <edumazet@google.com>
Acked-by: Jesper Dangaard Brouer <hawk@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/netlink/specs/netdev.yaml
include/uapi/linux/netdev.h
net/core/netdev-genl-gen.c
net/core/netdev-genl-gen.h
net/core/page_pool_user.c

index 84ca3c2ab872dd4c24875639d0cf8bc1e3187364..82fbe81f7a49815e2cfc528bc0c6f3bb32cd521a 100644 (file)
@@ -166,8 +166,28 @@ operations:
       dump:
         reply: *pp-reply
       config-cond: page-pool
+    -
+      name: page-pool-add-ntf
+      doc: Notification about page pool appearing.
+      notify: page-pool-get
+      mcgrp: page-pool
+      config-cond: page-pool
+    -
+      name: page-pool-del-ntf
+      doc: Notification about page pool disappearing.
+      notify: page-pool-get
+      mcgrp: page-pool
+      config-cond: page-pool
+    -
+      name: page-pool-change-ntf
+      doc: Notification about page pool configuration being changed.
+      notify: page-pool-get
+      mcgrp: page-pool
+      config-cond: page-pool
 
 mcast-groups:
   list:
     -
       name: mgmt
+    -
+      name: page-pool
index 176665bcf0da105847c709875f9e57d73d6268e9..beb1588722267202030fc5317389038f28d57021 100644 (file)
@@ -79,11 +79,15 @@ enum {
        NETDEV_CMD_DEV_DEL_NTF,
        NETDEV_CMD_DEV_CHANGE_NTF,
        NETDEV_CMD_PAGE_POOL_GET,
+       NETDEV_CMD_PAGE_POOL_ADD_NTF,
+       NETDEV_CMD_PAGE_POOL_DEL_NTF,
+       NETDEV_CMD_PAGE_POOL_CHANGE_NTF,
 
        __NETDEV_CMD_MAX,
        NETDEV_CMD_MAX = (__NETDEV_CMD_MAX - 1)
 };
 
 #define NETDEV_MCGRP_MGMT      "mgmt"
+#define NETDEV_MCGRP_PAGE_POOL "page-pool"
 
 #endif /* _UAPI_LINUX_NETDEV_H */
index bfde13981c770108e4f05e12edd4a0f02029075b..47fb5e1b636987db76cade604f14f0819ec65af9 100644 (file)
@@ -60,6 +60,7 @@ static const struct genl_split_ops netdev_nl_ops[] = {
 
 static const struct genl_multicast_group netdev_nl_mcgrps[] = {
        [NETDEV_NLGRP_MGMT] = { "mgmt", },
+       [NETDEV_NLGRP_PAGE_POOL] = { "page-pool", },
 };
 
 struct genl_family netdev_nl_family __ro_after_init = {
index a011d12abff43f2cb8c269b73a65895875eac1f4..7380978471008e285d4e265001627eb7a0bc4fc8 100644 (file)
@@ -19,6 +19,7 @@ int netdev_nl_page_pool_get_dumpit(struct sk_buff *skb,
 
 enum {
        NETDEV_NLGRP_MGMT,
+       NETDEV_NLGRP_PAGE_POOL,
 };
 
 extern struct genl_family netdev_nl_family;
index 7eb37c31fce94db6497f683d4ae58016a6053c09..1577fef880c95329f4e2664a1d400c2b71632a34 100644 (file)
@@ -135,6 +135,37 @@ err_cancel:
        return -EMSGSIZE;
 }
 
+static void netdev_nl_page_pool_event(const struct page_pool *pool, u32 cmd)
+{
+       struct genl_info info;
+       struct sk_buff *ntf;
+       struct net *net;
+
+       lockdep_assert_held(&page_pools_lock);
+
+       /* 'invisible' page pools don't matter */
+       if (hlist_unhashed(&pool->user.list))
+               return;
+       net = dev_net(pool->slow.netdev);
+
+       if (!genl_has_listeners(&netdev_nl_family, net, NETDEV_NLGRP_PAGE_POOL))
+               return;
+
+       genl_info_init_ntf(&info, &netdev_nl_family, cmd);
+
+       ntf = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
+       if (!ntf)
+               return;
+
+       if (page_pool_nl_fill(ntf, pool, &info)) {
+               nlmsg_free(ntf);
+               return;
+       }
+
+       genlmsg_multicast_netns(&netdev_nl_family, net, ntf,
+                               0, NETDEV_NLGRP_PAGE_POOL, GFP_KERNEL);
+}
+
 int netdev_nl_page_pool_get_doit(struct sk_buff *skb, struct genl_info *info)
 {
        u32 id;
@@ -168,6 +199,8 @@ int page_pool_list(struct page_pool *pool)
                hlist_add_head(&pool->user.list,
                               &pool->slow.netdev->page_pools);
                pool->user.napi_id = pool->p.napi ? pool->p.napi->napi_id : 0;
+
+               netdev_nl_page_pool_event(pool, NETDEV_CMD_PAGE_POOL_ADD_NTF);
        }
 
        mutex_unlock(&page_pools_lock);
@@ -181,6 +214,7 @@ err_unlock:
 void page_pool_unlist(struct page_pool *pool)
 {
        mutex_lock(&page_pools_lock);
+       netdev_nl_page_pool_event(pool, NETDEV_CMD_PAGE_POOL_DEL_NTF);
        xa_erase(&page_pools, pool->user.id);
        hlist_del(&pool->user.list);
        mutex_unlock(&page_pools_lock);
@@ -210,6 +244,8 @@ static void page_pool_unreg_netdev(struct net_device *netdev)
        last = NULL;
        hlist_for_each_entry(pool, &netdev->page_pools, user.list) {
                pool->slow.netdev = lo;
+               netdev_nl_page_pool_event(pool,
+                                         NETDEV_CMD_PAGE_POOL_CHANGE_NTF);
                last = pool;
        }
        if (last)