]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
workqueue: Basic memory allocation profiling support
authorKent Overstreet <kent.overstreet@linux.dev>
Mon, 16 Jun 2025 17:59:20 +0000 (13:59 -0400)
committerTejun Heo <tj@kernel.org>
Mon, 16 Jun 2025 18:01:45 +0000 (08:01 -1000)
Hook alloc_workqueue and alloc_workqueue_attrs() so that they're
accounted to the callsite. Since we're doing allocations on behalf of
another subsystem, this helps when using memory allocation profiling to
check for leaks.

Cc: Tejun Heo <tj@kernel.org>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: Tejun Heo <tj@kernel.org>
include/linux/workqueue.h
kernel/workqueue.c

index 6e30f275da77eac24043a277cc8f8d9506e38830..e907c9bb840c4c84145bc0c86862d56278006b5c 100644 (file)
@@ -6,6 +6,7 @@
 #ifndef _LINUX_WORKQUEUE_H
 #define _LINUX_WORKQUEUE_H
 
+#include <linux/alloc_tag.h>
 #include <linux/timer.h>
 #include <linux/linkage.h>
 #include <linux/bitops.h>
@@ -505,7 +506,8 @@ void workqueue_softirq_dead(unsigned int cpu);
  * Pointer to the allocated workqueue on success, %NULL on failure.
  */
 __printf(1, 4) struct workqueue_struct *
-alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...);
+alloc_workqueue_noprof(const char *fmt, unsigned int flags, int max_active, ...);
+#define alloc_workqueue(...)   alloc_hooks(alloc_workqueue_noprof(__VA_ARGS__))
 
 #ifdef CONFIG_LOCKDEP
 /**
@@ -544,8 +546,8 @@ alloc_workqueue_lockdep_map(const char *fmt, unsigned int flags, int max_active,
  * Pointer to the allocated workqueue on success, %NULL on failure.
  */
 #define alloc_ordered_workqueue_lockdep_map(fmt, flags, lockdep_map, args...)  \
-       alloc_workqueue_lockdep_map(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags),   \
-                                   1, lockdep_map, ##args)
+       alloc_hooks(alloc_workqueue_lockdep_map(fmt, WQ_UNBOUND | __WQ_ORDERED | (flags),\
+                                               1, lockdep_map, ##args))
 #endif
 
 /**
@@ -577,7 +579,9 @@ alloc_workqueue_lockdep_map(const char *fmt, unsigned int flags, int max_active,
 
 extern void destroy_workqueue(struct workqueue_struct *wq);
 
-struct workqueue_attrs *alloc_workqueue_attrs(void);
+struct workqueue_attrs *alloc_workqueue_attrs_noprof(void);
+#define alloc_workqueue_attrs(...)     alloc_hooks(alloc_workqueue_attrs_noprof(__VA_ARGS__))
+
 void free_workqueue_attrs(struct workqueue_attrs *attrs);
 int apply_workqueue_attrs(struct workqueue_struct *wq,
                          const struct workqueue_attrs *attrs);
index d9de0f2a2e0063b2efd14c37390a172b8e2e591c..c24844afaa9851c553c5dd82f2aa178a2b0d7446 100644 (file)
@@ -4626,7 +4626,7 @@ void free_workqueue_attrs(struct workqueue_attrs *attrs)
  *
  * Return: The allocated new workqueue_attr on success. %NULL on failure.
  */
-struct workqueue_attrs *alloc_workqueue_attrs(void)
+struct workqueue_attrs *alloc_workqueue_attrs_noprof(void)
 {
        struct workqueue_attrs *attrs;
 
@@ -5679,12 +5679,12 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt,
        else
                wq_size = sizeof(*wq);
 
-       wq = kzalloc(wq_size, GFP_KERNEL);
+       wq = kzalloc_noprof(wq_size, GFP_KERNEL);
        if (!wq)
                return NULL;
 
        if (flags & WQ_UNBOUND) {
-               wq->unbound_attrs = alloc_workqueue_attrs();
+               wq->unbound_attrs = alloc_workqueue_attrs_noprof();
                if (!wq->unbound_attrs)
                        goto err_free_wq;
        }
@@ -5774,9 +5774,9 @@ err_destroy:
 }
 
 __printf(1, 4)
-struct workqueue_struct *alloc_workqueue(const char *fmt,
-                                        unsigned int flags,
-                                        int max_active, ...)
+struct workqueue_struct *alloc_workqueue_noprof(const char *fmt,
+                                               unsigned int flags,
+                                               int max_active, ...)
 {
        struct workqueue_struct *wq;
        va_list args;
@@ -5791,7 +5791,7 @@ struct workqueue_struct *alloc_workqueue(const char *fmt,
 
        return wq;
 }
-EXPORT_SYMBOL_GPL(alloc_workqueue);
+EXPORT_SYMBOL_GPL(alloc_workqueue_noprof);
 
 #ifdef CONFIG_LOCKDEP
 __printf(1, 5)