Merge tag 'timers-urgent-2021-11-14' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull timer fix from Thomas Gleixner:
"A single fix for POSIX CPU timers to address a problem where POSIX CPU
timer delivery stops working for a new child task because
copy_process() copies state information which is only valid for the
parent task"

* tag 'timers-urgent-2021-11-14' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
posix-cpu-timers: Clear task::posix_cputimers_work in copy_process()

+20 -2
+2
include/linux/posix-timers.h
··· 184 #endif 185 186 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK 187 void posix_cputimers_init_work(void); 188 #else 189 static inline void posix_cputimers_init_work(void) { } 190 #endif 191
··· 184 #endif 185 186 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK 187 + void clear_posix_cputimers_work(struct task_struct *p); 188 void posix_cputimers_init_work(void); 189 #else 190 + static inline void clear_posix_cputimers_work(struct task_struct *p) { } 191 static inline void posix_cputimers_init_work(void) { } 192 #endif 193
+1
kernel/fork.c
··· 2277 p->pdeath_signal = 0; 2278 INIT_LIST_HEAD(&p->thread_group); 2279 p->task_works = NULL; 2280 2281 #ifdef CONFIG_KRETPROBES 2282 p->kretprobe_instances.first = NULL;
··· 2277 p->pdeath_signal = 0; 2278 INIT_LIST_HEAD(&p->thread_group); 2279 p->task_works = NULL; 2280 + clear_posix_cputimers_work(p); 2281 2282 #ifdef CONFIG_KRETPROBES 2283 p->kretprobe_instances.first = NULL;
+17 -2
kernel/time/posix-cpu-timers.c
··· 1159 } 1160 1161 /* 1162 * Initialize posix CPU timers task work in init task. Out of line to 1163 * keep the callback static and to avoid header recursion hell. 1164 */ 1165 void __init posix_cputimers_init_work(void) 1166 { 1167 - init_task_work(&current->posix_cputimers_work.work, 1168 - posix_cpu_timers_work); 1169 } 1170 1171 /*
··· 1159 } 1160 1161 /* 1162 + * Clear existing posix CPU timers task work. 1163 + */ 1164 + void clear_posix_cputimers_work(struct task_struct *p) 1165 + { 1166 + /* 1167 + * A copied work entry from the old task is not meaningful, clear it. 1168 + * N.B. init_task_work will not do this. 1169 + */ 1170 + memset(&p->posix_cputimers_work.work, 0, 1171 + sizeof(p->posix_cputimers_work.work)); 1172 + init_task_work(&p->posix_cputimers_work.work, 1173 + posix_cpu_timers_work); 1174 + p->posix_cputimers_work.scheduled = false; 1175 + } 1176 + 1177 + /* 1178 * Initialize posix CPU timers task work in init task. Out of line to 1179 * keep the callback static and to avoid header recursion hell. 1180 */ 1181 void __init posix_cputimers_init_work(void) 1182 { 1183 + clear_posix_cputimers_work(current); 1184 } 1185 1186 /*