]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
macsec: introduce dedicated workqueue for SA crypto cleanup
authorJinliang Zheng <alexjlzheng@tencent.com>
Mon, 11 May 2026 15:30:58 +0000 (23:30 +0800)
committerJakub Kicinski <kuba@kernel.org>
Thu, 14 May 2026 02:03:05 +0000 (19:03 -0700)
Introduce a dedicated ordered workqueue, macsec_wq, which will be used
by subsequent patches to defer SA crypto cleanup (crypto_free_aead and
related teardown) out of softirq context.

Using a dedicated workqueue instead of system_wq allows macsec_exit()
to drain exactly the work items belonging to this module via
destroy_workqueue(), without interfering with unrelated work items on
system_wq or causing unexpected delays elsewhere.

rcu_barrier() in macsec_exit() ensures all in-flight rcu_work callbacks
have enqueued their work items before destroy_workqueue() drains and
destroys the queue, making the two-step teardown correct and complete.
The same sequence is kept in the error path of macsec_init() as a
precaution, to mirror macsec_exit() and stay safe if work ever becomes
queueable before this point in the future.

While at it, rename the error labels in macsec_init() from the
resource-named style (rtnl:, notifier:, wq:) to the err_xxx: style
(err_rtnl:, err_notifier:, err_destroy_wq:) to align with the broader
kernel convention.

Signed-off-by: Jinliang Zheng <alexjlzheng@tencent.com>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Link: https://patch.msgid.link/20260511153102.2640368-2-alexjlzheng@tencent.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/macsec.c

index 6147ee8b1d78b12136e2178336dacfaae1570aa0..ef5ac634f9163da72060dbbf0134dc4fea59fbed 100644 (file)
@@ -26,6 +26,8 @@
 
 #include <uapi/linux/if_macsec.h>
 
+static struct workqueue_struct *macsec_wq;
+
 /* SecTAG length = macsec_eth_header without the optional SCI */
 #define MACSEC_TAG_LEN 6
 
@@ -4505,25 +4507,35 @@ static int __init macsec_init(void)
 {
        int err;
 
+       macsec_wq = alloc_workqueue("macsec", WQ_UNBOUND, 0);
+       if (!macsec_wq)
+               return -ENOMEM;
+
        pr_info("MACsec IEEE 802.1AE\n");
        err = register_netdevice_notifier(&macsec_notifier);
        if (err)
-               return err;
+               goto err_destroy_wq;
 
        err = rtnl_link_register(&macsec_link_ops);
        if (err)
-               goto notifier;
+               goto err_notifier;
 
        err = genl_register_family(&macsec_fam);
        if (err)
-               goto rtnl;
+               goto err_rtnl;
 
        return 0;
 
-rtnl:
+err_rtnl:
        rtnl_link_unregister(&macsec_link_ops);
-notifier:
+err_notifier:
        unregister_netdevice_notifier(&macsec_notifier);
+err_destroy_wq:
+       /* Precautionary, mirrors macsec_exit() to stay safe if work
+        * ever becomes queueable before this point in the future.
+        */
+       rcu_barrier();
+       destroy_workqueue(macsec_wq);
        return err;
 }
 
@@ -4533,6 +4545,7 @@ static void __exit macsec_exit(void)
        rtnl_link_unregister(&macsec_link_ops);
        unregister_netdevice_notifier(&macsec_notifier);
        rcu_barrier();
+       destroy_workqueue(macsec_wq);
 }
 
 module_init(macsec_init);