Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

workqueue: introduce create_rt_workqueue

create_rt_workqueue will create a real time prioritized workqueue.
This is needed for the conversion of stop_machine to a workqueue based
implementation.
This patch adds yet another parameter to __create_workqueue_key to tell
it that we want an rt workqueue.
However it looks like we rather should have something like "int type"
instead of singlethread, freezable and rt.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Cc: Ingo Molnar <mingo@elte.hu>

authored by

Heiko Carstens and committed by
Rusty Russell
0d557dc9 a802dd0e

+16 -9
+10 -8
include/linux/workqueue.h
··· 149 149 150 150 extern struct workqueue_struct * 151 151 __create_workqueue_key(const char *name, int singlethread, 152 - int freezeable, struct lock_class_key *key, 152 + int freezeable, int rt, struct lock_class_key *key, 153 153 const char *lock_name); 154 154 155 155 #ifdef CONFIG_LOCKDEP 156 - #define __create_workqueue(name, singlethread, freezeable) \ 156 + #define __create_workqueue(name, singlethread, freezeable, rt) \ 157 157 ({ \ 158 158 static struct lock_class_key __key; \ 159 159 const char *__lock_name; \ ··· 164 164 __lock_name = #name; \ 165 165 \ 166 166 __create_workqueue_key((name), (singlethread), \ 167 - (freezeable), &__key, \ 167 + (freezeable), (rt), &__key, \ 168 168 __lock_name); \ 169 169 }) 170 170 #else 171 - #define __create_workqueue(name, singlethread, freezeable) \ 172 - __create_workqueue_key((name), (singlethread), (freezeable), NULL, NULL) 171 + #define __create_workqueue(name, singlethread, freezeable, rt) \ 172 + __create_workqueue_key((name), (singlethread), (freezeable), (rt), \ 173 + NULL, NULL) 173 174 #endif 174 175 175 - #define create_workqueue(name) __create_workqueue((name), 0, 0) 176 - #define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1) 177 - #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0) 176 + #define create_workqueue(name) __create_workqueue((name), 0, 0, 0) 177 + #define create_rt_workqueue(name) __create_workqueue((name), 0, 0, 1) 178 + #define create_freezeable_workqueue(name) __create_workqueue((name), 1, 1, 0) 179 + #define create_singlethread_workqueue(name) __create_workqueue((name), 1, 0, 0) 178 180 179 181 extern void destroy_workqueue(struct workqueue_struct *wq); 180 182
+6 -1
kernel/workqueue.c
··· 62 62 const char *name; 63 63 int singlethread; 64 64 int freezeable; /* Freeze threads during suspend */ 65 + int rt; 65 66 #ifdef CONFIG_LOCKDEP 66 67 struct lockdep_map lockdep_map; 67 68 #endif ··· 767 766 768 767 static int create_workqueue_thread(struct cpu_workqueue_struct *cwq, int cpu) 769 768 { 769 + struct sched_param param = { .sched_priority = MAX_RT_PRIO-1 }; 770 770 struct workqueue_struct *wq = cwq->wq; 771 771 const char *fmt = is_single_threaded(wq) ? "%s" : "%s/%d"; 772 772 struct task_struct *p; ··· 783 781 */ 784 782 if (IS_ERR(p)) 785 783 return PTR_ERR(p); 786 - 784 + if (cwq->wq->rt) 785 + sched_setscheduler_nocheck(p, SCHED_FIFO, &param); 787 786 cwq->thread = p; 788 787 789 788 return 0; ··· 804 801 struct workqueue_struct *__create_workqueue_key(const char *name, 805 802 int singlethread, 806 803 int freezeable, 804 + int rt, 807 805 struct lock_class_key *key, 808 806 const char *lock_name) 809 807 { ··· 826 822 lockdep_init_map(&wq->lockdep_map, lock_name, key, 0); 827 823 wq->singlethread = singlethread; 828 824 wq->freezeable = freezeable; 825 + wq->rt = rt; 829 826 INIT_LIST_HEAD(&wq->list); 830 827 831 828 if (singlethread) {