Commit fda6add9 authored by Kent Overstreet's avatar Kent Overstreet Committed by Tejun Heo
Browse files

workqueue: Basic memory allocation profiling support



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: default avatarKent Overstreet <kent.overstreet@linux.dev>
Signed-off-by: default avatarTejun Heo <tj@kernel.org>
parent 0998f0ac
Loading
Loading
Loading
Loading
+8 −4
Original line number Diff line number Diff line
@@ -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);
+7 −7
Original line number Diff line number Diff line
@@ -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,7 +5774,7 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt,
}

__printf(1, 4)
struct workqueue_struct *alloc_workqueue(const char *fmt,
struct workqueue_struct *alloc_workqueue_noprof(const char *fmt,
						unsigned int flags,
						int max_active, ...)
{
@@ -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)