[PATCH 1/2] workqueue: Add a helper to identify current workqueue

From: Benjamin Coddington
Date: Mon Jul 07 2025 - 14:46:39 EST


Introduce a new helper current_workqueue() which returns the current task's
workqueue pointer or NULL if not a workqueue worker.

This will allow the NFS client to recognize the case where writeback occurs
within the nfsiod workqueue or is being submitted directly. NFS would like
to change the GFP_ flags for memory allocation to avoid stalls or cycles in
memory pools based on which context writeback is occurring. In a following
patch, this helper detects the case rather than checking the PF_WQ_WORKER
flag which can be passed along from another workqueue worker.

Signed-off-by: Benjamin Coddington <bcodding@xxxxxxxxxx>
---
include/linux/workqueue.h | 1 +
kernel/workqueue.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+)

diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 6e30f275da77..29e1096e6dfa 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -623,6 +623,7 @@ extern void workqueue_set_max_active(struct workqueue_struct *wq,
extern void workqueue_set_min_active(struct workqueue_struct *wq,
int min_active);
extern struct work_struct *current_work(void);
+extern struct workqueue_struct *current_workqueue(void);
extern bool current_is_workqueue_rescuer(void);
extern bool workqueue_congested(int cpu, struct workqueue_struct *wq);
extern unsigned int work_busy(struct work_struct *work);
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 9f9148075828..a96eb209d5e0 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -6009,6 +6009,24 @@ struct work_struct *current_work(void)
}
EXPORT_SYMBOL(current_work);

+/**
+ * current_workqueue - retrieve %current task's work queue
+ *
+ * Determine if %current task is a workqueue worker and what workqueue it's
+ * working on. Useful to find out the context that the %current task is
+ * running in.
+ *
+ * Return: workqueue_struct if %current task is a workqueue worker, %NULL
+ * otherwise.
+ */
+struct workqueue_struct *current_workqueue(void)
+{
+ struct worker *worker = current_wq_worker();
+
+ return worker ? worker->current_pwq->wq : NULL;
+}
+EXPORT_SYMBOL(current_workqueue);
+
/**
* current_is_workqueue_rescuer - is %current workqueue rescuer?
*
--
2.47.0