diff options
Diffstat (limited to 'kernel/time')
| -rw-r--r-- | kernel/time/posix-timers.c | 19 | ||||
| -rw-r--r-- | kernel/time/tick-sched.c | 1 | 
2 files changed, 14 insertions, 6 deletions
| diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 1cd10b102c51..5dead89308b7 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1051,15 +1051,24 @@ retry_delete:  }  /* - * This is called by do_exit or de_thread, only when there are no more - * references to the shared signal_struct. + * This is called by do_exit or de_thread, only when nobody else can + * modify the signal->posix_timers list. Yet we need sighand->siglock + * to prevent the race with /proc/pid/timers.   */ -void exit_itimers(struct signal_struct *sig) +void exit_itimers(struct task_struct *tsk)  { +	struct list_head timers;  	struct k_itimer *tmr; -	while (!list_empty(&sig->posix_timers)) { -		tmr = list_entry(sig->posix_timers.next, struct k_itimer, list); +	if (list_empty(&tsk->signal->posix_timers)) +		return; + +	spin_lock_irq(&tsk->sighand->siglock); +	list_replace_init(&tsk->signal->posix_timers, &timers); +	spin_unlock_irq(&tsk->sighand->siglock); + +	while (!list_empty(&timers)) { +		tmr = list_first_entry(&timers, struct k_itimer, list);  		itimer_delete(tmr);  	}  } diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 58a11f859ac7..30049580cd62 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -526,7 +526,6 @@ void __init tick_nohz_full_setup(cpumask_var_t cpumask)  	cpumask_copy(tick_nohz_full_mask, cpumask);  	tick_nohz_full_running = true;  } -EXPORT_SYMBOL_GPL(tick_nohz_full_setup);  static int tick_nohz_cpu_down(unsigned int cpu)  { |