Re: Increase priority of a workqueue thread ?

From: Con Kolivas
Date: Thu Oct 20 2005 - 10:05:42 EST


On Thu, 20 Oct 2005 23:12, Block Device wrote:
> Hi,
> I am using a custom workqueue thread in my module. How do I increase
> the priority of the workqueue threads ?
> I've seen that each workqueue contains an array of per-cpu structures
> which has a
> task_struct of the thread on a particular cpu. Since these threads are
> created from keventd
> I think they'll have the same priority as keventd. Also the per-cpu
> structure is something which is private to the workqueue
> implementation. Directly using it (from my driver) to increase the
> priority of the workqueue doesnt seem correct to me. Is there any
> interface or standard way of changing the priority of a workqueue.

By strange coincidence I was working on a patch to do this. Here's what I have
so far - I know the code is safe but I don't know if it does as advertised
yet ;)

Cheers,
Con
Index: linux-2.6.14-rc4-ck1/include/linux/workqueue.h
===================================================================
--- linux-2.6.14-rc4-ck1.orig/include/linux/workqueue.h 2005-06-18 23:59:46.000000000 +1000
+++ linux-2.6.14-rc4-ck1/include/linux/workqueue.h 2005-10-11 16:03:09.000000000 +1000
@@ -56,6 +56,7 @@ extern struct workqueue_struct *__create
#define create_singlethread_workqueue(name) __create_workqueue((name), 1)

extern void destroy_workqueue(struct workqueue_struct *wq);
+extern void set_workqueue_nice(struct workqueue_struct *wq, long nice);

extern int FASTCALL(queue_work(struct workqueue_struct *wq, struct work_struct *work));
extern int FASTCALL(queue_delayed_work(struct workqueue_struct *wq, struct work_struct *work, unsigned long delay));
Index: linux-2.6.14-rc4-ck1/kernel/workqueue.c
===================================================================
--- linux-2.6.14-rc4-ck1.orig/kernel/workqueue.c 2005-10-11 15:56:13.000000000 +1000
+++ linux-2.6.14-rc4-ck1/kernel/workqueue.c 2005-10-11 16:03:09.000000000 +1000
@@ -383,6 +383,26 @@ void destroy_workqueue(struct workqueue_
kfree(wq);
}

+void set_workqueue_nice(struct workqueue_struct *wq, long nice)
+{
+ struct task_struct *p;
+ int cpu;
+
+ lock_cpu_hotplug();
+ if (is_single_threaded(wq)) {
+ p = wq->cpu_wq->thread;
+ set_user_nice(p, nice);
+ } else {
+ for_each_online_cpu(cpu) {
+ struct cpu_workqueue_struct *cwq = wq->cpu_wq + cpu;
+
+ p = cwq->thread;
+ set_user_nice(p, nice);
+ }
+ }
+ unlock_cpu_hotplug();
+}
+
static struct workqueue_struct *keventd_wq;

int fastcall schedule_work(struct work_struct *work)