From: Matthew Brost <matthew.brost@intel.com>
To: intel-xe@lists.freedesktop.org, dri-devel@lists.freedesktop.org,
linux-kernel@vger.kernel.org
Cc: tj@kernel.org, jiangshanlai@gmail.com, christian.koenig@amd.com,
ltuikov89@gmail.com, daniel@ffwll.ch
Subject: [PATCH v3 3/5] workqueue: Add interface for user-defined workqueue lockdep map
Date: Fri, 9 Aug 2024 15:28:25 -0700 [thread overview]
Message-ID: <20240809222827.3211998-4-matthew.brost@intel.com> (raw)
In-Reply-To: <20240809222827.3211998-1-matthew.brost@intel.com>
Add an interface for a user-defined workqueue lockdep map, which is
helpful when multiple workqueues are created for the same purpose. This
also helps avoid leaking lockdep maps on each workqueue creation.
v2:
- Add alloc_workqueue_lockdep_map (Tejun)
v3:
- Drop __WQ_USER_OWNED_LOCKDEP (Tejun)
- static inline alloc_ordered_workqueue_lockdep_map (Tejun)
Cc: Tejun Heo <tj@kernel.org>
Cc: Lai Jiangshan <jiangshanlai@gmail.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
---
include/linux/workqueue.h | 52 +++++++++++++++++++++++++++++++++++++++
kernel/workqueue.c | 28 +++++++++++++++++++++
2 files changed, 80 insertions(+)
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 4eb8f9563136..8ccbf510880b 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -507,6 +507,58 @@ void workqueue_softirq_dead(unsigned int cpu);
__printf(1, 4) struct workqueue_struct *
alloc_workqueue(const char *fmt, unsigned int flags, int max_active, ...);
+#ifdef CONFIG_LOCKDEP
+/**
+ * alloc_workqueue_lockdep_map - allocate a workqueue with user-defined lockdep_map
+ * @fmt: printf format for the name of the workqueue
+ * @flags: WQ_* flags
+ * @max_active: max in-flight work items, 0 for default
+ * @lockdep_map: user-defined lockdep_map
+ * @...: args for @fmt
+ *
+ * Same as alloc_workqueue but with the a user-define lockdep_map. Useful for
+ * workqueues created with the same purpose and to avoid leaking a lockdep_map
+ * on each workqueue creation.
+ *
+ * RETURNS:
+ * Pointer to the allocated workqueue on success, %NULL on failure.
+ */
+__printf(1, 5) struct workqueue_struct *
+alloc_workqueue_lockdep_map(const char *fmt, unsigned int flags, int max_active,
+ struct lockdep_map *lockdep_map, ...);
+
+/**
+ * alloc_ordered_workqueue_lockdep_map - allocate an ordered workqueue with
+ * user-defined lockdep_map
+ *
+ * @fmt: printf format for the name of the workqueue
+ * @flags: WQ_* flags (only WQ_FREEZABLE and WQ_MEM_RECLAIM are meaningful)
+ * @lockdep_map: user-defined lockdep_map
+ * @args: args for @fmt
+ *
+ * Same as alloc_ordered_workqueue but with the a user-define lockdep_map.
+ * Useful for workqueues created with the same purpose and to avoid leaking a
+ * lockdep_map on each workqueue creation.
+ *
+ * RETURNS:
+ * Pointer to the allocated workqueue on success, %NULL on failure.
+ */
+__printf(1, 4) static inline struct workqueue_struct *
+alloc_ordered_workqueue_lockdep_map(const char *fmt, unsigned int flags,
+ struct lockdep_map *lockdep_map, ...)
+{
+ struct workqueue_struct *wq;
+ va_list args;
+
+ va_start(args, lockdep_map);
+ wq = alloc_workqueue_lockdep_map(fmt, WQ_UNBOUND | __WQ_ORDERED | flags,
+ 1, lockdep_map, args);
+ va_end(args);
+
+ return wq;
+}
+#endif
+
/**
* alloc_ordered_workqueue - allocate an ordered workqueue
* @fmt: printf format for the name of the workqueue
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 24df85589dc0..f4b50a995e99 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -4775,11 +4775,17 @@ static void wq_init_lockdep(struct workqueue_struct *wq)
static void wq_unregister_lockdep(struct workqueue_struct *wq)
{
+ if (wq->lockdep_map != &wq->__lockdep_map)
+ return;
+
lockdep_unregister_key(&wq->key);
}
static void wq_free_lockdep(struct workqueue_struct *wq)
{
+ if (wq->lockdep_map != &wq->__lockdep_map)
+ return;
+
if (wq->lock_name != wq->name)
kfree(wq->lock_name);
}
@@ -5756,6 +5762,28 @@ struct workqueue_struct *alloc_workqueue(const char *fmt,
}
EXPORT_SYMBOL_GPL(alloc_workqueue);
+#ifdef CONFIG_LOCKDEP
+__printf(1, 5)
+struct workqueue_struct *
+alloc_workqueue_lockdep_map(const char *fmt, unsigned int flags,
+ int max_active, struct lockdep_map *lockdep_map, ...)
+{
+ struct workqueue_struct *wq;
+ va_list args;
+
+ va_start(args, lockdep_map);
+ wq = __alloc_workqueue(fmt, flags, max_active, args);
+ va_end(args);
+ if (!wq)
+ return NULL;
+
+ wq->lockdep_map = lockdep_map;
+
+ return wq;
+}
+EXPORT_SYMBOL_GPL(alloc_workqueue_lockdep_map);
+#endif
+
static bool pwq_busy(struct pool_workqueue *pwq)
{
int i;
--
2.34.1
next prev parent reply other threads:[~2024-08-09 22:27 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-09 22:28 [PATCH v3 0/5] Use user-defined workqueue lockdep map for drm sched Matthew Brost
2024-08-09 22:28 ` [PATCH v3 1/5] workqueue: Split alloc_workqueue into internal function and lockdep init Matthew Brost
2024-08-13 6:13 ` kernel test robot
2024-08-09 22:28 ` [PATCH v3 2/5] workqueue: Change workqueue lockdep map to pointer Matthew Brost
2024-08-09 22:28 ` Matthew Brost [this message]
2024-08-12 5:03 ` [PATCH v3 3/5] workqueue: Add interface for user-defined workqueue lockdep map Ghimiray, Himal Prasad
2024-08-13 18:52 ` Tejun Heo
2024-08-13 18:55 ` Matthew Brost
2024-08-13 19:05 ` Tejun Heo
2024-08-13 19:06 ` Tejun Heo
2024-08-09 22:28 ` [PATCH v3 4/5] drm/sched: Use drm sched lockdep map for submit_wq Matthew Brost
2024-08-12 5:35 ` Ghimiray, Himal Prasad
2024-08-13 19:16 ` Matthew Brost
2024-08-19 8:11 ` Ghimiray, Himal Prasad
2024-08-09 22:28 ` [PATCH v3 5/5] drm/xe: Drop GuC submit_wq pool Matthew Brost
2024-08-09 23:07 ` ✓ CI.Patch_applied: success for Use user-defined workqueue lockdep map for drm sched (rev3) Patchwork
2024-08-09 23:08 ` ✓ CI.checkpatch: " Patchwork
2024-08-09 23:09 ` ✓ CI.KUnit: " Patchwork
2024-08-09 23:20 ` ✓ CI.Build: " Patchwork
2024-08-09 23:23 ` ✓ CI.Hooks: " Patchwork
2024-08-09 23:24 ` ✗ CI.checksparse: warning " Patchwork
2024-08-09 23:55 ` ✗ CI.BAT: failure " Patchwork
2024-08-10 2:53 ` ✗ CI.FULL: " Patchwork
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240809222827.3211998-4-matthew.brost@intel.com \
--to=matthew.brost@intel.com \
--cc=christian.koenig@amd.com \
--cc=daniel@ffwll.ch \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jiangshanlai@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=ltuikov89@gmail.com \
--cc=tj@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.