aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2021-11-03 10:06:12 +0100
committerIngo Molnar <mingo@kernel.org>2021-11-03 10:06:12 +0100
commitea79c24a30aa27ccc4aac26be33f8b73f3f1f59c (patch)
tree424aca63bb8ca6fc36c09ca0f9a0b6eebc9e7daf
parentcc0356d6a02e064387c16a83cb96fe43ef33181e (diff)
parentca7752caeaa70bd31d1714af566c9809688544af (diff)
downloadtip-ea79c24a30aa27ccc4aac26be33f8b73f3f1f59c.tar.gz
Merge branch 'timers/urgent'
Notice: this object is not reachable from any branch.
Notice: this object is not reachable from any branch.
-rw-r--r--include/linux/posix-timers.h2
-rw-r--r--kernel/fork.c1
-rw-r--r--kernel/time/posix-cpu-timers.c19
3 files changed, 20 insertions, 2 deletions
diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h
index 00fef0064355fe..5bbcd280bfd267 100644
--- a/include/linux/posix-timers.h
+++ b/include/linux/posix-timers.h
@@ -184,8 +184,10 @@ static inline void posix_cputimers_group_init(struct posix_cputimers *pct,
#endif
#ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK
+void clear_posix_cputimers_work(struct task_struct *p);
void posix_cputimers_init_work(void);
#else
+static inline void clear_posix_cputimers_work(struct task_struct *p) { }
static inline void posix_cputimers_init_work(void) { }
#endif
diff --git a/kernel/fork.c b/kernel/fork.c
index 8e9feeef555e7f..8269ae2e5d7c51 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2279,6 +2279,7 @@ static __latent_entropy struct task_struct *copy_process(
p->pdeath_signal = 0;
INIT_LIST_HEAD(&p->thread_group);
p->task_works = NULL;
+ clear_posix_cputimers_work(p);
#ifdef CONFIG_KRETPROBES
p->kretprobe_instances.first = NULL;
diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c
index 643d412ac6235e..96b4e78104266f 100644
--- a/kernel/time/posix-cpu-timers.c
+++ b/kernel/time/posix-cpu-timers.c
@@ -1159,13 +1159,28 @@ static void posix_cpu_timers_work(struct callback_head *work)
}
/*
+ * Clear existing posix CPU timers task work.
+ */
+void clear_posix_cputimers_work(struct task_struct *p)
+{
+ /*
+ * A copied work entry from the old task is not meaningful, clear it.
+ * N.B. init_task_work will not do this.
+ */
+ memset(&p->posix_cputimers_work.work, 0,
+ sizeof(p->posix_cputimers_work.work));
+ init_task_work(&p->posix_cputimers_work.work,
+ posix_cpu_timers_work);
+ p->posix_cputimers_work.scheduled = false;
+}
+
+/*
* Initialize posix CPU timers task work in init task. Out of line to
* keep the callback static and to avoid header recursion hell.
*/
void __init posix_cputimers_init_work(void)
{
- init_task_work(&current->posix_cputimers_work.work,
- posix_cpu_timers_work);
+ clear_posix_cputimers_work(current);
}
/*