From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0DE89189BAC for ; Fri, 27 Sep 2024 08:48:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426929; cv=none; b=dqu5uLsa/6ON4wmPgpT2piJ8S0wDq+cnhCfL4L1xxEK61bvoZS6kVqWcCSUSqseL1diPu8akithEuMPcijaf2q6anCFVOpXodKioGj1Ec2yi1fr4iPM2Ct0v8v7G0M4HInLcPtGvyLPGjUHJlfkdRIcrz1CYgwCIoXoKC3EB/Ls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426929; c=relaxed/simple; bh=lu+lCj7ZVMVtP6xFMyNezD2j+vD3+Z0v9oyVtIFOsfc=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=AsHKGf5Hp4a0Ap34GyaANQhUlNdFlywnu6P8rodxJ0vIX+DK2FOFVuDeR5QQ3yVId1MQwM0dN+5ShCgFjG6/h119ICDvNpXz6/VVGBMPC0l1Cikx8e9pCq8BqIQI4L8n/CaxzdNy+s2oZp88mZ+thK/VOcn6RSNmoj87pHn3q/0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=jLrgTIQz; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=f1NS19Xl; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="jLrgTIQz"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="f1NS19Xl" Message-ID: <20240927084816.951098399@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426920; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=EGeKgiJ7rau/udRThkUHhOJFPEYVFEblJCwbvubO3v4=; b=jLrgTIQz2PVC5boOFCf+RwEtFqqNLo7bIrvT5cDQQtOutSSkgsEYDA/R0JPl9bCG1xLy8s Q98mI69HxXqMFe9i6rQsO/ELUKu12EKcydr5Z1zvlOu3+aTF5X1iczVnv+X1z6O2FJ+m7o LZw2WXaJ27nDWclS1y98sF4liemBaDgcBYKvM7WTM8GidKLCU1T0vN15r0xpJ+A4bAZ6FD wuOL5mnzCSA936z7icci0g6IL27E0O0HlbZlXQvxldKfUd1sfLFjfz9aIHGNgfa9+sahE+ t3fz1ExCYOLru7cl1/Z5mmz2P+UlZKMTSbL2sjmGOYLZoBA3Ga4sS4isLtTydg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426920; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=EGeKgiJ7rau/udRThkUHhOJFPEYVFEblJCwbvubO3v4=; b=f1NS19XlIefhedH3AHJSdPQymwH1eDS5Pw/L7mutoveicgUsMfafWzXZZTGTkQq1FU+Wgm bjxYfYZu+EUxCqBg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 01/27] signal: Confine POSIX_TIMERS properly References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:40 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Move the itimer rearming out of the signal code and consolidate all posix timer related functions in the signal code under one ifdef. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Reviewed-by: Frederic Weisbecker --- include/linux/posix-timers.h | 5 +- kernel/signal.c | 125 +++++++++++++++------------------------= ----- kernel/time/itimer.c | 22 +++++++- kernel/time/posix-timers.c | 15 ++++- 4 files changed, 81 insertions(+), 86 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 453691710839..670bf03a56ef 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -100,6 +100,8 @@ static inline void posix_cputimers_rt_watchdog(struct p= osix_cputimers *pct, { pct->bases[CPUCLOCK_SCHED].nextevt =3D runtime; } +void posixtimer_rearm_itimer(struct task_struct *p); +void posixtimer_rearm(struct kernel_siginfo *info); =20 /* Init task static initializer */ #define INIT_CPU_TIMERBASE(b) { \ @@ -122,6 +124,8 @@ struct cpu_timer { }; static inline void posix_cputimers_init(struct posix_cputimers *pct) { } static inline void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit) { } +static inline void posixtimer_rearm_itimer(struct task_struct *p) { } +static inline void posixtimer_rearm(struct kernel_siginfo *info) { } #endif =20 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK @@ -196,5 +200,4 @@ void set_process_cpu_timer(struct task_struct *task, un= signed int clock_idx, =20 int update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); =20 -void posixtimer_rearm(struct kernel_siginfo *info); #endif diff --git a/kernel/signal.c b/kernel/signal.c index 6f3a5aa39b09..a83ea99f9389 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -478,42 +478,6 @@ void flush_signals(struct task_struct *t) } EXPORT_SYMBOL(flush_signals); =20 -#ifdef CONFIG_POSIX_TIMERS -static void __flush_itimer_signals(struct sigpending *pending) -{ - sigset_t signal, retain; - struct sigqueue *q, *n; - - signal =3D pending->signal; - sigemptyset(&retain); - - list_for_each_entry_safe(q, n, &pending->list, list) { - int sig =3D q->info.si_signo; - - if (likely(q->info.si_code !=3D SI_TIMER)) { - sigaddset(&retain, sig); - } else { - sigdelset(&signal, sig); - list_del_init(&q->list); - __sigqueue_free(q); - } - } - - sigorsets(&pending->signal, &signal, &retain); -} - -void flush_itimer_signals(void) -{ - struct task_struct *tsk =3D current; - unsigned long flags; - - spin_lock_irqsave(&tsk->sighand->siglock, flags); - __flush_itimer_signals(&tsk->pending); - __flush_itimer_signals(&tsk->signal->shared_pending); - spin_unlock_irqrestore(&tsk->sighand->siglock, flags); -} -#endif - void ignore_signals(struct task_struct *t) { int i; @@ -636,31 +600,9 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *i= nfo, enum pid_type *type) *type =3D PIDTYPE_TGID; signr =3D __dequeue_signal(&tsk->signal->shared_pending, mask, info, &resched_timer); -#ifdef CONFIG_POSIX_TIMERS - /* - * itimer signal ? - * - * itimers are process shared and we restart periodic - * itimers in the signal delivery path to prevent DoS - * attacks in the high resolution timer case. This is - * compliant with the old way of self-restarting - * itimers, as the SIGALRM is a legacy signal and only - * queued once. Changing the restart behaviour to - * restart the timer in the signal dequeue path is - * reducing the timer noise on heavy loaded !highres - * systems too. - */ - if (unlikely(signr =3D=3D SIGALRM)) { - struct hrtimer *tmr =3D &tsk->signal->real_timer; - - if (!hrtimer_is_queued(tmr) && - tsk->signal->it_real_incr !=3D 0) { - hrtimer_forward(tmr, tmr->base->get_time(), - tsk->signal->it_real_incr); - hrtimer_restart(tmr); - } - } -#endif + + if (unlikely(signr =3D=3D SIGALRM)) + posixtimer_rearm_itimer(tsk); } =20 recalc_sigpending(); @@ -682,22 +624,12 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *= info, enum pid_type *type) */ current->jobctl |=3D JOBCTL_STOP_DEQUEUED; } -#ifdef CONFIG_POSIX_TIMERS - if (resched_timer) { - /* - * Release the siglock to ensure proper locking order - * of timer locks outside of siglocks. Note, we leave - * irqs disabled here, since the posix-timers code is - * about to disable them again anyway. - */ - spin_unlock(&tsk->sighand->siglock); - posixtimer_rearm(info); - spin_lock(&tsk->sighand->siglock); =20 - /* Don't expose the si_sys_private value to userspace */ - info->si_sys_private =3D 0; + if (IS_ENABLED(CONFIG_POSIX_TIMERS)) { + if (unlikely(resched_timer)) + posixtimer_rearm(info); } -#endif + return signr; } EXPORT_SYMBOL_GPL(dequeue_signal); @@ -1922,15 +1854,43 @@ int kill_pid(struct pid *pid, int sig, int priv) } EXPORT_SYMBOL(kill_pid); =20 +#ifdef CONFIG_POSIX_TIMERS /* - * These functions support sending signals using preallocated sigqueue - * structures. This is needed "because realtime applications cannot - * afford to lose notifications of asynchronous events, like timer - * expirations or I/O completions". In the case of POSIX Timers - * we allocate the sigqueue structure from the timer_create. If this - * allocation fails we are able to report the failure to the application - * with an EAGAIN error. + * These functions handle POSIX timer signals. POSIX timers use + * preallocated sigqueue structs for sending signals. */ +static void __flush_itimer_signals(struct sigpending *pending) +{ + sigset_t signal, retain; + struct sigqueue *q, *n; + + signal =3D pending->signal; + sigemptyset(&retain); + + list_for_each_entry_safe(q, n, &pending->list, list) { + int sig =3D q->info.si_signo; + + if (likely(q->info.si_code !=3D SI_TIMER)) { + sigaddset(&retain, sig); + } else { + sigdelset(&signal, sig); + list_del_init(&q->list); + __sigqueue_free(q); + } + } + + sigorsets(&pending->signal, &signal, &retain); +} + +void flush_itimer_signals(void) +{ + struct task_struct *tsk =3D current; + + guard(spinlock_irqsave)(&tsk->sighand->siglock); + __flush_itimer_signals(&tsk->pending); + __flush_itimer_signals(&tsk->signal->shared_pending); +} + struct sigqueue *sigqueue_alloc(void) { return __sigqueue_alloc(-1, current, GFP_KERNEL, 0, SIGQUEUE_PREALLOC); @@ -2027,6 +1987,7 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid= , enum pid_type type) rcu_read_unlock(); return ret; } +#endif /* CONFIG_POSIX_TIMERS */ =20 void do_notify_pidfd(struct task_struct *task) { diff --git a/kernel/time/itimer.c b/kernel/time/itimer.c index 00629e658ca1..876d389b2e21 100644 --- a/kernel/time/itimer.c +++ b/kernel/time/itimer.c @@ -151,7 +151,27 @@ COMPAT_SYSCALL_DEFINE2(getitimer, int, which, #endif =20 /* - * The timer is automagically restarted, when interval !=3D 0 + * Invoked from dequeue_signal() when SIG_ALRM is delivered. + * + * Restart the ITIMER_REAL timer if it is armed as periodic timer. Doing + * this in the signal delivery path instead of self rearming prevents a DoS + * with small increments in the high reolution timer case and reduces timer + * noise in general. + */ +void posixtimer_rearm_itimer(struct task_struct *tsk) +{ + struct hrtimer *tmr =3D &tsk->signal->real_timer; + + if (!hrtimer_is_queued(tmr) && tsk->signal->it_real_incr !=3D 0) { + hrtimer_forward(tmr, tmr->base->get_time(), + tsk->signal->it_real_incr); + hrtimer_restart(tmr); + } +} + +/* + * Interval timers are restarted in the signal delivery path. See + * posixtimer_rearm_itimer(). */ enum hrtimer_restart it_real_fn(struct hrtimer *timer) { diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 1cc830ef93a7..bcd5e56412e7 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -251,7 +251,7 @@ static void common_hrtimer_rearm(struct k_itimer *timr) =20 /* * This function is called from the signal delivery code if - * info->si_sys_private is not zero, which indicates that the timer has to + * info::si_sys_private is not zero, which indicates that the timer has to * be rearmed. Restart the timer and update info::si_overrun. */ void posixtimer_rearm(struct kernel_siginfo *info) @@ -259,9 +259,15 @@ void posixtimer_rearm(struct kernel_siginfo *info) struct k_itimer *timr; unsigned long flags; =20 + /* + * Release siglock to ensure proper locking order versus + * timr::it_lock. Keep interrupts disabled. + */ + spin_unlock(¤t->sighand->siglock); + timr =3D lock_timer(info->si_tid, &flags); if (!timr) - return; + goto out; =20 if (timr->it_interval && timr->it_requeue_pending =3D=3D info->si_sys_pri= vate) { timr->kclock->timer_rearm(timr); @@ -275,6 +281,11 @@ void posixtimer_rearm(struct kernel_siginfo *info) } =20 unlock_timer(timr, flags); +out: + spin_lock(¤t->sighand->siglock); + + /* Don't expose the si_sys_private value to userspace */ + info->si_sys_private =3D 0; } =20 int posix_timer_queue_signal(struct k_itimer *timr) From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 787BA189F4B for ; Fri, 27 Sep 2024 08:48:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426930; cv=none; b=LObtSj0VK5NRfLG3c3Bz8ko3OlHqGGSTl5xsoJcUvPeTJP1+aLGzhomAzAypWXjpjSin7UR4IoWKd4LHMHhpl/vfWfn2WZr3/3W7z8vYEQarxfz4qICyyIIT+d6s3IFrgMBz18g7yMvhhCsgFzTSWAQg84R3CDOdixj66RK8KGo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426930; c=relaxed/simple; bh=2EY36ZPw9Bk/FILeYTge588GXUMBVDbi+K7dEpepmeY=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=ulKDz6Ock7IRZ5cvJWCjtY0oY6IJ8GV5GIKWKqQE/rC/UyF577ZJbql9butn77AaKn7AdTDFx/T/UbYuwOmPoFrAkU2EdgneUpGFUYQrt/OHslxyaDJPD7fNiIKH7bzyc9AUHnjO6uoXGYXbZdSfDQdVHIz6KgAOVr5uU+KfIYg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=EeQwRBOz; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=b+Jn09j0; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="EeQwRBOz"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="b+Jn09j0" Message-ID: <20240927084817.014903652@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426921; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=T+btbZAWH26XQNm65rNe9WbaHh1YRJhaO/jWuR8/ACU=; b=EeQwRBOzS+25vhB1Ey0RULol7GE27wkxZr3vTFlSfeh0VKeqcgmlyiLsByGcSJaQVmy2V0 hZiSy060fcSeRZDiJHzYW7rLL2xnJZjti6jlHaWbOEeI1cxfq5ItVjmmIu0LxnSHQjQAee kkjRCEk6T9ZZKBcPm7iFvXQ06WyHZcyghMprJqx2NZGw0At0R1XL+o7BI3s8Vvzd05Lkn+ fVrF/b9MIL3uNmmkAkxaMYkpLFHTCe35M0cc3iyancf86hK+bzLZZD1xnhb4Trbb0WXjx8 AUmovWM+VagVibZmiLfKr3d2r8Jt+YiiLK2lKlVjuuMJQUeAi8E8In0tUgqW2A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426921; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=T+btbZAWH26XQNm65rNe9WbaHh1YRJhaO/jWuR8/ACU=; b=b+Jn09j0O+akSHWGtgH9AWFKy7siUkLKoBTbo32rlz1bTMTiqinIaiNpNYThAJd8uIKhiv uTcYpjRKrwJL1KAQ== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 02/27] signal: Prevent user space from setting si_sys_private References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:41 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner The si_sys_private member of siginfo is used to handle posix-timer rearming from the signal delivery path. Prevent user space from setting it as that creates inconsistent state. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Acked-by: Frederic Weisbecker --- kernel/signal.c | 8 ++++++++ 1 file changed, 8 insertions(+) --- diff --git a/kernel/signal.c b/kernel/signal.c index a83ea99f9389..7706cd304785 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3354,6 +3354,14 @@ int copy_siginfo_to_user(siginfo_t __user *to, const= kernel_siginfo_t *from) static int post_copy_siginfo_from_user(kernel_siginfo_t *info, const siginfo_t __user *from) { + /* + * Clear the si_sys_private field for timer signals as that's the + * indicator for rearming a posix timer. User space submitted + * signals are not allowed to inject that. + */ + if (info->si_code =3D=3D SI_TIMER) + info->si_sys_private =3D 0; + if (unlikely(!known_siginfo_layout(info->si_signo, info->si_code))) { char __user *expansion =3D si_expansion(from); char buf[SI_EXPANSION_SIZE]; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33F5618A6DD for ; Fri, 27 Sep 2024 08:48:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426932; cv=none; b=kSd7m9epjnC5lTOn3wLVXvVTkWLzS6fE35j6+IU3mtmPI9+Ellf7A6yK5teaq673m2CfeOXTOz00+iBty8LRVtlDetwCSEH0NjRZewiaR5brTO4uDcEKragd9ASycLWgsucSHg9ROY5HYbjHbPJzhdb+L73kjHyrXWaPXU7LiuA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426932; c=relaxed/simple; bh=zIuK2lE66Z+HPke8d7lxHWmFzYXh1WtDOUi7OBB0t5M=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=DcmxT1dAlLoQKK56Px4mp8qXv4Vq6o/rIwNXbwvGKC8B1SC0eA5GjfoDXFaOo6bettIJ7ySgs3RJSdwIqUtt90fkXY6PHVqKX/7SRJ1C5G4YyHn2vUkSZY8QOsaKbm9lwGAv1khvhQ/QhbP2qjJNLPVukjBx7CU9fDP9HJULD+s= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=cnMcQj9b; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=sohlXReU; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="cnMcQj9b"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="sohlXReU" Message-ID: <20240927084817.077215973@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426923; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=iFAEBuAlpYC8f3qlbhRRUEyjDeW+2nw5ukmxpOId5Ps=; b=cnMcQj9bsJFJwQXsbJ8e0OOF+oNES2h8zXkMGOb30KGnQ8FU9FSz3w9hwB4kAMI6CwKix1 2VnzP/NjQjR6yUv4rb3h6VhdnWuO2c/MspRugcuWtNGmwF6uoLWiQje+Ov/axnzw2XN/ly PMXW1c8ySyNq6BhFP4R4+bB6XNUwsABuvEZa9KUfEjOioqIEmG4tMpymt7qS9qNk1WxklB +GVCtntXjujgZhD3vBLPLX1ITbX+IYTHNtA2PpU0nATA5TmieDj8LPuaR0u2LkZByuzauh f9MWAfMgiZ6f9NCrur+158K86iYNTeFc1HVaTS/zJPSbN8lud4iu/j2wHWzVDA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426923; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=iFAEBuAlpYC8f3qlbhRRUEyjDeW+2nw5ukmxpOId5Ps=; b=sohlXReUJtQRrFj/uGz3qIDaurVitSPZM2GR0yFEjXEJ5e4e4nCUES8LTBAuMIUxKZBXAl cVHw6q/wETDn/TCw== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 03/27] signal: Get rid of resched_timer logic References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:42 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner There is no reason for handing the *resched pointer argument through several functions just to check whether the signal is related to a self rearming posix timer. SI_TIMER is only used by the posix timer code and cannot be queued from user space. The only extra check in collect_signal() to verify whether the queued signal is preallocated is not really useful. Some other places already check purely the SI_TIMER type. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Acked-by: Frederic Weisbecker --- kernel/signal.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) --- diff --git a/kernel/signal.c b/kernel/signal.c index 7706cd304785..3d2e087283ab 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -526,8 +526,7 @@ bool unhandled_signal(struct task_struct *tsk, int sig) return !tsk->ptrace; } =20 -static void collect_signal(int sig, struct sigpending *list, kernel_siginf= o_t *info, - bool *resched_timer) +static void collect_signal(int sig, struct sigpending *list, kernel_siginf= o_t *info) { struct sigqueue *q, *first =3D NULL; =20 @@ -549,12 +548,6 @@ static void collect_signal(int sig, struct sigpending = *list, kernel_siginfo_t *i still_pending: list_del_init(&first->list); copy_siginfo(info, &first->info); - - *resched_timer =3D - (first->flags & SIGQUEUE_PREALLOC) && - (info->si_code =3D=3D SI_TIMER) && - (info->si_sys_private); - __sigqueue_free(first); } else { /* @@ -571,13 +564,12 @@ static void collect_signal(int sig, struct sigpending= *list, kernel_siginfo_t *i } } =20 -static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, - kernel_siginfo_t *info, bool *resched_timer) +static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, ke= rnel_siginfo_t *info) { int sig =3D next_signal(pending, mask); =20 if (sig) - collect_signal(sig, pending, info, resched_timer); + collect_signal(sig, pending, info); return sig; } =20 @@ -589,17 +581,15 @@ static int __dequeue_signal(struct sigpending *pendin= g, sigset_t *mask, int dequeue_signal(sigset_t *mask, kernel_siginfo_t *info, enum pid_type *= type) { struct task_struct *tsk =3D current; - bool resched_timer =3D false; int signr; =20 lockdep_assert_held(&tsk->sighand->siglock); =20 *type =3D PIDTYPE_PID; - signr =3D __dequeue_signal(&tsk->pending, mask, info, &resched_timer); + signr =3D __dequeue_signal(&tsk->pending, mask, info); if (!signr) { *type =3D PIDTYPE_TGID; - signr =3D __dequeue_signal(&tsk->signal->shared_pending, - mask, info, &resched_timer); + signr =3D __dequeue_signal(&tsk->signal->shared_pending, mask, info); =20 if (unlikely(signr =3D=3D SIGALRM)) posixtimer_rearm_itimer(tsk); @@ -626,7 +616,7 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *in= fo, enum pid_type *type) } =20 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) { - if (unlikely(resched_timer)) + if (unlikely(info->si_code =3D=3D SI_TIMER && info->si_sys_private)) posixtimer_rearm(info); } =20 @@ -1011,6 +1001,9 @@ static int __send_signal_locked(int sig, struct kerne= l_siginfo *info, =20 lockdep_assert_held(&t->sighand->siglock); =20 + if (WARN_ON_ONCE(!is_si_special(info) && info->si_code =3D=3D SI_TIMER)) + return 0; + result =3D TRACE_SIGNAL_IGNORED; if (!prepare_signal(sig, t, force)) goto ret; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 42B3518A948 for ; Fri, 27 Sep 2024 08:48:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426932; cv=none; b=PZJaobde2qASVvv5vD+8ak7yMnaFlvhXOoXpblTo/rRMKAKAUIe8Z525HX/XAwHpmiDN88mTaphQPrshbaWrSk7BITqfyTNuYFcCq1aGn7bogvt4keLztnI1Nhrw3DJIMoA12IXW6PreMMT7kV3J1REFKPB72loke7UWXlOhpEc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426932; c=relaxed/simple; bh=TX3TFV/PcpEe2I3CEleRen+sJB2L82vbAcbfKlv8tFg=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=Ea95tZLKWuR2bLSZ8Yq9JEgY5+o1vE5ve9MTavzqE60icLdwTrkOC75adRmyEj57XABly8nQQwrHCxntMNu01bv14pxXVBmv5J8sfHkRWg5fr55mmDt/USddxZSCsiIHjebzn+U1hrUFAdlPQUlqoCC1i/ABRP1GzraxVS4IqK0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=vA8AzNfN; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=hqzHayhN; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="vA8AzNfN"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="hqzHayhN" Message-ID: <20240927084817.138903581@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426924; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=nMa/V7VTOC/xYG0c2/c7ZQoshOFect1N4p4ux1Yw8j8=; b=vA8AzNfNgYk2u+L8GExYnSy/sFsLR9Nui3/VeV7TxyQYBlRNyGy8tm7lTp9PsJWhDfzuAp 4aYh7O8pFtJv4O00Chh5Nie4jv0CuupTfw/yJRAGNBQTMIr2QtpkA4ovZtbDmYR2HrpFSQ TQnTNtQHEo51Npk94X0AQjdm+dAfPtq/0Kk/6mOO2ZBsbEuilQiEXiYhWhdSmCNokPoiUX htEuBZQxZLa4M383hUh9Y+Yp5k6sLQikKZ45upg27viX1hT0IiaZuGefk9qRh41MVmTdZ0 4VxbBdBtnGMHXeYXcwgyH70jNWIoS0aDob9k9yLueG4HomAdEjq+S8mS3TpcJA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426924; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=nMa/V7VTOC/xYG0c2/c7ZQoshOFect1N4p4ux1Yw8j8=; b=hqzHayhNX/8gPsxyhFQFubHdXMuFgw56TbWU+eHivhDRqAXQh+ipUuLAiXmyGLDW8UccYn uzpTCMGckq3sirBg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 04/27] posix-timers: Cure si_sys_private race References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:44 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner The si_sys_private member of the siginfo which is embedded in the preallocated sigqueue is used by the posix timer code to decide whether a timer must be reprogrammed on signal delivery. The handling of this is racy as a long standing comment in that code documents. It is modified with the timer lock held, but without sighand lock being held. The actual signal delivery code checks for it under sighand lock without holding the timer lock. Hand the new value to send_sigqueue() as argument and store it with sighand lock held. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/sched/signal.h | 2 +- kernel/signal.c | 10 +++++++++- kernel/time/posix-timers.c | 15 +-------------- 3 files changed, 11 insertions(+), 16 deletions(-) --- diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index c8ed09ac29ac..bd9f569231d9 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -340,7 +340,7 @@ extern int send_sig(int, struct task_struct *, int); extern int zap_other_threads(struct task_struct *p); extern struct sigqueue *sigqueue_alloc(void); extern void sigqueue_free(struct sigqueue *); -extern int send_sigqueue(struct sigqueue *, struct pid *, enum pid_type); +extern int send_sigqueue(struct sigqueue *, struct pid *, enum pid_type, i= nt si_private); extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); =20 static inline void clear_notify_signal(void) diff --git a/kernel/signal.c b/kernel/signal.c index 3d2e087283ab..443baadb5ab0 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1915,7 +1915,7 @@ void sigqueue_free(struct sigqueue *q) __sigqueue_free(q); } =20 -int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type) +int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type,= int si_private) { int sig =3D q->info.si_signo; struct sigpending *pending; @@ -1950,6 +1950,14 @@ int send_sigqueue(struct sigqueue *q, struct pid *pi= d, enum pid_type type) if (!likely(lock_task_sighand(t, &flags))) goto ret; =20 + /* + * Update @q::info::si_sys_private for posix timer signals with + * sighand locked to prevent a race against dequeue_signal() which + * decides based on si_sys_private whether to invoke + * posixtimer_rearm() or not. + */ + q->info.si_sys_private =3D si_private; + ret =3D 1; /* the signal is ignored */ result =3D TRACE_SIGNAL_IGNORED; if (!prepare_signal(sig, t, false)) diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index bcd5e56412e7..b6cca1ed2f90 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -299,21 +299,8 @@ int posix_timer_queue_signal(struct k_itimer *timr) if (timr->it_interval) si_private =3D ++timr->it_requeue_pending; =20 - /* - * FIXME: if ->sigq is queued we can race with - * dequeue_signal()->posixtimer_rearm(). - * - * If dequeue_signal() sees the "right" value of - * si_sys_private it calls posixtimer_rearm(). - * We re-queue ->sigq and drop ->it_lock(). - * posixtimer_rearm() locks the timer - * and re-schedules it while ->sigq is pending. - * Not really bad, but not that we want. - */ - timr->sigq->info.si_sys_private =3D si_private; - type =3D !(timr->it_sigev_notify & SIGEV_THREAD_ID) ? PIDTYPE_TGID : PIDT= YPE_PID; - ret =3D send_sigqueue(timr->sigq, timr->it_pid, type); + ret =3D send_sigqueue(timr->sigq, timr->it_pid, type, si_private); /* If we failed to send the signal the timer stops. */ return ret > 0; } From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00D7B18A6AF for ; Fri, 27 Sep 2024 08:48:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426931; cv=none; b=rwOHvfUOwEDCPbSpSVUxPlLX4GRTmJPN5uJqt35jrYqnmHvDAO4LaUjZJb4LHB057lXpqCHipD7R3YM6e6O5ckzHs9kKVzWfjx/WiaeoErMoAwbNafZq2wp1dl9gFeY7sNB4FvkqPbCPAn+tBt8E6iYEtoHRlJy+CYqXPf8rt3E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426931; c=relaxed/simple; bh=nMxK2TVQUw9yR6HLv+Lk2ZUa3NgJga3POK/2Yd563DQ=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=KHHP+1StJh8k3nyzHNwN7SKyXG48+aRbDfAahtxhxd3nAENqAtSUwXG8zQCQIPJyhEyojvUhVJwE/Zs4hMOiAtyX8YKky5bEGavq14Qynqz7dJcrpc/U4r9bImWC3zYKtkmeOMPgkOvVbFHyU8iyUkmTOcmKZnMoIomVgYUOrmQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=soptG/GD; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=tj43IAUI; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="soptG/GD"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="tj43IAUI" Message-ID: <20240927084817.199851763@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426925; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=nctofLmIte6TSx5Fcm0ses5QzBfXpuCNkO8zmbzciOI=; b=soptG/GDN8YoLc/uvj8wQkW709NG2NkTPcZUgHxBoMS2EMQiLnmT3P7lRmOeR9UKP+Rc4V MmfRn51hoU+EeMWy5BZXra1iQHtlOlJvaDB4RKr1YwmBPSuRRCLWOjtplOXCDBw9OgPDjD pCT/AcRNnAmEkV3fq4A8dAMfxhTaTFAyat2r5RfCshzyjFy1OBtPYfdDnQHAY8yYqzFAVo CBOSpdHFPdrQBfFV8JsAIQ9iA67TiluZafRHZdKYkXY7tiCwZ4wc31qCv2VR5wu4fKWqNP SmV1dXT2C3l98uVGmZTUAbI+aWtRvI5alY8VMEL8XPWrCYfRhiRbXSU/EFPT6g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426925; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=nctofLmIte6TSx5Fcm0ses5QzBfXpuCNkO8zmbzciOI=; b=tj43IAUIBK8RIXCylZqehFjA0Foufvzfms1zfCv1Hq8QafD+pGALUZhpXuQpPXRqEUlelj aLr7ag+KIPLUbHDg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 05/27] signal: Allow POSIX timer signals to be dropped References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:45 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner In case that a timer was reprogrammed or deleted an already pending signal is obsolete. Right now such signals are kept around and eventually delivered. While POSIX is blury about this: - "The effect of disarming or resetting a timer with pending expiration notifications is unspecified." - "The disposition of pending signals for the deleted timer is unspecified." it is reasonable in both cases to expect that pending signals are discarded as they have no meaning anymore. Prepare the signal code to allow dropping posix timer signals. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 5 +++-- kernel/signal.c | 7 +++++-- kernel/time/posix-timers.c | 3 ++- 3 files changed, 10 insertions(+), 5 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 670bf03a56ef..4ab49e5c42af 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -100,8 +100,9 @@ static inline void posix_cputimers_rt_watchdog(struct p= osix_cputimers *pct, { pct->bases[CPUCLOCK_SCHED].nextevt =3D runtime; } + void posixtimer_rearm_itimer(struct task_struct *p); -void posixtimer_rearm(struct kernel_siginfo *info); +bool posixtimer_deliver_signal(struct kernel_siginfo *info); =20 /* Init task static initializer */ #define INIT_CPU_TIMERBASE(b) { \ @@ -125,7 +126,7 @@ static inline void posix_cputimers_init(struct posix_cp= utimers *pct) { } static inline void posix_cputimers_group_init(struct posix_cputimers *pct, u64 cpu_limit) { } static inline void posixtimer_rearm_itimer(struct task_struct *p) { } -static inline void posixtimer_rearm(struct kernel_siginfo *info) { } +static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info) = { return false; } #endif =20 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK diff --git a/kernel/signal.c b/kernel/signal.c index 443baadb5ab0..c35b6ff52767 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -585,6 +585,7 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *in= fo, enum pid_type *type) =20 lockdep_assert_held(&tsk->sighand->siglock); =20 +again: *type =3D PIDTYPE_PID; signr =3D __dequeue_signal(&tsk->pending, mask, info); if (!signr) { @@ -616,8 +617,10 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *i= nfo, enum pid_type *type) } =20 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) { - if (unlikely(info->si_code =3D=3D SI_TIMER && info->si_sys_private)) - posixtimer_rearm(info); + if (unlikely(info->si_code =3D=3D SI_TIMER && info->si_sys_private)) { + if (!posixtimer_deliver_signal(info)) + goto again; + } } =20 return signr; diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index b6cca1ed2f90..d7ed7542f803 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -254,7 +254,7 @@ static void common_hrtimer_rearm(struct k_itimer *timr) * info::si_sys_private is not zero, which indicates that the timer has to * be rearmed. Restart the timer and update info::si_overrun. */ -void posixtimer_rearm(struct kernel_siginfo *info) +bool posixtimer_deliver_signal(struct kernel_siginfo *info) { struct k_itimer *timr; unsigned long flags; @@ -286,6 +286,7 @@ void posixtimer_rearm(struct kernel_siginfo *info) =20 /* Don't expose the si_sys_private value to userspace */ info->si_sys_private =3D 0; + return true; } =20 int posix_timer_queue_signal(struct k_itimer *timr) From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33EE218A6B5 for ; Fri, 27 Sep 2024 08:48:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426931; cv=none; b=roFUp1p/z5aeXR16Ueu7uSWDqk6Kv49iSUMAUullRxSYbX17rJw5ov0iybQ6TXJVc4nHjZe9elUTbu52Pxjgg3aSYCXbIJk8fCugz9Hvi+C654ET/3GrQWWQhj5yFkrAl8v9UoG4e/gK7Wf772KsJSiTECX02gSR9DWsIX3Y7og= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426931; c=relaxed/simple; bh=MLbvTApDwcn4rh7emeTMGx1Q505+q6MoicWj4Jh2Yfg=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=gUHrxWg1eXurPCZNm+3ulVHLt499JeWcJRgk0h9XNzlv2+fdYMtC2m1QS/EuJBImEk1T4G8IgsSN2pMtF26/ocWx1kbMxKL+W/YfZvKgzK4+k6HlVVTINpg8e6SlKHtJiPu5tnTCbBWrBe0l54WBgtr3lb1oV0lB4RpYD3h8fbQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qIO9m7jt; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=GueneQV6; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qIO9m7jt"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="GueneQV6" Message-ID: <20240927084817.261702549@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426926; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=RKLyvk4kjAmxUrZnWrBzTvZjowh6Tz3OdWzxp5LVw2k=; b=qIO9m7jt5/Rz4bIHOp4HoOrRUPdYRn1H/rflE/7ySnjJBJ2GFeyDVUeQE83pkNGT/NgBr7 28+dgzjEU3WR6hIm4OKx5JmmMp4jd8YE5CFYXnH3g3OuputP7i2rPGMm1bjIk/mGLHsM7J q8f3UkTh5moqRjB11UAk69Rq5Q7z+N5us4brmT2zO6b5EEf3DeVp3uJRGich3Puf7v9Eq9 nN+bonrPZBfiEv3kjPYKY5OOe9wapnC/o3O5pD7dw6LqVAQg5a4br1umR0IPHK1k2vcX9L F1VtKRN2oD66W5tzPtCu5ChFJ3UbGKMP+h6D1RMfuh197gI2ojJSZ6uA+DR+2Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426926; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=RKLyvk4kjAmxUrZnWrBzTvZjowh6Tz3OdWzxp5LVw2k=; b=GueneQV6KCVq0cibTzXfN0LryZGhUik5kBmLoDGkTMjPHXccxJ+pjcHFyz5AzDDhKP1t4m /PajCjFQhSQnYCCQ== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 06/27] posix-timers: Drop signal if timer has been deleted or reprogrammed References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:46 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner No point in delivering a signal from the past. POSIX does not specify the behaviour here: - "The effect of disarming or resetting a timer with pending expiration notifications is unspecified." - "The disposition of pending signals for the deleted timer is unspecified= ." In both cases it is reasonable to expect that pending signals are discarded. Especially in the reprogramming case it does not make sense to account for previous overruns or to deliver a signal for a timer which has been disarmed. Drop the signal as that is conistent and understandable behaviour. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- kernel/time/posix-timers.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) --- diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index d7ed7542f803..b5d7e71c10f2 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -250,14 +250,14 @@ static void common_hrtimer_rearm(struct k_itimer *tim= r) } =20 /* - * This function is called from the signal delivery code if - * info::si_sys_private is not zero, which indicates that the timer has to - * be rearmed. Restart the timer and update info::si_overrun. + * This function is called from the signal delivery code. It decides + * whether the signal should be dropped and rearms interval timers. */ bool posixtimer_deliver_signal(struct kernel_siginfo *info) { struct k_itimer *timr; unsigned long flags; + bool ret =3D false; =20 /* * Release siglock to ensure proper locking order versus @@ -279,6 +279,7 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *i= nfo) =20 info->si_overrun =3D timer_overrun_to_int(timr, info->si_overrun); } + ret =3D true; =20 unlock_timer(timr, flags); out: @@ -286,7 +287,7 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *i= nfo) =20 /* Don't expose the si_sys_private value to userspace */ info->si_sys_private =3D 0; - return true; + return ret; } =20 int posix_timer_queue_signal(struct k_itimer *timr) From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6168018B463 for ; Fri, 27 Sep 2024 08:48:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426934; cv=none; b=J7A0n04aPpqSRIJy349cI0F/gVud+37ZmHjr0+Oi3k5M2zWDI37IrtQatQb5X8cbS/T2/gdoZd5UgwMPkkbt4wPcac9qeOAiKjoo3x8l/eqPtF5U/GseBmmadQuGNVbedS8zsH2rP3AiPYjNSQzhP364Sd9kKoEeoRuw4UKBTLA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426934; c=relaxed/simple; bh=PqzWsjYbtK5XT4wEGWmnJWfxOv0sZ1E1jD72R5OAXbY=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=Lq4c2jRF8dshmNl5vZomR/lMR043WRynKKVQMLqKWQ0HdquqLDG+mwFDkO6+7UKfjan2EnD7FfOro3lt4yIzpzhUI6oau130q+wQd53EWrbQorZsFVwlf7S8d6KuBLMcvI63jBxIZ+Ent4GjZkL7hfhkmYqKQSnelp5bJZnI6yE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=z677W7Ki; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=+aMKNf63; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="z677W7Ki"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="+aMKNf63" Message-ID: <20240927084817.323660727@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426928; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=o0OaJqinlokgy9Yq/GYNUvVlAK25MwM65rlj48+ovmI=; b=z677W7KihOtnzj26akPqmtlqSxUZOH6tSAQjDcKeP9cVoxsUpZO43s9JyZ5ITiJVH9C2es lZwOke75H3mCJ4yOcRjkN6MX1CUoKqns9mEzM+OH4ZOxDQ2R0Yt4QRzAIv68TGvtVtkUxu sFiHTuJXz+CRA4UOpyAG0dqBVYEHRV4LUwvgiPrA0FQrs2PORHYkeUbIadOu3xH4qWM/Mk fmDOxuuHV9meKnI/AIzuJwEDFlvzAVFrJXweF4CijyO4Uyt9WLyuRs0zyWU6AkCOshyAx5 M954ijhoJmxxhhSLUefTMSVh5xKE7yPRf5XSh1CcAAsfW3Xg7hAH4CN2LQvCTA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426928; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=o0OaJqinlokgy9Yq/GYNUvVlAK25MwM65rlj48+ovmI=; b=+aMKNf63d0U1t14CnxC5QZGNKyp/VylfshJAjUUvKTRIOFCaFf8dapCof25V2nlkreA+u3 kp/RTpULR5+j9VDg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 07/27] posix-timers: Rename k_itimer::it_requeue_pending References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:47 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Prepare for using this struct member to do a proper reprogramming and deletion accounting so that stale signals can be dropped. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 5 ++--- kernel/time/alarmtimer.c | 2 +- kernel/time/posix-cpu-timers.c | 4 ++-- kernel/time/posix-timers.c | 12 ++++++------ 4 files changed, 11 insertions(+), 12 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 4ab49e5c42af..253d106fac2c 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -150,8 +150,7 @@ static inline void posix_cputimers_init_work(void) { } * @it_active: Marker that timer is active * @it_overrun: The overrun counter for pending signals * @it_overrun_last: The overrun at the time of the last delivered signal - * @it_requeue_pending: Indicator that timer waits for being requeued on - * signal delivery + * @it_signal_seq: Sequence count to control signal delivery * @it_sigev_notify: The notify word of sigevent struct for signal delivery * @it_interval: The interval for periodic timers * @it_signal: Pointer to the creators signal struct @@ -172,7 +171,7 @@ struct k_itimer { int it_active; s64 it_overrun; s64 it_overrun_last; - int it_requeue_pending; + unsigned int it_signal_seq; int it_sigev_notify; ktime_t it_interval; struct signal_struct *it_signal; diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 76bd4fda3472..22d5145dd9a7 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -584,7 +584,7 @@ static enum alarmtimer_restart alarm_handle_timer(struc= t alarm *alarm, * small intervals cannot starve the system. */ ptr->it_overrun +=3D __alarm_forward_now(alarm, ptr->it_interval, true); - ++ptr->it_requeue_pending; + ++ptr->it_signal_seq; ptr->it_active =3D 1; result =3D ALARMTIMER_RESTART; } diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 6bcee4704059..993243b5be98 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -608,7 +608,7 @@ static void cpu_timer_fire(struct k_itimer *timer) * ticking in case the signal is deliverable next time. */ posix_cpu_timer_rearm(timer); - ++timer->it_requeue_pending; + ++timer->it_signal_seq; } } =20 @@ -745,7 +745,7 @@ static void __posix_cpu_timer_get(struct k_itimer *time= r, struct itimerspec64 *i * - Timers which expired, but the signal has not yet been * delivered */ - if (iv && ((timer->it_requeue_pending & REQUEUE_PENDING) || sigev_none)) + if (iv && ((timer->it_signal_seq & REQUEUE_PENDING) || sigev_none)) expires =3D bump_cpu_timer(timer, now); else expires =3D cpu_timer_getexpires(&timer->it.cpu); diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index b5d7e71c10f2..26243d38d27d 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -269,13 +269,13 @@ bool posixtimer_deliver_signal(struct kernel_siginfo = *info) if (!timr) goto out; =20 - if (timr->it_interval && timr->it_requeue_pending =3D=3D info->si_sys_pri= vate) { + if (timr->it_interval && timr->it_signal_seq =3D=3D info->si_sys_private)= { timr->kclock->timer_rearm(timr); =20 timr->it_active =3D 1; timr->it_overrun_last =3D timr->it_overrun; timr->it_overrun =3D -1LL; - ++timr->it_requeue_pending; + ++timr->it_signal_seq; =20 info->si_overrun =3D timer_overrun_to_int(timr, info->si_overrun); } @@ -299,7 +299,7 @@ int posix_timer_queue_signal(struct k_itimer *timr) =20 timr->it_active =3D 0; if (timr->it_interval) - si_private =3D ++timr->it_requeue_pending; + si_private =3D ++timr->it_signal_seq; =20 type =3D !(timr->it_sigev_notify & SIGEV_THREAD_ID) ? PIDTYPE_TGID : PIDT= YPE_PID; ret =3D send_sigqueue(timr->sigq, timr->it_pid, type, si_private); @@ -366,7 +366,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtim= er *timer) =20 timr->it_overrun +=3D hrtimer_forward(timer, now, timr->it_interval); ret =3D HRTIMER_RESTART; - ++timr->it_requeue_pending; + ++timr->it_signal_seq; timr->it_active =3D 1; } } @@ -667,7 +667,7 @@ void common_timer_get(struct k_itimer *timr, struct iti= merspec64 *cur_setting) * is a SIGEV_NONE timer move the expiry time forward by intervals, * so expiry is > now. */ - if (iv && (timr->it_requeue_pending & REQUEUE_PENDING || sig_none)) + if (iv && (timr->it_signal_seq & REQUEUE_PENDING || sig_none)) timr->it_overrun +=3D kc->timer_forward(timr, now); =20 remaining =3D kc->timer_remaining(timr, now); @@ -868,7 +868,7 @@ void posix_timer_set_common(struct k_itimer *timer, str= uct itimerspec64 *new_set timer->it_interval =3D 0; =20 /* Prevent reloading in case there is a signal pending */ - timer->it_requeue_pending =3D (timer->it_requeue_pending + 2) & ~REQUEUE_= PENDING; + timer->it_signal_seq =3D (timer->it_signal_seq + 2) & ~REQUEUE_PENDING; /* Reset overrun accounting */ timer->it_overrun_last =3D 0; timer->it_overrun =3D -1LL; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FF3518B460 for ; Fri, 27 Sep 2024 08:48:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426933; cv=none; b=amg2jsoUaawRN2EqOHmtXeyVo395LxulODov2JEaVsSf3EJOqzwh177bvRPsA8HkEXOYjxs49tg/XixrRmGVFeooK4QkZz5CbR1W4njOxkCYJnzaFIktB4jNX2w49wvfO4J2UxmwI8I2dG52MntF1Eum5PNxHQeRX4pG+ON21i0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426933; c=relaxed/simple; bh=B+2TAbL5ECEgs7nw6T2RilAjCrqncNh+NmQwTs14m2k=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=icnn7mU9D14H1MTAJMOoam66KM7l/EjYx8AgEak9kveUhoZkLbmni2Gflg0xiyPZ/64KarDg69u3XBXKJKRyX99wEoRKayTY5Vx3HC3AG/zRwc4AebrIY3ul4myWz+GZvTzCrdu7MB6Xh1R3jkX76vFgx9/MvVGO6QH/3KcdldI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ViRHYvxL; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=+cZSPqUx; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ViRHYvxL"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="+cZSPqUx" Message-ID: <20240927084817.386508461@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426929; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=LOXnOtS2SoQNq0MXiARkvZd94aAhAmUpnLizG+MsF2Q=; b=ViRHYvxLblAfdkg9erWqraMh/MfufJUosT7zdIxBnUte4x49NWU9RPzOal/WP+2KViqQxo NbChShiH+YRO0i0nq0qWMGSBXJPZWgdmdVwWkI9xM2dXq03pJ9G0PLp9HZC0rznBJdnp5Q 74bYoRmKASdTvfxk+0ma0YaedGa3oEQLxLINLSeFrspR+VkxkSsnK2JGpqlCa4HeeJNysF C2F6CMlt9nAW38VPWXcCVTG+eL5M8TahytLD6txBOtdsYyl21wX8sYtoCdvrzLbQdk2UBE jzbwQCn+YF45prZyIObBAK4hhm+XakpxVkmuJPkh/J5z3vSD7Esh6hDP+RrHaQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426929; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=LOXnOtS2SoQNq0MXiARkvZd94aAhAmUpnLizG+MsF2Q=; b=+cZSPqUxTtgoOIxVGnWQfWYgfpbHG/DzXo8nta2nGo383AlAixJblVsrk0wXYhYmEzGMNf sFlIGHWN5iBIdVCg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 08/27] posix-timers: Add proper state tracking References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:48 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Right now the state tracking is done by two struct members: - it_active: A boolean which tracks armed/disarmed state - it_signal_seq: A sequence counter which is used to invalidate settings and prevent rearming Replace it_active with it_status and keep properly track about the states in one place. This allows to reuse it_signal_seq to track reprogramming, disarm and delete operations in order to drop signals which are related to the state previous of those operations. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 4 ++-- kernel/time/alarmtimer.c | 2 +- kernel/time/posix-cpu-timers.c | 15 ++++++++------- kernel/time/posix-timers.c | 22 +++++++++++++--------- kernel/time/posix-timers.h | 6 ++++++ 5 files changed, 30 insertions(+), 19 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 253d106fac2c..02afbb4da7f7 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -147,7 +147,7 @@ static inline void posix_cputimers_init_work(void) { } * @kclock: Pointer to the k_clock struct handling this timer * @it_clock: The posix timer clock id * @it_id: The posix timer id for identifying the timer - * @it_active: Marker that timer is active + * @it_status: The status of the timer * @it_overrun: The overrun counter for pending signals * @it_overrun_last: The overrun at the time of the last delivered signal * @it_signal_seq: Sequence count to control signal delivery @@ -168,7 +168,7 @@ struct k_itimer { const struct k_clock *kclock; clockid_t it_clock; timer_t it_id; - int it_active; + int it_status; s64 it_overrun; s64 it_overrun_last; unsigned int it_signal_seq; diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 22d5145dd9a7..71360f8072d4 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -585,7 +585,7 @@ static enum alarmtimer_restart alarm_handle_timer(struc= t alarm *alarm, */ ptr->it_overrun +=3D __alarm_forward_now(alarm, ptr->it_interval, true); ++ptr->it_signal_seq; - ptr->it_active =3D 1; + ptr->it_status =3D POSIX_TIMER_ARMED; result =3D ALARMTIMER_RESTART; } spin_unlock_irqrestore(&ptr->it_lock, flags); diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 993243b5be98..12f828d704b1 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -453,7 +453,6 @@ static void disarm_timer(struct k_itimer *timer, struct= task_struct *p) struct cpu_timer *ctmr =3D &timer->it.cpu; struct posix_cputimer_base *base; =20 - timer->it_active =3D 0; if (!cpu_timer_dequeue(ctmr)) return; =20 @@ -494,11 +493,12 @@ static int posix_cpu_timer_del(struct k_itimer *timer) */ WARN_ON_ONCE(ctmr->head || timerqueue_node_queued(&ctmr->node)); } else { - if (timer->it.cpu.firing) + if (timer->it.cpu.firing) { ret =3D TIMER_RETRY; - else + } else { disarm_timer(timer, p); - + timer->it_status =3D POSIX_TIMER_DISARMED; + } unlock_task_sighand(p, &flags); } =20 @@ -560,7 +560,7 @@ static void arm_timer(struct k_itimer *timer, struct ta= sk_struct *p) struct cpu_timer *ctmr =3D &timer->it.cpu; u64 newexp =3D cpu_timer_getexpires(ctmr); =20 - timer->it_active =3D 1; + timer->it_status =3D POSIX_TIMER_ARMED; if (!cpu_timer_enqueue(&base->tqhead, ctmr)) return; =20 @@ -586,7 +586,8 @@ static void cpu_timer_fire(struct k_itimer *timer) { struct cpu_timer *ctmr =3D &timer->it.cpu; =20 - timer->it_active =3D 0; + timer->it_status =3D POSIX_TIMER_DISARMED; + if (unlikely(timer->sigq =3D=3D NULL)) { /* * This a special case for clock_nanosleep, @@ -671,7 +672,7 @@ static int posix_cpu_timer_set(struct k_itimer *timer, = int timer_flags, ret =3D TIMER_RETRY; } else { cpu_timer_dequeue(ctmr); - timer->it_active =3D 0; + timer->it_status =3D POSIX_TIMER_DISARMED; } =20 /* diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 26243d38d27d..6f0dacec25e0 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -272,7 +272,7 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *i= nfo) if (timr->it_interval && timr->it_signal_seq =3D=3D info->si_sys_private)= { timr->kclock->timer_rearm(timr); =20 - timr->it_active =3D 1; + timr->it_status =3D POSIX_TIMER_ARMED; timr->it_overrun_last =3D timr->it_overrun; timr->it_overrun =3D -1LL; ++timr->it_signal_seq; @@ -292,14 +292,17 @@ bool posixtimer_deliver_signal(struct kernel_siginfo = *info) =20 int posix_timer_queue_signal(struct k_itimer *timr) { + enum posix_timer_state state =3D POSIX_TIMER_DISARMED; int ret, si_private =3D 0; enum pid_type type; =20 lockdep_assert_held(&timr->it_lock); =20 - timr->it_active =3D 0; - if (timr->it_interval) + if (timr->it_interval) { + state =3D POSIX_TIMER_REQUEUE_PENDING; si_private =3D ++timr->it_signal_seq; + } + timr->it_status =3D state; =20 type =3D !(timr->it_sigev_notify & SIGEV_THREAD_ID) ? PIDTYPE_TGID : PIDT= YPE_PID; ret =3D send_sigqueue(timr->sigq, timr->it_pid, type, si_private); @@ -367,7 +370,7 @@ static enum hrtimer_restart posix_timer_fn(struct hrtim= er *timer) timr->it_overrun +=3D hrtimer_forward(timer, now, timr->it_interval); ret =3D HRTIMER_RESTART; ++timr->it_signal_seq; - timr->it_active =3D 1; + timr->it_status =3D POSIX_TIMER_ARMED; } } =20 @@ -647,10 +650,10 @@ void common_timer_get(struct k_itimer *timr, struct i= timerspec64 *cur_setting) /* interval timer ? */ if (iv) { cur_setting->it_interval =3D ktime_to_timespec64(iv); - } else if (!timr->it_active) { + } else if (timr->it_status =3D=3D POSIX_TIMER_DISARMED) { /* * SIGEV_NONE oneshot timers are never queued and therefore - * timr->it_active is always false. The check below + * timr->it_status is always DISARMED. The check below * vs. remaining time will handle this case. * * For all other timers there is nothing to update here, so @@ -895,7 +898,7 @@ int common_timer_set(struct k_itimer *timr, int flags, if (kc->timer_try_to_cancel(timr) < 0) return TIMER_RETRY; =20 - timr->it_active =3D 0; + timr->it_status =3D POSIX_TIMER_DISARMED; posix_timer_set_common(timr, new_setting); =20 /* Keep timer disarmed when it_value is zero */ @@ -908,7 +911,8 @@ int common_timer_set(struct k_itimer *timr, int flags, sigev_none =3D timr->it_sigev_notify =3D=3D SIGEV_NONE; =20 kc->timer_arm(timr, expires, flags & TIMER_ABSTIME, sigev_none); - timr->it_active =3D !sigev_none; + if (!sigev_none) + timr->it_status =3D POSIX_TIMER_ARMED; return 0; } =20 @@ -1007,7 +1011,7 @@ int common_timer_del(struct k_itimer *timer) timer->it_interval =3D 0; if (kc->timer_try_to_cancel(timer) < 0) return TIMER_RETRY; - timer->it_active =3D 0; + timer->it_status =3D POSIX_TIMER_DISARMED; return 0; } =20 diff --git a/kernel/time/posix-timers.h b/kernel/time/posix-timers.h index 4784ea65f685..4d09677e584e 100644 --- a/kernel/time/posix-timers.h +++ b/kernel/time/posix-timers.h @@ -1,6 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0 */ #define TIMER_RETRY 1 =20 +enum posix_timer_state { + POSIX_TIMER_DISARMED, + POSIX_TIMER_ARMED, + POSIX_TIMER_REQUEUE_PENDING, +}; + struct k_clock { int (*clock_getres)(const clockid_t which_clock, struct timespec64 *tp); From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8A395194138 for ; Fri, 27 Sep 2024 08:48:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426934; cv=none; b=a62o2fDrNYxFNOWBqlydztZRzns8/VbfbK5gB19wQAH6IVWumsywzXLn+e66odD17V0aPsOiWU3/NIpur7H0K0tH2iRy76fsJhQAEwuw3raJLUAYDkWsEkWf18ZYRTStgW57MlVIhgTkdmCp+cFW45q0jpBDW2IWBWA2/+9LFSI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426934; c=relaxed/simple; bh=kcnbNFf0PqRgHjX+kLb8eKf2yoh61nkQKKITQrvCz+E=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=E+5VaLQZmE6bdqQWUkZ84QNQALNNNbQiMp/A5einkF964rTWsRcx8+XensNv4USx499gTvuW5TeCOT2dKstrr0FkCpTkVh2qXjo4sPyLowScAA9ZqWd+p1GNmrVbqh0wZVRpybV8dfPa+Y2u4f+gSXgHLRIEcdwawzy2LtM0Ads= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=GxXjKeez; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=/tDPDNKL; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="GxXjKeez"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="/tDPDNKL" Message-ID: <20240927084817.449464642@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=S11ye5tLkZYHnPip+zXMdwlR8ANrj5PEcLf0WRbbImk=; b=GxXjKeezjSe0ico0FyVFThgbGB0cnTKGLO7xhu05KVXVqe8058B1m7dhE0CAm3Zp60Q81+ sBHuBGRXTYdGqVk2iBqM5ED2bJp2fcdbi4XXZYUph9R6d3wqJQ8X0bhfm/HlZ1L5/dbxW5 WsFShq4k/vYgj+Z+Ho/Ztv85IEeNu1ZJlfe+Og8WXSXNdsaaKmbWjc+Sr8iEDX4ZG2zFML t7zYbsZXq23LVkyiZLZpyREaHh2KGpUv1CWw0YQRQ8gfNthnRi4lZUYHIMJ6ZFhlQ1II9/ cxzelcwORfCbJ0oZNH8j2Uvkmaonwu7Tqz8GkKJcrXKcTzrbPWkjsWf2lWLWYA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426930; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=S11ye5tLkZYHnPip+zXMdwlR8ANrj5PEcLf0WRbbImk=; b=/tDPDNKLJ122BdU3KJ8pjVgq8+73Z/G1zm4LwPzNDm9LLJzUnx6e6USgRPjXV4Zh9Mmi5F 06NzzYp11eQuVlAQ== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 09/27] posix-timers: Make signal delivery consistent References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:50 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Signals of timers which are reprogammed, disarmed or deleted can deliver signals related to the past. The POSIX spec is blury about this: - "The effect of disarming or resetting a timer with pending expiration notifications is unspecified." - "The disposition of pending signals for the deleted timer is unspecified." In both cases it is reasonable to expect that pending signals are discarded. Especially in the reprogramming case it does not make sense to account for previous overruns or to deliver a signal for a timer which has been disarmed. This makes the behaviour consistent and understandable. Remove the si_sys_private check from the signal delivery code and invoke posix_timer_deliver_signal() unconditionally. Change that function so it controls the actual signal delivery via the return value. It now instructs the signal code to drop the signal when: 1) The timer does not longer exist in the hash table 2) The timer signal_seq value is not the same as the si_sys_private value which was set when the signal was queued. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 2 -- kernel/signal.c | 2 +- kernel/time/posix-cpu-timers.c | 2 +- kernel/time/posix-timers.c | 25 +++++++++++++++---------- 4 files changed, 17 insertions(+), 14 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 02afbb4da7f7..8c6d97412526 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -137,8 +137,6 @@ static inline void clear_posix_cputimers_work(struct ta= sk_struct *p) { } static inline void posix_cputimers_init_work(void) { } #endif =20 -#define REQUEUE_PENDING 1 - /** * struct k_itimer - POSIX.1b interval timer structure. * @list: List head for binding the timer to signals->posix_timers diff --git a/kernel/signal.c b/kernel/signal.c index c35b6ff52767..a407724f1267 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -617,7 +617,7 @@ int dequeue_signal(sigset_t *mask, kernel_siginfo_t *in= fo, enum pid_type *type) } =20 if (IS_ENABLED(CONFIG_POSIX_TIMERS)) { - if (unlikely(info->si_code =3D=3D SI_TIMER && info->si_sys_private)) { + if (unlikely(info->si_code =3D=3D SI_TIMER)) { if (!posixtimer_deliver_signal(info)) goto again; } diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index 12f828d704b1..bc2cd32b7a40 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -746,7 +746,7 @@ static void __posix_cpu_timer_get(struct k_itimer *time= r, struct itimerspec64 *i * - Timers which expired, but the signal has not yet been * delivered */ - if (iv && ((timer->it_signal_seq & REQUEUE_PENDING) || sigev_none)) + if (iv && timer->it_status !=3D POSIX_TIMER_ARMED) expires =3D bump_cpu_timer(timer, now); else expires =3D cpu_timer_getexpires(&timer->it.cpu); diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 6f0dacec25e0..1231efb7c30f 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -269,7 +269,10 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *= info) if (!timr) goto out; =20 - if (timr->it_interval && timr->it_signal_seq =3D=3D info->si_sys_private)= { + if (timr->it_signal_seq !=3D info->si_sys_private) + goto out_unlock; + + if (timr->it_interval && timr->it_status =3D=3D POSIX_TIMER_REQUEUE_PENDI= NG) { timr->kclock->timer_rearm(timr); =20 timr->it_status =3D POSIX_TIMER_ARMED; @@ -281,6 +284,7 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *i= nfo) } ret =3D true; =20 +out_unlock: unlock_timer(timr, flags); out: spin_lock(¤t->sighand->siglock); @@ -293,19 +297,19 @@ bool posixtimer_deliver_signal(struct kernel_siginfo = *info) int posix_timer_queue_signal(struct k_itimer *timr) { enum posix_timer_state state =3D POSIX_TIMER_DISARMED; - int ret, si_private =3D 0; enum pid_type type; + int ret; =20 lockdep_assert_held(&timr->it_lock); =20 if (timr->it_interval) { + timr->it_signal_seq++; state =3D POSIX_TIMER_REQUEUE_PENDING; - si_private =3D ++timr->it_signal_seq; } timr->it_status =3D state; =20 type =3D !(timr->it_sigev_notify & SIGEV_THREAD_ID) ? PIDTYPE_TGID : PIDT= YPE_PID; - ret =3D send_sigqueue(timr->sigq, timr->it_pid, type, si_private); + ret =3D send_sigqueue(timr->sigq, timr->it_pid, type, timr->it_signal_seq= ); /* If we failed to send the signal the timer stops. */ return ret > 0; } @@ -670,7 +674,7 @@ void common_timer_get(struct k_itimer *timr, struct iti= merspec64 *cur_setting) * is a SIGEV_NONE timer move the expiry time forward by intervals, * so expiry is > now. */ - if (iv && (timr->it_signal_seq & REQUEUE_PENDING || sig_none)) + if (iv && timr->it_status !=3D POSIX_TIMER_ARMED) timr->it_overrun +=3D kc->timer_forward(timr, now); =20 remaining =3D kc->timer_remaining(timr, now); @@ -870,8 +874,6 @@ void posix_timer_set_common(struct k_itimer *timer, str= uct itimerspec64 *new_set else timer->it_interval =3D 0; =20 - /* Prevent reloading in case there is a signal pending */ - timer->it_signal_seq =3D (timer->it_signal_seq + 2) & ~REQUEUE_PENDING; /* Reset overrun accounting */ timer->it_overrun_last =3D 0; timer->it_overrun =3D -1LL; @@ -889,8 +891,6 @@ int common_timer_set(struct k_itimer *timr, int flags, if (old_setting) common_timer_get(timr, old_setting); =20 - /* Prevent rearming by clearing the interval */ - timr->it_interval =3D 0; /* * Careful here. On SMP systems the timer expiry function could be * active and spinning on timr->it_lock. @@ -940,6 +940,9 @@ static int do_timer_settime(timer_t timer_id, int tmr_f= lags, if (old_spec64) old_spec64->it_interval =3D ktime_to_timespec64(timr->it_interval); =20 + /* Prevent signal delivery and rearming. */ + timr->it_signal_seq++; + kc =3D timr->kclock; if (WARN_ON_ONCE(!kc || !kc->timer_set)) error =3D -EINVAL; @@ -1008,7 +1011,6 @@ int common_timer_del(struct k_itimer *timer) { const struct k_clock *kc =3D timer->kclock; =20 - timer->it_interval =3D 0; if (kc->timer_try_to_cancel(timer) < 0) return TIMER_RETRY; timer->it_status =3D POSIX_TIMER_DISARMED; @@ -1036,6 +1038,9 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) if (!timer) return -EINVAL; =20 + /* Prevent signal delivery and rearming. */ + timer->it_signal_seq++; + if (unlikely(timer_delete_hook(timer) =3D=3D TIMER_RETRY)) { /* Unlocks and relocks the timer if it still exists */ timer =3D timer_wait_running(timer, &flags); From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 1E02418A6C6 for ; Fri, 27 Sep 2024 08:48:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426936; cv=none; b=KRsyv7sJypKp7pXWW7gnMC15hmIo8rAMuylgWLXhAvmiqKDu1U46UEQclJnUbA/9B/XUcx7ulC4yCgSVmFBySTthFVNTN8BvxzQBtwxF+nKf2M1Ly/k43QI4xBjmuLP2v8h1GXRMwx2ixoPzqC0gfRYf9yNwS3yuZ0K1TPAe0Lg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426936; c=relaxed/simple; bh=qdJDQEzOOu3OZFRx5A7UAJYAHMf5/XE2Ts3qnk+RTFg=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=dluEIs+tG8+zJ5xWPHb5sA70SS7A3P2wEQAxcUFm/t33hmbjJFNH6l3GuJ/Olb/nDI05qC7m5drwHKbZPIOM5iSvB7FXaFKlK40SQD4NWD8KHX8oQakaOCGXLLYJX0y1LDLgpRlLylga8zdTpeEY4A4+A+/q+CJyOCrAZx4ZjEs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qOB0QE2m; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=d5MX4JU0; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qOB0QE2m"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="d5MX4JU0" Message-ID: <20240927084817.512919719@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=4HNgn73tHuuvjYhUziBtvcDe9dnmdw0DM+iGVaf6dzo=; b=qOB0QE2my4mnax7hznpSbrCrxGgatXit6BG/XYKTMSNnVA4kvdlEuBTQwLLuDnUPG/EOle 5CFXDH/ENj91Wp1wzcJtvgE8ljkKLY637t6Wo2C+nG7UDcnet3x8y8NMJb3DN4Kiw629sm 8w+9pUNZEAmO2fywragL7UuRJ7QEUfXMkainf/k8xUx0l+lYY1c+dUoA0LTcEy7PVecz4j T1IeRz6bPX/CplCpqjUYmpOXYxjPmhDmJrVjmg7pApD2icTWRSOlHRa6EGz0JmvoemQNI8 RwibIu7BNnViq3d+9bF1XUS0DeZeft5Wb2nyBBoDZXTlmg6tmy/e9TmWmeyt4g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426931; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=4HNgn73tHuuvjYhUziBtvcDe9dnmdw0DM+iGVaf6dzo=; b=d5MX4JU0BogCF0yG4x9PY7vVUyH4NoFUAqKAnVr3HnWiGkMCnzRYfdzqpb0N1A2a5IIrRz pnUzRiVb3vUUcFCw== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 10/27] posix-timers: Make signal overrun accounting sensible References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:51 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner The handling of the timer overrun in the signal code is inconsistent as it takes previous overruns into account. This is just wrong as after the reprogramming of a timer the overrun count starts over from a clean state, i.e. 0. Make the accounting in send_sigqueue() consistent with that. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- kernel/signal.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) --- diff --git a/kernel/signal.c b/kernel/signal.c index a407724f1267..a99274287902 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1961,6 +1961,34 @@ int send_sigqueue(struct sigqueue *q, struct pid *pi= d, enum pid_type type, int s */ q->info.si_sys_private =3D si_private; =20 + /* + * Set the overrun count to zero unconditionally. The posix timer + * code does not self rearm periodic timers. They are rearmed from + * dequeue_signal(). + * + * But there is a situation where @q is already enqueued: + * + * 1) timer_settime() + * arm_timer() + * 2) timer_expires() + * send_sigqueue(@q) + * enqueue(@q) + * 3) timer_settime() + * arm_timer() + * 4) timer_expires() + * send_sigqueue(@q) <- Observes @q already queued + * + * In this case incrementing si_overrun does not make sense because + * there is no relationship between timer_settime() #1 and #2. + * + * The POSIX specification is useful as always: "The effect of + * disarming or resetting a timer with pending expiration + * notifications is unspecified." + * + * Just do the sensible thing and reset the overrun. + */ + q->info.si_overrun =3D 0; + ret =3D 1; /* the signal is ignored */ result =3D TRACE_SIGNAL_IGNORED; if (!prepare_signal(sig, t, false)) @@ -1968,15 +1996,9 @@ int send_sigqueue(struct sigqueue *q, struct pid *pi= d, enum pid_type type, int s =20 ret =3D 0; if (unlikely(!list_empty(&q->list))) { - /* - * If an SI_TIMER entry is already queue just increment - * the overrun count. - */ - q->info.si_overrun++; result =3D TRACE_SIGNAL_ALREADY_PENDING; goto out; } - q->info.si_overrun =3D 0; =20 signalfd_notify(t, sig); pending =3D (type !=3D PIDTYPE_PID) ? &t->signal->shared_pending : &t->pe= nding; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2974C1B07B2 for ; Fri, 27 Sep 2024 08:48:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426935; cv=none; b=TWtSK+3VB71nBUVjohLPLWcPaKczhNvnCkq3651beQsjO/QjKXIrM0hvbmzFFRkkajg8jbtmpI86+hSh65+6uz/sZyWQ4/aNpS0ZuCUT5Hi9v+dHadi6+tJ/ScPDRHVBboU6Ez9jv35hBkt1/OR99aThnf+xbX3w/DNR+GGA4w0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426935; c=relaxed/simple; bh=JS8OTIugV54U4c9TnOdGFMqXhSz/nJrdTvMchyD+w/M=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=RwKadS9JkYnlrmooP0w/U8UK6FZc1vkpk9Y+FlMjzB2xzgaNJl0YZeme6IQD1C9S4pHoy0Li8MmuYirMWvGpNUagYysu9hXdPhYHGLACii7SlgGNpHh1/6rxJmkMpHv5SGZb343NZIFGvBSa44VL4kbIdMgjrNxZjiopgVR+uCw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=hvH70WKl; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=kE9l8ejV; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="hvH70WKl"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="kE9l8ejV" Message-ID: <20240927084817.574566710@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=KgET3aIT9+OZMdI/ErQ6Q2EVM4fWSh0RVcwU7MumU1s=; b=hvH70WKlWaFoy9bj9Sgw3w/MNFQCjofPpIHt9YELmRARDIFwI9s1Sh2ooPwm7eetsb2X7s HPk3zpBaWwfH84dx3haOtT/iCItrta4jG1QVYxzSK1fkEVzYcsL19Jmjw4DLT3WV7S6buF U0lNI1ZQaVSuT7Uu//JQL9uVCXpnI3coJoaHugZhpCyP1Rn98dPBypqeSRCm3MBPc4oY60 dlIyPS/8VdpdB9FDqT0E18yWbvGR3Zy67bJvUxL1Fi/9h3PRGXgiKDwmm6MU4YHLo0cnOe 6cOkB11cAM0cGxmSY0bxZMl08lHFglLL4+08kaYzHx1tuSso3et+Tv8RMqtxyw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426932; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=KgET3aIT9+OZMdI/ErQ6Q2EVM4fWSh0RVcwU7MumU1s=; b=kE9l8ejVONf+ZP2MJ4v0C67x0GtN0KRaeBwK61NqxvSz6gJexzbHIfZbtCaZxepbbK4pM7 1FQzOQIX+Ew9H6Bw== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 11/27] posix-cpu-timers: Use dedicated flag for CPU timer nanosleep References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:52 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner POSIX CPU timer nanosleep creates a k_itimer on stack and uses the sigq pointer to detect the nanosleep case in the expiry function. Prepare for embedding sigqueue into struct k_itimer by using a dedicated flag for nanosleep. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 4 +++- kernel/time/posix-cpu-timers.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 8c6d97412526..bcd01208d795 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -42,6 +42,7 @@ static inline int clockid_to_fd(const clockid_t clk) * @pid: Pointer to target task PID * @elist: List head for the expiry list * @firing: Timer is currently firing + * @nanosleep: Timer is used for nanosleep and is not a regular posix-timer * @handling: Pointer to the task which handles expiry */ struct cpu_timer { @@ -49,7 +50,8 @@ struct cpu_timer { struct timerqueue_head *head; struct pid *pid; struct list_head elist; - int firing; + bool firing; + bool nanosleep; struct task_struct __rcu *handling; }; =20 diff --git a/kernel/time/posix-cpu-timers.c b/kernel/time/posix-cpu-timers.c index bc2cd32b7a40..ea1835cb541a 100644 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -588,7 +588,7 @@ static void cpu_timer_fire(struct k_itimer *timer) =20 timer->it_status =3D POSIX_TIMER_DISARMED; =20 - if (unlikely(timer->sigq =3D=3D NULL)) { + if (unlikely(ctmr->nanosleep)) { /* * This a special case for clock_nanosleep, * not a normal timer from sys_timer_create. @@ -1479,6 +1479,7 @@ static int do_cpu_nanosleep(const clockid_t which_clo= ck, int flags, timer.it_overrun =3D -1; error =3D posix_cpu_timer_create(&timer); timer.it_process =3D current; + timer.it.cpu.nanosleep =3D true; =20 if (!error) { static struct itimerspec64 zero_it; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9E2411B1408 for ; Fri, 27 Sep 2024 08:48:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426937; cv=none; b=YhmkEefTw/UiC/MxaJM1CxYX11J8hK0K7r1EzkiEQZr+0zofKVu1fK1cXhVJXCK21m/SJDnuUOSpHGgg6VE1bNsebBFY5/x26mbUpkS2Ab4wvHJ4dlJ3Y56drnCOZ/GFAXpOjv18EaA3esCPsfm3OXl9z+EVuHPnD1+Nlzb4cLM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426937; c=relaxed/simple; bh=bqKMIW20BvE93+TTGpef15PeydDZXZdPbYIig5eo5rs=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=T8HDRc4gokva2gnMie8fUZAtClgROoE145bzSHjoSYvNIMmMLd27TgZHov0uyJ0GPB3AIJkYjohKx/Zsqizy6FLab/WYPGP3KjB4BkCINfNhvM5c48LlKdTrkJqU/hBTmRF3Mj1z7jNCeHIHYbMWPY8eFmHxDDYY2xsL63TzjcE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=P1BgWwB+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=qq56EgBf; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="P1BgWwB+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="qq56EgBf" Message-ID: <20240927084817.635782665@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426934; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=1s4/+wgUFt/xsHtMm50Sqp9rImc2F37Rzip7gGAsmzM=; b=P1BgWwB+0j+DyGvl/E8dK0s9s/9HYgFtD1CJd2blCEHoJSVygT8tsWzfLjnFWGnA7K5T/8 M6ywSUGr8+FYUdKvuXl1ajXT6lnd96hoCagFdP7mVIREdaTIhxExQN0D1PlslUagarqUsH pg2GP0h8KzpopAtg8TmQhnUSgiI26g/sH0ZuYslxvOFkkQxVtyJcFaXrC9G+J40D0Lxp9T mjb2bOGPsJwcCzW+/leQT/ycid4r8gnoaXrcU96AbSSzCdFuFbiUm87CrdWnQiWB5Tggx7 X3eIgmKm0FN5hjJzarupWv2RDgtiHFPuSbYen/arxlZAktoIHRA+8/gFs59MjQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426934; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=1s4/+wgUFt/xsHtMm50Sqp9rImc2F37Rzip7gGAsmzM=; b=qq56EgBfkfmoN3A9FAu6kKf2nFpRp2Am0DoyaYmfwRmLoDuT3dGwXQHY9PjKPiDYCn0wy6 b4MTSGwMyueKIDCg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 12/27] posix-timers: Add a refcount to struct k_itimer References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:53 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To cure the SIG_IGN handling for posix interval timers, the preallocated sigqueue needs to be embedded into struct k_itimer to prevent life time races of all sorts. To make that work correctly it needs reference counting so that timer deletion does not free the timer prematuraly when there is a signal queued or delivered concurrently. Add a rcuref to the posix timer part. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 14 ++++++++++++++ kernel/time/posix-timers.c | 7 ++++--- 2 files changed, 18 insertions(+), 3 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index bcd01208d795..9740fd0c2933 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -6,11 +6,13 @@ #include #include #include +#include #include #include =20 struct kernel_siginfo; struct task_struct; +struct k_itimer; =20 static inline clockid_t make_process_cpuclock(const unsigned int pid, const clockid_t clock) @@ -105,6 +107,7 @@ static inline void posix_cputimers_rt_watchdog(struct p= osix_cputimers *pct, =20 void posixtimer_rearm_itimer(struct task_struct *p); bool posixtimer_deliver_signal(struct kernel_siginfo *info); +void posixtimer_free_timer(struct k_itimer *timer); =20 /* Init task static initializer */ #define INIT_CPU_TIMERBASE(b) { \ @@ -129,6 +132,7 @@ static inline void posix_cputimers_group_init(struct po= six_cputimers *pct, u64 cpu_limit) { } static inline void posixtimer_rearm_itimer(struct task_struct *p) { } static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info) = { return false; } +static inline void posixtimer_free_timer(struct k_itimer *timer) { } #endif =20 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK @@ -156,6 +160,7 @@ static inline void posix_cputimers_init_work(void) { } * @it_signal: Pointer to the creators signal struct * @it_pid: The pid of the process/task targeted by the signal * @it_process: The task to wakeup on clock_nanosleep (CPU timers) + * @rcuref: Reference count for life time management * @sigq: Pointer to preallocated sigqueue * @it: Union representing the various posix timer type * internals. @@ -180,6 +185,7 @@ struct k_itimer { struct task_struct *it_process; }; struct sigqueue *sigq; + rcuref_t rcuref; union { struct { struct hrtimer timer; @@ -200,4 +206,12 @@ void set_process_cpu_timer(struct task_struct *task, u= nsigned int clock_idx, =20 int update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); =20 +#ifdef CONFIG_POSIX_TIMERS +static inline void posixtimer_putref(struct k_itimer *tmr) +{ + if (rcuref_put(&tmr->rcuref)) + posixtimer_free_timer(tmr); +} +#endif /* !CONFIG_POSIX_TIMERS */ + #endif diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 1231efb7c30f..1c2f6090b767 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -417,6 +417,7 @@ static struct k_itimer * alloc_posix_timer(void) return NULL; } clear_siginfo(&tmr->sigq->info); + rcuref_init(&tmr->rcuref, 1); return tmr; } =20 @@ -427,7 +428,7 @@ static void k_itimer_rcu_free(struct rcu_head *head) kmem_cache_free(posix_timers_cache, tmr); } =20 -static void posix_timer_free(struct k_itimer *tmr) +void posixtimer_free_timer(struct k_itimer *tmr) { put_pid(tmr->it_pid); sigqueue_free(tmr->sigq); @@ -439,7 +440,7 @@ static void posix_timer_unhash_and_free(struct k_itimer= *tmr) spin_lock(&hash_lock); hlist_del_rcu(&tmr->t_hash); spin_unlock(&hash_lock); - posix_timer_free(tmr); + posixtimer_putref(tmr); } =20 static int common_timer_create(struct k_itimer *new_timer) @@ -474,7 +475,7 @@ static int do_timer_create(clockid_t which_clock, struc= t sigevent *event, */ new_timer_id =3D posix_timer_add(new_timer); if (new_timer_id < 0) { - posix_timer_free(new_timer); + posixtimer_free_timer(new_timer); return new_timer_id; } From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E6CEC18A6DD for ; Fri, 27 Sep 2024 08:48:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426938; cv=none; b=eDWVBTkVwJ9J4VrABz4LD7CmYWODIvJdWYp5cCNIr4CLIpvJltQJFxU82Pk0gFEPD24lsd6hWRX8lrmK7dvCciEoEqzqnnh3ITCFNlf9p19BCDEeaxbSPKYjDyxK1CaA7u483wBTbFtpcaaUNeZ4ix8r3nThbwRGwbxkboCF5Ao= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426938; c=relaxed/simple; bh=DfYL3+3SFLsU0hRcuOo4JWa93YLYDt/I9LNPYUckKaw=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=Lj4gXxxWwQjgxCBgWBebl+dQ9cgvj4vWiIib/rl1o5LoT9lHgJBL4lX/NQOtxIXu8+0c38eD5KwN0cFCQ2FtJ1bE0D++rWk+nVB2d4hxvzrDPUngpiJszuWKDb+8mPPzgyWXUPq580mfGLQepUtTBQOVyUlo9dstpl+/2IiYB7E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Rd+IIPCa; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=NoQcX64W; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Rd+IIPCa"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="NoQcX64W" Message-ID: <20240927084817.696404991@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426935; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=WYlva8bmBHl4f8vOKzz3cvfxu2ebItKHVNkITds+FdQ=; b=Rd+IIPCa4FwE09bRT9JG+4cNspjKEBYa1LNJ5AqEXkLkAmbzgqtOSIcd4z6wh6qlWUrG6O fIS44GoBXCKxckiPuAS6rRCBbMFi8tF4DCngkXHSHdgOblL8S35uQXHhe/18Ueg7CHfePs MWZIHtHkXGHVyK2o7iHosx/Di1FfwCYvag3y4rUBTHdg61jWMhORMa3NqYpffg6s7nAFUM 3+9aFgTFkKR7kucVVQtTBCvIiPvKxIf5fRk1z5B3b4GcpLCF4J1vG0Dx8Ue7EOWqNAeFCo SYGIu7vNx3oqFQWsF1TY25f4yFsqtTrwGRdGpTVu/oZUzdq3uOHvpEoa+iA8ng== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426935; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=WYlva8bmBHl4f8vOKzz3cvfxu2ebItKHVNkITds+FdQ=; b=NoQcX64WCgiNHOKX+hppsmS+nd/ABdCOBYGCDClGtqDrwofq8Wu8lJrHB7Zu5Gjz4w7mWp K6+BHgjkPkX5qRCQ== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 13/27] signal: Split up __sigqueue_alloc() References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:55 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To cure the SIG_IGN handling for posix interval timers, the preallocated sigqueue needs to be embedded into struct k_itimer to prevent life time races of all sorts. Reorganize __sigqueue_alloc() so the ucounts retrieval and the initialization can be used independently. No functional change. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- kernel/signal.c | 52 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 17 deletions(-) --- diff --git a/kernel/signal.c b/kernel/signal.c index a99274287902..87c349a2ddf7 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -396,16 +396,9 @@ void task_join_group_stop(struct task_struct *task) task_set_jobctl_pending(task, mask | JOBCTL_STOP_PENDING); } =20 -/* - * allocate a new signal queue record - * - this may be called without locks if and only if t =3D=3D current, oth= erwise an - * appropriate lock must be held to stop the target task from exiting - */ -static struct sigqueue * -__sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags, - int override_rlimit, const unsigned int sigqueue_flags) +static struct ucounts *sig_get_ucounts(struct task_struct *t, int sig, + int override_rlimit) { - struct sigqueue *q =3D NULL; struct ucounts *ucounts; long sigpending; =20 @@ -424,19 +417,44 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_= t gfp_flags, if (!sigpending) return NULL; =20 - if (override_rlimit || likely(sigpending <=3D task_rlimit(t, RLIMIT_SIGPE= NDING))) { - q =3D kmem_cache_alloc(sigqueue_cachep, gfp_flags); - } else { + if (unlikely(!override_rlimit && sigpending > task_rlimit(t, RLIMIT_SIGPE= NDING))) { + dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING); print_dropped_signal(sig); + return NULL; } =20 - if (unlikely(q =3D=3D NULL)) { + return ucounts; +} + +static void __sigqueue_init(struct sigqueue *q, struct ucounts *ucounts, + const unsigned int sigqueue_flags) +{ + INIT_LIST_HEAD(&q->list); + q->flags =3D sigqueue_flags; + q->ucounts =3D ucounts; +} + +/* + * allocate a new signal queue record + * - this may be called without locks if and only if t =3D=3D current, oth= erwise an + * appropriate lock must be held to stop the target task from exiting + */ +static struct sigqueue *__sigqueue_alloc(int sig, struct task_struct *t, g= fp_t gfp_flags, + int override_rlimit, const unsigned int sigqueue_flags) +{ + struct ucounts *ucounts =3D sig_get_ucounts(t, sig, override_rlimit); + struct sigqueue *q; + + if (!ucounts) + return NULL; + + q =3D kmem_cache_alloc(sigqueue_cachep, gfp_flags); + if (!q) { dec_rlimit_put_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING); - } else { - INIT_LIST_HEAD(&q->list); - q->flags =3D sigqueue_flags; - q->ucounts =3D ucounts; + return NULL; } + + __sigqueue_init(q, ucounts, sigqueue_flags); return q; } From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CAB4C1B1518 for ; Fri, 27 Sep 2024 08:48:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426939; cv=none; b=KHDPJb23sIAwaT9baisSu7Nf/nnm0Za0osuxIrzGszJCSSsAiTUfNdSuHm57GuSldi3IExO0Td6toV3QSbcGc1pGrC1MxYXnpnfhcOD4cDSFC3CcPMHu55123xH8anGxfSL4FbaFi/IlJ68NbJucLwjYRoDo2gsGeyqwTf3q1R8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426939; c=relaxed/simple; bh=Lv8sWAH1reiYtjOeVwcDxBTN4hpZA4BEb9kDGDSeenY=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=rxwW+IOIGnep1ONQM3NC2L0KfbAxhH3m4r3+ZvMA8QYL+tbUmhvi/HnfC83cKbVfztTczrPsdWpMlNm9Mo3FtDfhNyAK26H3sOAT1wTCIgK/T8a9+IuMRiWKy45NBAgoiXJmWQzl7y2LiE34J2vuvqSQbuvRukswF7bY37E3e04= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=EacqyRwx; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Z2hN6d6R; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="EacqyRwx"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Z2hN6d6R" Message-ID: <20240927084817.757075875@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=CGcYe5MF339xP0ZdHat0PZB/Z0z3pouUAaoRRU1aupE=; b=EacqyRwx9nAeM31BglomV+QxI+23tza1QsfPg4rUwTLi7Fp1qUmJb70L7KHc4cqoF3iweO FVuu58qtlsDhjrGltKTKdG7NNd7vWjAoy1fesvck5Rv71H1d0G43Ds9mPRHYnlTJZqONeS /GDQNRr4WElRJojyeKYDziAejecSO5mGFkth4nWaxVNCb/Mj8lfesbeA1b0pSWeSjvu0uG hmkq2Y/4U34gyze4VsBpRY3KYZcDGEAVp36wrBa3d8eW9Y5KNASVDhIUN1qWxkZhLWu3Yt 0ZkGVLKv42sSFpToiIHq2/2wfeWQlhl0NwD3sbXlt4bBWrk9NnJ12L2/oRSXwQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426936; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=CGcYe5MF339xP0ZdHat0PZB/Z0z3pouUAaoRRU1aupE=; b=Z2hN6d6R+Y/YtPYp5sfHiZN+UMbkOiNcyzY2A3+W08JrjK0o85xye/986OFoRIcAS/E4YO vHd+dE0BgVsYAiCA== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 14/27] signal: Provide posixtimer_sigqueue_init() References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:56 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To cure the SIG_IGN handling for posix interval timers, the preallocated sigqueue needs to be embedded into struct k_itimer to prevent life time races of all sorts. Provide a new function to initialize the embedded sigqueue to prepare for that. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 2 ++ kernel/signal.c | 11 +++++++++++ 2 files changed, 13 insertions(+) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 9740fd0c2933..200098d27cc0 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -12,6 +12,7 @@ =20 struct kernel_siginfo; struct task_struct; +struct sigqueue; struct k_itimer; =20 static inline clockid_t make_process_cpuclock(const unsigned int pid, @@ -106,6 +107,7 @@ static inline void posix_cputimers_rt_watchdog(struct p= osix_cputimers *pct, } =20 void posixtimer_rearm_itimer(struct task_struct *p); +bool posixtimer_init_sigqueue(struct sigqueue *q); bool posixtimer_deliver_signal(struct kernel_siginfo *info); void posixtimer_free_timer(struct k_itimer *timer); =20 diff --git a/kernel/signal.c b/kernel/signal.c index 87c349a2ddf7..a857f6628e77 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1905,6 +1905,17 @@ void flush_itimer_signals(void) __flush_itimer_signals(&tsk->signal->shared_pending); } =20 +bool posixtimer_init_sigqueue(struct sigqueue *q) +{ + struct ucounts *ucounts =3D sig_get_ucounts(current, -1, 0); + + if (!ucounts) + return false; + clear_siginfo(&q->info); + __sigqueue_init(q, ucounts, SIGQUEUE_PREALLOC); + return true; +} + struct sigqueue *sigqueue_alloc(void) { return __sigqueue_alloc(-1, current, GFP_KERNEL, 0, SIGQUEUE_PREALLOC); From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7285E1B1D70 for ; Fri, 27 Sep 2024 08:48:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426941; cv=none; b=pFa9EGu08TtpwuljvKdLC4bsK1mKQZTctY9go24nxRZ9zod4rZZKzV6skYp3cLqa5gNIyT5ga6/yn6TXJTbr5BT7DXjud2OCeMEhfbnbLm5+uOk/b2F/TmZGNr3dFPxd7kFo1Y41h4sKIlMX3dZ5idtjmJZ9K6tTSAgbkN7jP5g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426941; c=relaxed/simple; bh=PEewBGulmZPu8ZHmUN61qpWbDO61m5TTGTWBqYAmiHk=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=FKLorChlxDGLGcrBeOiWBoOMYWUrQLYcbyNYhdoJIOUTcxnqQftCId5SXvwhw+3xuZGFJlnXGJ5IMImXIsdgVL2DjwfMCLxJhm7Xbsj73eoONKcU8FAJjOZTM1cBHFdP+BZALO5OajdSKZrPSyaMlBr7xD8T5NFDsyzzS72QzHI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=lDl6umro; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1c+LurNi; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="lDl6umro"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1c+LurNi" Message-ID: <20240927084817.817985972@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426937; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=nrmvUR0qb/rc4yHapT27FFgcyIjEIsAuloH4m+uCF3Q=; b=lDl6umroqt5gVInyd2xf630fxe1xOesJxiPOhOMAGovmIQVcNhH6YnT098Z774kwICgZBO yEmt3rYwRj4NnScjY/3f0oIQHfHxDQDuxHfipVV6RnMsOQkFrvVvKpLnFSXVamiYlAGTSR MTE0NboyBlYaTk1MG5cUzMf5KKk6wcp4xF3fKU0GuGdYn6huliw3n8btIn8QtqYu/ZG3P/ 5rmFyHYZu1Hhb8eppp3czNeP2fHCMGM7DDFVKDNiMNhPf4QrdqKo03o5q14jFKuk2sRsQv ehndz/6h9CHeZ3Hh2DdlTJGCS/arUe4zmQ9nFhnv4LxfD6EcL7OJa/iwVSfUhg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426937; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=nrmvUR0qb/rc4yHapT27FFgcyIjEIsAuloH4m+uCF3Q=; b=1c+LurNiqb+61JWPQOnr5+rjYlcW/d4t8V2CKcOHU5ZWy6SthzluriNRMYnFO0opHigplx HFM8DN90bVFtq6Bg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 15/27] signal: Add sys_private_ptr to siginfo::_sifields:: _timer References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:57 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner On signal delivery collect_signal() copies the queued siginfo into a caller provided siginfo struct. The posix timer signal delivery code then uses siginfo::si_tid to lookup the timer in the hash table. That's required today as the timer and the sigqueue are separate entities and have different life time rules. The sigqueue will be embedded into struct k_itimer to address a few issues in the posix timer signal handling, which means the life time rules are not longer separate, which can spare the lookup. Due to locking rules posixtimer_deliver_signal() cannot be invoked from collect_signal(). The timer pointer could be handed down from collect_signal() to dequeue_signal(), but that's just overhead for the non-posixtimer case. There is room in the _sifields union for an extra pointer which will be used later for storing the timer pointer. This field is copied with siginfo and cleared before the info is delivered to userspace like the existing si_sys_private field. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- arch/x86/kernel/signal_32.c | 2 +- arch/x86/kernel/signal_64.c | 2 +- include/uapi/asm-generic/siginfo.h | 2 ++ kernel/signal.c | 6 ++++-- kernel/time/posix-timers.c | 4 +++- 5 files changed, 11 insertions(+), 5 deletions(-) --- diff --git a/arch/x86/kernel/signal_32.c b/arch/x86/kernel/signal_32.c index ef654530bf5a..34ce839ed4ff 100644 --- a/arch/x86/kernel/signal_32.c +++ b/arch/x86/kernel/signal_32.c @@ -456,7 +456,7 @@ CHECK_SI_OFFSET(_timer); /* compat_siginfo_t doesn't have si_sys_private */ CHECK_SI_SIZE (_timer, 3*sizeof(int)); #else -CHECK_SI_SIZE (_timer, 4*sizeof(int)); +CHECK_SI_SIZE (_timer, 5*sizeof(int)); #endif static_assert(offsetof(siginfo32_t, si_tid) =3D=3D 0x0C); static_assert(offsetof(siginfo32_t, si_overrun) =3D=3D 0x10); diff --git a/arch/x86/kernel/signal_64.c b/arch/x86/kernel/signal_64.c index 8a94053c5444..dd96b7f3f60c 100644 --- a/arch/x86/kernel/signal_64.c +++ b/arch/x86/kernel/signal_64.c @@ -462,7 +462,7 @@ static_assert(offsetof(siginfo_t, si_pid) =3D=3D 0x10); static_assert(offsetof(siginfo_t, si_uid) =3D=3D 0x14); =20 CHECK_SI_OFFSET(_timer); -CHECK_SI_SIZE (_timer, 6*sizeof(int)); +CHECK_SI_SIZE (_timer, 8*sizeof(int)); static_assert(offsetof(siginfo_t, si_tid) =3D=3D 0x10); static_assert(offsetof(siginfo_t, si_overrun) =3D=3D 0x14); static_assert(offsetof(siginfo_t, si_value) =3D=3D 0x18); diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/= siginfo.h index b7bc545ec3b2..702d7d3ca117 100644 --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h @@ -47,6 +47,7 @@ union __sifields { int _overrun; /* overrun count */ sigval_t _sigval; /* same as below */ int _sys_private; /* not to be passed to user */ + void *_sys_privptr; /* not to be passed to user */ } _timer; =20 /* POSIX.1b signals */ @@ -146,6 +147,7 @@ typedef struct siginfo { #define si_tid _sifields._timer._tid #define si_overrun _sifields._timer._overrun #define si_sys_private _sifields._timer._sys_private +#define si_sys_privptr _sifields._timer._sys_privptr #define si_status _sifields._sigchld._status #define si_utime _sifields._sigchld._utime #define si_stime _sifields._sigchld._stime diff --git a/kernel/signal.c b/kernel/signal.c index a857f6628e77..0aa01eec5e2d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -3410,12 +3410,14 @@ static int post_copy_siginfo_from_user(kernel_sigin= fo_t *info, const siginfo_t __user *from) { /* - * Clear the si_sys_private field for timer signals as that's the + * Clear the si_sys_priv* fields for timer signals as that's the * indicator for rearming a posix timer. User space submitted * signals are not allowed to inject that. */ - if (info->si_code =3D=3D SI_TIMER) + if (info->si_code =3D=3D SI_TIMER) { info->si_sys_private =3D 0; + info->si_sys_privptr =3D NULL; + } =20 if (unlikely(!known_siginfo_layout(info->si_signo, info->si_code))) { char __user *expansion =3D si_expansion(from); diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 1c2f6090b767..9d7e02db4157 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -289,8 +289,9 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *i= nfo) out: spin_lock(¤t->sighand->siglock); =20 - /* Don't expose the si_sys_private value to userspace */ + /* Don't expose the si_sys_priv* values to userspace */ info->si_sys_private =3D 0; + info->si_sys_privptr =3D NULL; return ret; } =20 @@ -505,6 +506,7 @@ static int do_timer_create(clockid_t which_clock, struc= t sigevent *event, =20 new_timer->sigq->info.si_tid =3D new_timer->it_id; new_timer->sigq->info.si_code =3D SI_TIMER; + new_timer->sigq->info.si_sys_privptr =3D new_timer; =20 if (copy_to_user(created_timer_id, &new_timer_id, sizeof (new_timer_id)))= { error =3D -EFAULT; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8702B1B2512 for ; Fri, 27 Sep 2024 08:49:00 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426942; cv=none; b=X8WTTrq9EtqIrJPYwbV6QgVY03HuI2uDFW56+VxOKsRjD1/xtB3WUdaDHqAGHJje+TDEm7kMmla0pmBK+78wChFwswN8wgnjQ6fD8t/qe58FPGD4wehfECPV5/G8o8Sa8fxGtS/iEpwVQt5jS+pr5c75/5NJOdfXad3Y7c98NFA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426942; c=relaxed/simple; bh=EaiBFn5ykFkyn3SnqsoIh2Ch8Km5zazOeHvVJZ17+p0=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=dZ3UTNQE9hfRyjhipfIKiQ+Lay7cm5DShJOEvRQElwhtyWPm4UZG6MpqfRrPCz4tRYQBfDM86L/T6JffdRzuqnLLxj+5zVnsCzfMuj3QgA4a6uJRSxRK+l7XF9KXsNzs5i3E0+t1NlNHS3xIo7wyXiUzw+4CmHh9/rjxHCWyeIs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=zj9GlIgo; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=3JaWNoZJ; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="zj9GlIgo"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="3JaWNoZJ" Message-ID: <20240927084817.878595561@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426938; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=SzaWYWlgppQYsQPjjX+C3/SOtqJIw5qvKkXGRKX9duM=; b=zj9GlIgoYEuN39qlOiKMbIvrd2FLT9g30qiV5oSBG9pu0ahNGq5yOQu05my+4ZXGYzw3yG ZpYHIvlkwjrJ7SoQY2GxThFEwBpEcHbFObzob3Sm8et/0/5bU9G29oK6/IVEVkZZcVHukm k4nV3NzTfplotJIUxJSGzZt0l7+4sUQmq8Omw/HztRNMsZ4PcvcevS+6FO90rk4BGUd/ub iFyUB2j+PhENJj573GjV+UoyEMSTFkTHQxfAmLcpM2AIv0aEEXOGnveAyXzPWtYCDh6jzk ULYWtQt6bsLHtWNBP6fnwTyOcFvne4jubODnbfB+rG96NMGbgIFQjC+3pCfwoQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426938; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=SzaWYWlgppQYsQPjjX+C3/SOtqJIw5qvKkXGRKX9duM=; b=3JaWNoZJ/iq7IPcBxTZZ26X2/EliOQgepiNm9jbT+l4DA8fs01miM1bLH3X21AqaJKHQKR g8+z9Phy7tQ2+CDA== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 16/27] posix-timers: Store PID type in the timer References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:58 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner instead of re-evaluating the signal delivery mode everywhere. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 2 ++ kernel/time/posix-timers.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 200098d27cc0..947176582de9 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -180,6 +181,7 @@ struct k_itimer { s64 it_overrun_last; unsigned int it_signal_seq; int it_sigev_notify; + enum pid_type it_pid_type; ktime_t it_interval; struct signal_struct *it_signal; union { diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 9d7e02db4157..bf68d80a0d75 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -298,7 +298,6 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *i= nfo) int posix_timer_queue_signal(struct k_itimer *timr) { enum posix_timer_state state =3D POSIX_TIMER_DISARMED; - enum pid_type type; int ret; =20 lockdep_assert_held(&timr->it_lock); @@ -309,8 +308,7 @@ int posix_timer_queue_signal(struct k_itimer *timr) } timr->it_status =3D state; =20 - type =3D !(timr->it_sigev_notify & SIGEV_THREAD_ID) ? PIDTYPE_TGID : PIDT= YPE_PID; - ret =3D send_sigqueue(timr->sigq, timr->it_pid, type, timr->it_signal_seq= ); + ret =3D send_sigqueue(timr->sigq, timr->it_pid, timr->it_pid_type, timr->= it_signal_seq); /* If we failed to send the signal the timer stops. */ return ret > 0; } @@ -504,6 +502,11 @@ static int do_timer_create(clockid_t which_clock, stru= ct sigevent *event, new_timer->it_pid =3D get_pid(task_tgid(current)); } =20 + if (new_timer->it_sigev_notify & SIGEV_THREAD_ID) + new_timer->it_pid_type =3D PIDTYPE_PID; + else + new_timer->it_pid_type =3D PIDTYPE_TGID; + new_timer->sigq->info.si_tid =3D new_timer->it_id; new_timer->sigq->info.si_code =3D SI_TIMER; new_timer->sigq->info.si_sys_privptr =3D new_timer; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9F0A81B252D for ; Fri, 27 Sep 2024 08:49:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426943; cv=none; b=drgmpT8U9IogyXatGJo3wE2QhvCmWbNKFJOOPG1LfvREiU+jihpXeFvzX7mqrV9j4A1dLF7Rx5B7gN/NnvXAL30LCwNIg5nCmaKthr0bYz6gN+JfO5Xz1+aIyLzqUH5BiIh6UT3BYanHLDUrvm7qj6fSiRcDu09E7kkCz0Dwzek= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426943; c=relaxed/simple; bh=gmlXbfdqzo/4QeK3ossw6X30lZBL4wrLRlOZ35Jc6xc=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=ojzeFi5v4J31JjyjusuL9PBEC412Al/vTxfIjnOM93nCdgvrVTXXkbzZp8YfMVsjcY0H/TlizRixTpjpXg6wJdgwPU+oRZI+1lzQBODkPf1J105Cn29Mhjbvac+GQkLzcevPdxnddoGijELh+blhe0krgtSWjtymMC1E7PWrGwE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=djPS6DVs; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=T2w9BYgn; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="djPS6DVs"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="T2w9BYgn" Message-ID: <20240927084817.948507874@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426940; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=okOUrbWkuU0neRq7h1aK4Wj+R1IhH/blhyN65/RKs4Q=; b=djPS6DVsjO6liHfqDHGJIcyzLUHlvHBohoTEp8E2UGiuD05dakFytPAB5fW16ybtSgVe4V 0A/HzqmL2DhAUCocRhqhabnteeYlOruVhUMF5k/yNUN9EuUZr/VGaTkgPgozngYRiUhPnu UH8/0NTrienyyBUMuDiQg27V4Ddkga+hWDDSJXscezsXphkOHgP4rQ/oZaLT3gN5sBfzaP MXmZp6tplk3lO7HbW5X8SWhAiIfB9md/bX4CC6Nfb4LznjCYuybtTEo2k5ru2Tfuu2Hhi1 BobjRzzm4REfrSb/ZVYYFTeKwKvqvdxzA6HdRUbeBXL31pdrdMIXC4OJUUFrNw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426940; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=okOUrbWkuU0neRq7h1aK4Wj+R1IhH/blhyN65/RKs4Q=; b=T2w9BYgnC0uOCo11acuHqoHKgcSY0SsLUPtk5xgtJ+MjLSRzivPcgiQaQ5geMnWaMkFshl EHU2b3ScgsbAupDQ== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 17/27] signal: Refactor send_sigqueue() References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:48:59 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To handle posix timers which have their signal ignored via SIG_IGN properly it is required to requeue a ignored signal for delivery when SIG_IGN is lifted so the timer gets rearmed. Split the required code out of send_sigqueue() so it can be reused in context of sigaction(). While at it rename send_sigqueue() to posixtimer_send_sigqueue() so its clear what this is about. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 1 +- include/linux/sched/signal.h | 1 +- kernel/signal.c | 73 +++++++++++++++++++++++++---------------= ----- kernel/time/posix-timers.c | 2 +- 4 files changed, 44 insertions(+), 33 deletions(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 947176582de9..52611ea923b2 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -109,6 +109,7 @@ static inline void posix_cputimers_rt_watchdog(struct p= osix_cputimers *pct, =20 void posixtimer_rearm_itimer(struct task_struct *p); bool posixtimer_init_sigqueue(struct sigqueue *q); +int posixtimer_send_sigqueue(struct k_itimer *tmr); bool posixtimer_deliver_signal(struct kernel_siginfo *info); void posixtimer_free_timer(struct k_itimer *timer); =20 diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index bd9f569231d9..36283c1c55e9 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -340,7 +340,6 @@ extern int send_sig(int, struct task_struct *, int); extern int zap_other_threads(struct task_struct *p); extern struct sigqueue *sigqueue_alloc(void); extern void sigqueue_free(struct sigqueue *); -extern int send_sigqueue(struct sigqueue *, struct pid *, enum pid_type, i= nt si_private); extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); =20 static inline void clear_notify_signal(void) diff --git a/kernel/signal.c b/kernel/signal.c index 0aa01eec5e2d..01102470e174 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1947,38 +1947,53 @@ void sigqueue_free(struct sigqueue *q) __sigqueue_free(q); } =20 -int send_sigqueue(struct sigqueue *q, struct pid *pid, enum pid_type type,= int si_private) +static void posixtimer_queue_sigqueue(struct sigqueue *q, struct task_stru= ct *t, enum pid_type type) { - int sig =3D q->info.si_signo; struct sigpending *pending; + int sig =3D q->info.si_signo; + + signalfd_notify(t, sig); + pending =3D (type !=3D PIDTYPE_PID) ? &t->signal->shared_pending : &t->pe= nding; + list_add_tail(&q->list, &pending->list); + sigaddset(&pending->signal, sig); + complete_signal(sig, t, type); +} + +/* + * This function is used by POSIX timers to deliver a timer signal. + * Where type is PIDTYPE_PID (such as for timers with SIGEV_THREAD_ID + * set), the signal must be delivered to the specific thread (queues + * into t->pending). + * + * Where type is not PIDTYPE_PID, signals must be delivered to the + * process. In this case, prefer to deliver to current if it is in + * the same thread group as the target process, which avoids + * unnecessarily waking up a potentially idle task. + */ +static inline struct task_struct *posixtimer_get_target(struct k_itimer *t= mr) +{ + struct task_struct *t =3D pid_task(tmr->it_pid, tmr->it_pid_type); + + if (t && tmr->it_pid_type !=3D PIDTYPE_PID && same_thread_group(t, curren= t)) + t =3D current; + return t; +} + +int posixtimer_send_sigqueue(struct k_itimer *tmr) +{ + struct sigqueue *q =3D tmr->sigq; + int sig =3D q->info.si_signo; struct task_struct *t; unsigned long flags; int ret, result; =20 - if (WARN_ON_ONCE(!(q->flags & SIGQUEUE_PREALLOC))) - return 0; - if (WARN_ON_ONCE(q->info.si_code !=3D SI_TIMER)) - return 0; - ret =3D -1; rcu_read_lock(); =20 - /* - * This function is used by POSIX timers to deliver a timer signal. - * Where type is PIDTYPE_PID (such as for timers with SIGEV_THREAD_ID - * set), the signal must be delivered to the specific thread (queues - * into t->pending). - * - * Where type is not PIDTYPE_PID, signals must be delivered to the - * process. In this case, prefer to deliver to current if it is in - * the same thread group as the target process, which avoids - * unnecessarily waking up a potentially idle task. - */ - t =3D pid_task(pid, type); + t =3D posixtimer_get_target(tmr); if (!t) goto ret; - if (type !=3D PIDTYPE_PID && same_thread_group(t, current)) - t =3D current; + if (!likely(lock_task_sighand(t, &flags))) goto ret; =20 @@ -1988,7 +2003,7 @@ int send_sigqueue(struct sigqueue *q, struct pid *pid= , enum pid_type type, int s * decides based on si_sys_private whether to invoke * posixtimer_rearm() or not. */ - q->info.si_sys_private =3D si_private; + q->info.si_sys_private =3D tmr->it_signal_seq; =20 /* * Set the overrun count to zero unconditionally. The posix timer @@ -2019,24 +2034,20 @@ int send_sigqueue(struct sigqueue *q, struct pid *p= id, enum pid_type type, int s q->info.si_overrun =3D 0; =20 ret =3D 1; /* the signal is ignored */ - result =3D TRACE_SIGNAL_IGNORED; - if (!prepare_signal(sig, t, false)) + if (!prepare_signal(sig, t, false)) { + result =3D TRACE_SIGNAL_IGNORED; goto out; + } =20 ret =3D 0; if (unlikely(!list_empty(&q->list))) { result =3D TRACE_SIGNAL_ALREADY_PENDING; goto out; } - - signalfd_notify(t, sig); - pending =3D (type !=3D PIDTYPE_PID) ? &t->signal->shared_pending : &t->pe= nding; - list_add_tail(&q->list, &pending->list); - sigaddset(&pending->signal, sig); - complete_signal(sig, t, type); + posixtimer_queue_sigqueue(q, t, tmr->it_pid_type); result =3D TRACE_SIGNAL_DELIVERED; out: - trace_signal_generate(sig, &q->info, t, type !=3D PIDTYPE_PID, result); + trace_signal_generate(sig, &q->info, t, tmr->it_pid_type !=3D PIDTYPE_PID= , result); unlock_task_sighand(t, &flags); ret: rcu_read_unlock(); diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index bf68d80a0d75..369c8f1c5e4c 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -308,7 +308,7 @@ int posix_timer_queue_signal(struct k_itimer *timr) } timr->it_status =3D state; =20 - ret =3D send_sigqueue(timr->sigq, timr->it_pid, timr->it_pid_type, timr->= it_signal_seq); + ret =3D posixtimer_send_sigqueue(timr); /* If we failed to send the signal the timer stops. */ return ret > 0; } From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46FA21B29AA for ; Fri, 27 Sep 2024 08:49:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426945; cv=none; b=HQvKShpdV9FB0BEtal+D0cdJwoDoXJr18GRq+ie/EhBtmGUXXHHoJ24qzr7N3biL8TWIGDQ8C05KAgkt3lY1nYMgioeivbRfO7aYVtQp4FH+J1Rz7TUMdnmx9FV3ifA20fUPpTcsN/+EZSQekIZG4d2ufmbWRy7BfFQAIZLFc0s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426945; c=relaxed/simple; bh=SyN3AEzJ16fH6loglE8H7o2ygb7apKBCSS8P7HPvdcc=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=UracSm33HZfi+XAc8ZXvdcDTNs0l5EqRjUnoe/sMY2nNuAg5R7zXK5x3IRjqq9l0QEszh3TPivs67MitW6Qjw+zGm3yHVEe0INsF2zMfkqGfNnnEcIRMC3horREwVk6+qvDyjvAaRWRATuFL+fLZGqJF9oLz3o3J/NPZXqdE3vA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Soy0xB45; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=+FCU2aV+; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Soy0xB45"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="+FCU2aV+" Message-ID: <20240927084818.008765489@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=2KA7dgQNEXiYmgcYupwhl/M42bH2pWxultOjXQ1ea0c=; b=Soy0xB45gqE2FFAuAiED3sM9/LmyGxqNjbcnZMm3VK4CmCuRjduaVCYSXA9LnxL0Ln/nKn Mj/mf+yojSeHA18LTCttSIx4Ya0VPfY2eZZi7uEWDpyTwCNXXfWjnGyddo9x3GjhdVr8vJ qBazBhnC6YcNMhtdhtXtKGlqKevpohdaLfk2ZpaoPvamMEIe2DTWJuTwtYA20EfvjW7mu6 MeenouQ3NVQdxhvtoWC/YWQsSsuGeXZrcHuMXUsPzraB4JEQXh1pfC3nA19jPIpr77sxxO R3DTNfKxNW/eiBAwFMlKoCwTtgeVc5Xw2Nu/IQqwFY+fmRbukWaA9FcK8tCdvw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426941; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=2KA7dgQNEXiYmgcYupwhl/M42bH2pWxultOjXQ1ea0c=; b=+FCU2aV+u9T35w+fjCyEOxshFzMopIKQWZF1zqtLCItv1MPFaoLlqBBayHN6gKQHHbI52x LKHxuomSADJ4MkCw== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 18/27] posix-timers: Embed sigqueue in struct k_itimer References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:01 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To cure the SIG_IGN handling for posix interval timers, the preallocated sigqueue needs to be embedded into struct k_itimer to prevent life time races of all sorts. Now that the prerequisites are in place, embed the sigqueue into struct k_itimer and fixup the relevant usage sites. Aside of preparing for proper SIG_IGN handling, this spares an extra allocation. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- fs/proc/base.c | 4 +-- include/linux/posix-timers.h | 23 ++++++++++++++++-- kernel/signal.c | 12 +++++++-- kernel/time/posix-timers.c | 59 +++++++++++++++++++++++++++-------------= ----- 4 files changed, 69 insertions(+), 29 deletions(-) --- diff --git a/fs/proc/base.c b/fs/proc/base.c index dd579332a7f8..f01ea013ff9b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2496,8 +2496,8 @@ static int show_timer(struct seq_file *m, void *v) =20 seq_printf(m, "ID: %d\n", timer->it_id); seq_printf(m, "signal: %d/%px\n", - timer->sigq->info.si_signo, - timer->sigq->info.si_value.sival_ptr); + timer->sigq.info.si_signo, + timer->sigq.info.si_value.sival_ptr); seq_printf(m, "notify: %s/%s.%d\n", nstr[notify & ~SIGEV_THREAD_ID], (notify & SIGEV_THREAD_ID) ? "tid" : "pid", diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index 52611ea923b2..ddd7ccd9ba77 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -39,6 +39,8 @@ static inline int clockid_to_fd(const clockid_t clk) =20 #ifdef CONFIG_POSIX_TIMERS =20 +#include + /** * cpu_timer - Posix CPU timer representation for k_itimer * @node: timerqueue node to queue in the task/sig @@ -165,7 +167,7 @@ static inline void posix_cputimers_init_work(void) { } * @it_pid: The pid of the process/task targeted by the signal * @it_process: The task to wakeup on clock_nanosleep (CPU timers) * @rcuref: Reference count for life time management - * @sigq: Pointer to preallocated sigqueue + * @sigq: Embedded sigqueue * @it: Union representing the various posix timer type * internals. * @rcu: RCU head for freeing the timer. @@ -189,7 +191,7 @@ struct k_itimer { struct pid *it_pid; struct task_struct *it_process; }; - struct sigqueue *sigq; + struct sigqueue sigq; rcuref_t rcuref; union { struct { @@ -217,6 +219,23 @@ static inline void posixtimer_putref(struct k_itimer *= tmr) if (rcuref_put(&tmr->rcuref)) posixtimer_free_timer(tmr); } + +static inline void posixtimer_sigqueue_getref(struct sigqueue *q) +{ + struct k_itimer *tmr =3D container_of(q, struct k_itimer, sigq); + + WARN_ON_ONCE(!rcuref_get(&tmr->rcuref)); +} + +static inline void posixtimer_sigqueue_putref(struct sigqueue *q) +{ + struct k_itimer *tmr =3D container_of(q, struct k_itimer, sigq); + + posixtimer_putref(tmr); +} +#else /* CONFIG_POSIX_TIMERS */ +static inline void posixtimer_sigqueue_getref(struct sigqueue *q) { } +static inline void posixtimer_sigqueue_putref(struct sigqueue *q) { } #endif /* !CONFIG_POSIX_TIMERS */ =20 #endif diff --git a/kernel/signal.c b/kernel/signal.c index 01102470e174..7a07f86e2ae6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -566,7 +566,12 @@ static void collect_signal(int sig, struct sigpending = *list, kernel_siginfo_t *i still_pending: list_del_init(&first->list); copy_siginfo(info, &first->info); - __sigqueue_free(first); + /* + * Do not drop the reference count for posix timer + * signals. That's done in posix_timer_deliver_signal(). + */ + if (info->si_code !=3D SI_TIMER) + __sigqueue_free(first); } else { /* * Ok, it wasn't in the queue. This must be @@ -1981,7 +1986,7 @@ static inline struct task_struct *posixtimer_get_targ= et(struct k_itimer *tmr) =20 int posixtimer_send_sigqueue(struct k_itimer *tmr) { - struct sigqueue *q =3D tmr->sigq; + struct sigqueue *q =3D &tmr->sigq; int sig =3D q->info.si_signo; struct task_struct *t; unsigned long flags; @@ -2041,9 +2046,12 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr) =20 ret =3D 0; if (unlikely(!list_empty(&q->list))) { + /* This holds a reference count already */ result =3D TRACE_SIGNAL_ALREADY_PENDING; goto out; } + + posixtimer_sigqueue_getref(q); posixtimer_queue_sigqueue(q, t, tmr->it_pid_type); result =3D TRACE_SIGNAL_DELIVERED; out: diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index 369c8f1c5e4c..b62e3ccb45ff 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -251,12 +251,13 @@ static void common_hrtimer_rearm(struct k_itimer *tim= r) =20 /* * This function is called from the signal delivery code. It decides - * whether the signal should be dropped and rearms interval timers. + * whether the signal should be dropped and rearms interval timers. The + * timer can be unconditionally accessed as there is a reference held on + * it. */ bool posixtimer_deliver_signal(struct kernel_siginfo *info) { - struct k_itimer *timr; - unsigned long flags; + struct k_itimer *timr =3D info->si_sys_privptr; bool ret =3D false; =20 /* @@ -264,12 +265,14 @@ bool posixtimer_deliver_signal(struct kernel_siginfo = *info) * timr::it_lock. Keep interrupts disabled. */ spin_unlock(¤t->sighand->siglock); + spin_lock(&timr->it_lock); =20 - timr =3D lock_timer(info->si_tid, &flags); - if (!timr) - goto out; - - if (timr->it_signal_seq !=3D info->si_sys_private) + /* + * Check if the timer is still alive or whether it got modified + * since the signal was queued. In either case, don't rearm and + * drop the signal. + */ + if (!timr->it_signal || timr->it_signal_seq !=3D info->si_sys_private) goto out_unlock; =20 if (timr->it_interval && timr->it_status =3D=3D POSIX_TIMER_REQUEUE_PENDI= NG) { @@ -285,8 +288,10 @@ bool posixtimer_deliver_signal(struct kernel_siginfo *= info) ret =3D true; =20 out_unlock: - unlock_timer(timr, flags); -out: + spin_unlock(&timr->it_lock); + /* Drop the reference which was acquired when the signal was queued */ + posixtimer_putref(timr); + spin_lock(¤t->sighand->siglock); =20 /* Don't expose the si_sys_priv* values to userspace */ @@ -405,17 +410,17 @@ static struct pid *good_sigevent(sigevent_t * event) } } =20 -static struct k_itimer * alloc_posix_timer(void) +static struct k_itimer *alloc_posix_timer(void) { struct k_itimer *tmr =3D kmem_cache_zalloc(posix_timers_cache, GFP_KERNEL= ); =20 if (!tmr) return tmr; - if (unlikely(!(tmr->sigq =3D sigqueue_alloc()))) { + + if (unlikely(!posixtimer_init_sigqueue(&tmr->sigq))) { kmem_cache_free(posix_timers_cache, tmr); return NULL; } - clear_siginfo(&tmr->sigq->info); rcuref_init(&tmr->rcuref, 1); return tmr; } @@ -430,7 +435,8 @@ static void k_itimer_rcu_free(struct rcu_head *head) void posixtimer_free_timer(struct k_itimer *tmr) { put_pid(tmr->it_pid); - sigqueue_free(tmr->sigq); + if (tmr->sigq.ucounts) + dec_rlimit_put_ucounts(tmr->sigq.ucounts, UCOUNT_RLIMIT_SIGPENDING); call_rcu(&tmr->rcu, k_itimer_rcu_free); } =20 @@ -492,13 +498,13 @@ static int do_timer_create(clockid_t which_clock, str= uct sigevent *event, goto out; } new_timer->it_sigev_notify =3D event->sigev_notify; - new_timer->sigq->info.si_signo =3D event->sigev_signo; - new_timer->sigq->info.si_value =3D event->sigev_value; + new_timer->sigq.info.si_signo =3D event->sigev_signo; + new_timer->sigq.info.si_value =3D event->sigev_value; } else { new_timer->it_sigev_notify =3D SIGEV_SIGNAL; - new_timer->sigq->info.si_signo =3D SIGALRM; - memset(&new_timer->sigq->info.si_value, 0, sizeof(sigval_t)); - new_timer->sigq->info.si_value.sival_int =3D new_timer->it_id; + new_timer->sigq.info.si_signo =3D SIGALRM; + memset(&new_timer->sigq.info.si_value, 0, sizeof(sigval_t)); + new_timer->sigq.info.si_value.sival_int =3D new_timer->it_id; new_timer->it_pid =3D get_pid(task_tgid(current)); } =20 @@ -507,9 +513,9 @@ static int do_timer_create(clockid_t which_clock, struc= t sigevent *event, else new_timer->it_pid_type =3D PIDTYPE_TGID; =20 - new_timer->sigq->info.si_tid =3D new_timer->it_id; - new_timer->sigq->info.si_code =3D SI_TIMER; - new_timer->sigq->info.si_sys_privptr =3D new_timer; + new_timer->sigq.info.si_tid =3D new_timer->it_id; + new_timer->sigq.info.si_code =3D SI_TIMER; + new_timer->sigq.info.si_sys_privptr =3D new_timer; =20 if (copy_to_user(created_timer_id, &new_timer_id, sizeof (new_timer_id)))= { error =3D -EFAULT; @@ -593,7 +599,14 @@ static struct k_itimer *__lock_timer(timer_t timer_id,= unsigned long *flags) * 1) Set timr::it_signal to NULL with timr::it_lock held * 2) Release timr::it_lock * 3) Remove from the hash under hash_lock - * 4) Call RCU for removal after the grace period + * 4) Put the reference count. + * + * The reference count might not drop to zero if timr::sigq is + * queued. In that case the signal delivery or flush will put the + * last reference count. + * + * When the reference count reaches zero, the timer is scheduled + * for RCU removal after the grace period. * * Holding rcu_read_lock() accross the lookup ensures that * the timer cannot be freed. From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 507971B29C1 for ; Fri, 27 Sep 2024 08:49:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426945; cv=none; b=tIzmCsfHFleZt6VqIPqdUzqFM9Uj31Io/QX4wJOnphgn6W+2XWhT7qae7Df43O8ctcnRcJk9aLBGT5c3xZp2hYHS9Kb12yCXY8huzrXvd7mzPUxLUd9ajnACasETKhZ+4xyDv1vFPl/3v3xqOREAK+F3SEzPnbvW3iDMiUPpxbo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426945; c=relaxed/simple; bh=UlHBOibUs+tPQI7hVRid7/rykm8kuHRH0y7EnCEYm+o=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=p/OMkUkq4NNdk43koWgyyElRFqCjyiQThlkP3X+ZYJg3dVPMldjE/L65O9+TtdsSplqsvVvL3s2ZA8pg9XG3l1o2V++gTB6ssT3rIsGLLzP1+NIHBVSO1/33sT30HFSLvdRCGgthqCbzb0yCch3Fj0WLjaB/d++JnbnFISjseA4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=INt5j6XA; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=7t7oC8X8; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="INt5j6XA"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="7t7oC8X8" Message-ID: <20240927084818.069667397@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426942; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=mQNrbcp+YcyVuJXLebTnSEkknpAl3WACHMwmKH9HqYw=; b=INt5j6XAyzF65xDyuh3XWAgIh0Z36i8qAqCqwLd6zJ9p9yyn+DanXPkkEO5FgOVNmBGBKt i7eFzAOpp/1KAskyrxVLX/sl04oKRHOjBj6hn+YkLST0Lb+uJntQVSQvUPSvI6IU0j3l7P cT+Ewj2FH+StWZbxFVNScTHlSSKjQXVSGE+/vRwWXNz2peRXF291GJbGhGmISFhX27PjCV Wkn8IGGGXsl2rXuG4silHUA7QSFMVQuVhX1dSQQMQV7uxzHcIbVFPLaGLVB2IUSWeaz7ru bXi+WRq01LKLSCZT6PhqD91poLSRleiotATxg8oqyQQOdq/94DWem9x+VqH7ag== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426942; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=mQNrbcp+YcyVuJXLebTnSEkknpAl3WACHMwmKH9HqYw=; b=7t7oC8X8F+KZgEbnwB+oMgUqr4KCkmYNU1/vuZoViNkRvXbm5NHo/8yMOF8yMRZPgrVxnZ yNWq7n/8QHUgj7BQ== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 19/27] signal: Cleanup unused posix-timer leftovers References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:02 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Remove the leftovers of sigqueue preallocation as it's not longer used. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/sched/signal.h | 2 -- kernel/signal.c | 43 +++++++---------------------------------= --- 2 files changed, 7 insertions(+), 38 deletions(-) --- diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 36283c1c55e9..02972fd41931 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -338,8 +338,6 @@ extern void force_fatal_sig(int); extern void force_exit_sig(int); extern int send_sig(int, struct task_struct *, int); extern int zap_other_threads(struct task_struct *p); -extern struct sigqueue *sigqueue_alloc(void); -extern void sigqueue_free(struct sigqueue *); extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *); =20 static inline void clear_notify_signal(void) diff --git a/kernel/signal.c b/kernel/signal.c index 7a07f86e2ae6..48bceca90a91 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -439,8 +439,8 @@ static void __sigqueue_init(struct sigqueue *q, struct = ucounts *ucounts, * - this may be called without locks if and only if t =3D=3D current, oth= erwise an * appropriate lock must be held to stop the target task from exiting */ -static struct sigqueue *__sigqueue_alloc(int sig, struct task_struct *t, g= fp_t gfp_flags, - int override_rlimit, const unsigned int sigqueue_flags) +static struct sigqueue *sigqueue_alloc(int sig, struct task_struct *t, gfp= _t gfp_flags, + int override_rlimit) { struct ucounts *ucounts =3D sig_get_ucounts(t, sig, override_rlimit); struct sigqueue *q; @@ -454,14 +454,16 @@ static struct sigqueue *__sigqueue_alloc(int sig, str= uct task_struct *t, gfp_t g return NULL; } =20 - __sigqueue_init(q, ucounts, sigqueue_flags); + __sigqueue_init(q, ucounts, 0); return q; } =20 static void __sigqueue_free(struct sigqueue *q) { - if (q->flags & SIGQUEUE_PREALLOC) + if (q->flags & SIGQUEUE_PREALLOC) { + posixtimer_sigqueue_putref(q); return; + } if (q->ucounts) { dec_rlimit_put_ucounts(q->ucounts, UCOUNT_RLIMIT_SIGPENDING); q->ucounts =3D NULL; @@ -1065,7 +1067,7 @@ static int __send_signal_locked(int sig, struct kerne= l_siginfo *info, else override_rlimit =3D 0; =20 - q =3D __sigqueue_alloc(sig, t, GFP_ATOMIC, override_rlimit, 0); + q =3D sigqueue_alloc(sig, t, GFP_ATOMIC, override_rlimit); =20 if (q) { list_add_tail(&q->list, &pending->list); @@ -1921,37 +1923,6 @@ bool posixtimer_init_sigqueue(struct sigqueue *q) return true; } =20 -struct sigqueue *sigqueue_alloc(void) -{ - return __sigqueue_alloc(-1, current, GFP_KERNEL, 0, SIGQUEUE_PREALLOC); -} - -void sigqueue_free(struct sigqueue *q) -{ - spinlock_t *lock =3D ¤t->sighand->siglock; - unsigned long flags; - - if (WARN_ON_ONCE(!(q->flags & SIGQUEUE_PREALLOC))) - return; - /* - * We must hold ->siglock while testing q->list - * to serialize with collect_signal() or with - * __exit_signal()->flush_sigqueue(). - */ - spin_lock_irqsave(lock, flags); - q->flags &=3D ~SIGQUEUE_PREALLOC; - /* - * If it is queued it will be freed when dequeued, - * like the "regular" sigqueue. - */ - if (!list_empty(&q->list)) - q =3D NULL; - spin_unlock_irqrestore(lock, flags); - - if (q) - __sigqueue_free(q); -} - static void posixtimer_queue_sigqueue(struct sigqueue *q, struct task_stru= ct *t, enum pid_type type) { struct sigpending *pending; From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AB73018A922 for ; Fri, 27 Sep 2024 08:49:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426947; cv=none; b=c9VliCyrRl6XCZHYf4bmDmuYVn5+fq9OnmiF4HkL6oMswqTTVoo6OLg3GGBvTLouFPuC9vs2k7Ba2RX80RyvNmjTtQTazA84rIZJo19rHA23Czp2RG+tnKxeg7gFb35B6vzuPy5qCTY95VUEGWFxMNtGKtyBx91OiBIyneuA4t0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426947; c=relaxed/simple; bh=HlE/rB9DJ2iFpW51kf3egByzflBOf5vMGbgvRd4sVBM=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=bqHnmKq1FYneEWonj6fo1i5DRIHvRx08zUIKnXO5JA9EeyXhQyie5UomvmqiFbLyfm+PsYpeYL82T37rlLoC9EB/h3axNqoyTYtWrrls+3ONws6OVaq4j/6PA8Kqe1fwgJPrKGvFUxgZRRGT+G1+ET+yPzHS2XA5zsnVTKrJ23Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=20P5hVWc; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=+SHmljH2; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="20P5hVWc"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="+SHmljH2" Message-ID: <20240927084818.130965127@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426943; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=WfdjifQzaEkh29PcCz6zrqcoHSPORIhLPU9iUugztoc=; b=20P5hVWcVxQwz/IrPw41/5Ib+IYJqaySxrIUlMArMipyWKmAovYdW4pZtK6Ls9srU2/mej 9UOqOk3QcMbDGyL2rP5SR7Y2wkBcQNu+jzWI6o2tgjaDpkZuiWR1Gbed0bRdbK0asIMRh/ Slmbism4G131D6s1AMOTRx+XWoAmkSCDOrxe5GnxNtpCd8c/66LcOtwLMx0tf9gmPcDyef kfIhOMa6a1M0H9c7QR9gchLRgdbALGnPH11WjqYjhdR1YuSpfAdIXFZ+/vYvRhTj+pOr0F hVrjMBehDPHDEuooOkUuUO5T8kHFOHxhaWt4mVwk5mVvq9+yZ6ZJ5YR+0FyZEA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426943; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=WfdjifQzaEkh29PcCz6zrqcoHSPORIhLPU9iUugztoc=; b=+SHmljH2bQaF9cWtzz8yzRpHADeUmhsQjrgWRLpgSpmeAX4xlFhIqccCmwntoRMoC/aSZx gc5H2TLxH3IiNkAQ== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 20/27] signal: Add task argument to flush_sigqueue_mask() References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:03 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To prepare for handling posix timer signals on sigaction(SIG_IGN) properly, add a task argument to flush_sigqueue_mask() and fixup all call sites. This argument will be used in a later step to enqueue posix timers on an ignored list, so their signal can be requeued when SIG_IGN is lifted later on. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- kernel/signal.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) --- diff --git a/kernel/signal.c b/kernel/signal.c index 48bceca90a91..93c2d681309c 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -724,11 +724,10 @@ void signal_wake_up_state(struct task_struct *t, unsi= gned int state) =20 /* * Remove signals in mask from the pending set and queue. - * Returns 1 if any signals were found. * * All callers must be holding the siglock. */ -static void flush_sigqueue_mask(sigset_t *mask, struct sigpending *s) +static void flush_sigqueue_mask(sigset_t *mask, struct sigpending *s, stru= ct task_struct *ptmr_tsk) { struct sigqueue *q, *n; sigset_t m; @@ -866,18 +865,18 @@ static bool prepare_signal(int sig, struct task_struc= t *p, bool force) * This is a stop signal. Remove SIGCONT from all queues. */ siginitset(&flush, sigmask(SIGCONT)); - flush_sigqueue_mask(&flush, &signal->shared_pending); + flush_sigqueue_mask(&flush, &signal->shared_pending, NULL); for_each_thread(p, t) - flush_sigqueue_mask(&flush, &t->pending); + flush_sigqueue_mask(&flush, &t->pending, NULL); } else if (sig =3D=3D SIGCONT) { unsigned int why; /* * Remove all stop signals from all queues, wake all threads. */ siginitset(&flush, SIG_KERNEL_STOP_MASK); - flush_sigqueue_mask(&flush, &signal->shared_pending); + flush_sigqueue_mask(&flush, &signal->shared_pending, NULL); for_each_thread(p, t) { - flush_sigqueue_mask(&flush, &t->pending); + flush_sigqueue_mask(&flush, &t->pending, NULL); task_clear_jobctl_pending(t, JOBCTL_STOP_PENDING); if (likely(!(t->ptrace & PT_SEIZED))) { t->jobctl &=3D ~JOBCTL_STOPPED; @@ -4169,8 +4168,8 @@ void kernel_sigaction(int sig, __sighandler_t action) sigemptyset(&mask); sigaddset(&mask, sig); =20 - flush_sigqueue_mask(&mask, ¤t->signal->shared_pending); - flush_sigqueue_mask(&mask, ¤t->pending); + flush_sigqueue_mask(&mask, ¤t->signal->shared_pending, NULL); + flush_sigqueue_mask(&mask, ¤t->pending, NULL); recalc_sigpending(); } spin_unlock_irq(¤t->sighand->siglock); @@ -4237,9 +4236,9 @@ int do_sigaction(int sig, struct k_sigaction *act, st= ruct k_sigaction *oact) if (sig_handler_ignored(sig_handler(p, sig), sig)) { sigemptyset(&mask); sigaddset(&mask, sig); - flush_sigqueue_mask(&mask, &p->signal->shared_pending); + flush_sigqueue_mask(&mask, &p->signal->shared_pending, NULL); for_each_thread(p, t) - flush_sigqueue_mask(&mask, &t->pending); + flush_sigqueue_mask(&mask, &t->pending, NULL); } } From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A4A711B2ECA for ; Fri, 27 Sep 2024 08:49:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426948; cv=none; b=HL2AkiyC70I+l+Oe2R9SaF7sDfCvIlhBxzMrf5PLMl7GymTZ/uK7jBFqp/Lnxt6Wvh6Hzvqb3rd/PNzuhP2mH7wRVZfMyReSgoDNX5GIGtMenSyR3FAyXc/0Vu03/4+NpxP/1CaUchz+N6H4LzIpE3rug6u7Kp3B9xMFEGTUPUo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426948; c=relaxed/simple; bh=LfXtJQwy94+oedKexOUya3zMtCS6elO6jHIITTZjjsc=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=Xx+hAYl7YDT6liJG1PVeQQF0waxkNvm7dSXHuj6auaohZVCNp2vkYwf+KLA8dWgbWXDUv3aVkccGTl/Uza+kMLezeHozqlUAvkzTys12r+Emj82oIChguC0ZwB/uGOoHibNAWhfJ5vP02eX38EPGW/irzIKEmpGeo1CqOM5ZSaw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=wSfC+wqH; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=xATPNmwe; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="wSfC+wqH"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="xATPNmwe" Message-ID: <20240927084818.190628301@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426945; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=P2a6nBvuJqqDzQ/HVjG6sUxFvMGxHvxjY93bghrPEFQ=; b=wSfC+wqHsZDhvlH1QLU9RvzbWQS1ws3jFTirYo269qnGqjs5/uCAmzEAbwB2gsEbws0URI J5G5cTZ4OfyMnarhe1KHfLcx/cmbN1TY5sGlAdizUGnOPd2+umnSv7OOxWx+j3+f8Eidgr xh1StSwbrdlM8dcxu3pPZ31ZFB3vTLnYzGz3OKzLpMp+/N8H6+w2BmN0HnggffaKQ/3yuL QvnJya7GMnPBJ4CbuQp/aFBOTuoevIrpldKJYh6g43zXsiFT4BSOo9HkCuYk4Weyzs8V85 Rc8kGYLXuO5d11yjDJrCMinaFQ1ooB+drDTLWGDS06OF7rlLpftTRfHfDOFluw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426945; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=P2a6nBvuJqqDzQ/HVjG6sUxFvMGxHvxjY93bghrPEFQ=; b=xATPNmweWcdztD74TQEuBVstRdACrDPviuC5bbzfYyQD7bq8BzvG0S2FDITXgs2S3OLsKP 1ePE+LNN7FxnIFAw== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 21/27] signal: Provide ignored_posix_timers list References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:04 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To prepare for handling posix timer signals on sigaction(SIG_IGN) properly, add a list to task::signal. This list will be used to queue posix timers so their signal can be requeued when SIG_IGN is lifted later. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/sched/signal.h | 1 + init/init_task.c | 5 +++-- kernel/fork.c | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) --- diff --git a/include/linux/sched/signal.h b/include/linux/sched/signal.h index 02972fd41931..d5d03d919df8 100644 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -138,6 +138,7 @@ struct signal_struct { /* POSIX.1b Interval Timers */ unsigned int next_posix_timer_id; struct hlist_head posix_timers; + struct hlist_head ignored_posix_timers; =20 /* ITIMER_REAL timer for the process */ struct hrtimer real_timer; diff --git a/init/init_task.c b/init/init_task.c index 5d0399bc8d2f..65af2ba93f25 100644 --- a/init/init_task.c +++ b/init/init_task.c @@ -29,8 +29,9 @@ static struct signal_struct init_signals =3D { .cred_guard_mutex =3D __MUTEX_INITIALIZER(init_signals.cred_guard_mutex), .exec_update_lock =3D __RWSEM_INITIALIZER(init_signals.exec_update_lock), #ifdef CONFIG_POSIX_TIMERS - .posix_timers =3D HLIST_HEAD_INIT, - .cputimer =3D { + .posix_timers =3D HLIST_HEAD_INIT, + .ignored_posix_timers =3D HLIST_HEAD_INIT, + .cputimer =3D { .cputime_atomic =3D INIT_CPUTIME_ATOMIC, }, #endif diff --git a/kernel/fork.c b/kernel/fork.c index c1b343cba560..bef4b51bd474 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1862,6 +1862,7 @@ static int copy_signal(unsigned long clone_flags, str= uct task_struct *tsk) =20 #ifdef CONFIG_POSIX_TIMERS INIT_HLIST_HEAD(&sig->posix_timers); + INIT_HLIST_HEAD(&sig->ignored_posix_timers); hrtimer_init(&sig->real_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); sig->real_timer.function =3D it_real_fn; #endif From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F027E1B2EEC for ; Fri, 27 Sep 2024 08:49:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426949; cv=none; b=VBnfCG27JGqYzw8s3nVDkVMX1zdpjy370TnBmrJ+zSp8d8Yt2RFq1plXoQZm8AL9uKEmYpc6dAiqtMVAeW0qB0h10h+WuVLYw7j3cL05UV14SukGmB2TMakNC+NQYxUevz4I3Q232J4Ghmyj862t/fD0RQdFcw8k1zAQK1VjMsY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426949; c=relaxed/simple; bh=nRkN+AiEmsFUgQVS26MCYMF4hF2KHRsgRGt7CXwjl7s=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=lMjNR6zAogw9ke4/IILUcwR8jozoSWDVsELr6Gt6hdRaeMuvfEOttkZG7sECLXHHzwRSks9YNHdugpQycJ1zXdeC1rY4cT0FsMsplZdnYE0gMrk2VCjm0SfEZK4l1tDBbh6ilKJqvfvmtdUgYZkKYizrJssup3Otisd8absnh6I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=RLwVJdHz; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Y+ilk7HH; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="RLwVJdHz"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Y+ilk7HH" Message-ID: <20240927084818.250962485@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426946; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=gKoKdWNMyp0JkiI/4428ZyD0vyyNKG9BGZhxNuonT28=; b=RLwVJdHz9Q8YjjY8Dhqm4jdUCxS1xyNwAEhFQBtaS2a/57z7f0Mj3WaE0AXCMw2YEloEXu pCMeSxqFSEIhEZMWvmWP7pMNwKBi1iuxkp8bn5NpbnnWFfQF76ffbSm57sY5xCBHIeGM/O VHmm/pSgv7e3lHeTVPK1D5GBkHBdC2RF/GetEvuTxBarvaEgNMWqt/ONhtjhavY1K+jfMx qyWhiMWx0eAfNIZZ7Pz5qn3Oyyc2Xl9bJx/NNPVrNkz0ZfRzBRaiAjG2e5ENxRumIKhFUD DUe0y5QJDXJOihT9iBC7x8Zl6nyrIHuzx4tf8cwKi5OnCZQ0ntG4ti5HmC0tzg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426946; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=gKoKdWNMyp0JkiI/4428ZyD0vyyNKG9BGZhxNuonT28=; b=Y+ilk7HHohzN1UJy5oMHrUl0IT3qldgTPvtWEnF3dXSIhNvDNFw1ncT5avEOWZzmb1enWa glfmbF9YPQYhC2Dw== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 22/27] posix-timers: Handle ignored list on delete and exit References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:06 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner To handle posix timer signals on sigaction(SIG_IGN) properly, the timers will be queued on a separate ignored list. Add the necessary cleanup code for timer_delete() and exit_itimers(). Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 4 +++- kernel/time/posix-timers.c | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) --- diff --git a/include/linux/posix-timers.h b/include/linux/posix-timers.h index ddd7ccd9ba77..efab1ef7a7fe 100644 --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -151,7 +151,8 @@ static inline void posix_cputimers_init_work(void) { } =20 /** * struct k_itimer - POSIX.1b interval timer structure. - * @list: List head for binding the timer to signals->posix_timers + * @list: List node for binding the timer to tsk::signal::posix_timers + * @ignored_list: List node for tracking ignored timers in tsk::signal::ig= nored_posix_timers * @t_hash: Entry in the posix timer hash table * @it_lock: Lock protecting the timer * @kclock: Pointer to the k_clock struct handling this timer @@ -174,6 +175,7 @@ static inline void posix_cputimers_init_work(void) { } */ struct k_itimer { struct hlist_node list; + struct hlist_node ignored_list; struct hlist_node t_hash; spinlock_t it_lock; const struct k_clock *kclock; diff --git a/kernel/time/posix-timers.c b/kernel/time/posix-timers.c index b62e3ccb45ff..5a5967a01f53 100644 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1036,6 +1036,18 @@ int common_timer_del(struct k_itimer *timer) return 0; } =20 +/* + * If the deleted timer is on the ignored list, remove it and + * drop the associated reference. + */ +static inline void posix_timer_cleanup_ignored(struct k_itimer *tmr) +{ + if (!hlist_unhashed(&tmr->ignored_list)) { + hlist_del_init(&tmr->ignored_list); + posixtimer_putref(tmr); + } +} + static inline int timer_delete_hook(struct k_itimer *timer) { const struct k_clock *kc =3D timer->kclock; @@ -1068,6 +1080,7 @@ SYSCALL_DEFINE1(timer_delete, timer_t, timer_id) =20 spin_lock(¤t->sighand->siglock); hlist_del(&timer->list); + posix_timer_cleanup_ignored(timer); spin_unlock(¤t->sighand->siglock); /* * A concurrent lookup could check timer::it_signal lockless. It @@ -1119,6 +1132,8 @@ static void itimer_delete(struct k_itimer *timer) } hlist_del(&timer->list); =20 + posix_timer_cleanup_ignored(timer); + /* * Setting timer::it_signal to NULL is technically not required * here as nothing can access the timer anymore legitimately via @@ -1151,6 +1166,11 @@ void exit_itimers(struct task_struct *tsk) /* The timers are not longer accessible via tsk::signal */ while (!hlist_empty(&timers)) itimer_delete(hlist_entry(timers.first, struct k_itimer, list)); + + /* Mop up timers which are on the ignored list */ + hlist_move_list(&tsk->signal->ignored_posix_timers, &timers); + while (!hlist_empty(&timers)) + posix_timer_cleanup_ignored(hlist_entry(timers.first, struct k_itimer, l= ist)); } =20 SYSCALL_DEFINE2(clock_settime, const clockid_t, which_clock, From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E3EA81B3725 for ; Fri, 27 Sep 2024 08:49:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426950; cv=none; b=qTuQjF0kJhBfWgUZkAWxgF5vHro3JyD6SKP38pR1a/OZPnZKCzZWA58U+ZUj5SglORKJmqKYwNPxIhD0wDXRvjE1YNLs4XLqMblaTtyJfE2qemyz1qc701eQHWI9hBNghSZZIiwcPhTH9tYESKyih/OCAhH2X5O5grqzxTtlDpY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426950; c=relaxed/simple; bh=4ikW86M3H7XfpKJPNbZtxvrCBNrAsM8MbXKgaFbcHoQ=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=Wimbj7hK2VcHAeuvGpRHI9RWtA745p6Vj3Yx2Oc4xkKcaZeH98bU9XfhjtQ4lrYy7G6tMJN3bMFPgoNoalP2XF+OQHZVaPOv3IpBftozjGsE0edFdR32ncGUiTSiwS+xTIr0LehqnU6WdwdBzDCJaVZfbKgzPc3rlNFZDZoJ6rc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=KMmndMI7; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=H2SM/Bt7; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="KMmndMI7"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="H2SM/Bt7" Message-ID: <20240927084818.309948950@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426947; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=bF1tbiczXha3tzRWe8mp8ywCA3VZYXkdj82il0Ewpe0=; b=KMmndMI7fD15drjJk/7VMhjgPKoCx1uVkHENbPXbsdBuK40Hn4ely0ZvBw0fTNesfaV5oX wOYyOWD3UDhgciy4+2mMIVkEMTzwUnPXgESY9GU1ZmnHaB6Rq5Kwrz2X5rotFnsNFyoUaG bH1RaIId3J939VQHle4j9edpo+olnENsFNNYbAk/+trl/BhrafgtHcT6D/z9zsLSLV+jtN RpR5B8PwFXE9NEw/bVTY+CxXsmYFAo954BJrsEWWKezmqNb7MbpVwBBwXnAV3F8zz0HqVC Ck6SM+CBrKDYNOM8CO78wMlJgu6lz0X/HcOF0KzVztihyvVPGzuUlLNUxl7o4w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426947; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=bF1tbiczXha3tzRWe8mp8ywCA3VZYXkdj82il0Ewpe0=; b=H2SM/Bt7Lgbdo6Ab1oTKXMgP5WXwOWSTDJRUTaOB6kd2BBDKUe2tQPqSPUyfa++MRtTZSV ztBvMN6iI2AguxDg== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 23/27] signal: Handle ignored signals in do_sigaction(action != SIG_IGN) References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:07 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner When a real handler (including SIG_DFL) is installed for a signal, which had previously SIG_IGN set, then the list of ignored posix timers has to be checked for timers which are affected by this change. Add a list walk function which checks for the matching signal number and if found requeues the timers signal, so the timer is rearmed on signal delivery. Rearming the timer right away is not possible because that requires to drop sighand lock. No functional change as the counter part which queues the timers on the ignored list is still missing. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- kernel/signal.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) --- diff --git a/kernel/signal.c b/kernel/signal.c index 93c2d681309c..855f19f74287 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2031,7 +2031,55 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr) rcu_read_unlock(); return ret; } -#endif /* CONFIG_POSIX_TIMERS */ + +static void posixtimer_sig_unignore(struct task_struct *tsk, int sig) +{ + struct hlist_head *head =3D &tsk->signal->ignored_posix_timers; + struct hlist_node *tmp; + struct k_itimer *tmr; + + if (likely(hlist_empty(head))) + return; + + /* + * Rearming a timer with sighand lock held is not possible due to + * lock ordering vs. tmr::it_lock. Just stick the sigqueue back and + * let the signal delivery path deal with it whether it needs to be + * rearmed or not. This cannot be decided here w/o dropping sighand + * lock and creating a loop retry horror show. + */ + hlist_for_each_entry_safe(tmr, tmp , head, ignored_list) { + struct task_struct *target; + + /* + * tmr::sigq.info.si_signo is immutable, so accessing it + * without holding tmr::it_lock is safe. + */ + if (tmr->sigq.info.si_signo !=3D sig) + continue; + + hlist_del_init(&tmr->ignored_list); + + /* This should never happen and leaks a reference count */ + if (WARN_ON_ONCE(!list_empty(&tmr->sigq.list))) + continue; + + /* + * Get the target for the signal. If target is a thread and + * has exited by now, drop the reference count. + */ + rcu_read_lock(); + target =3D posixtimer_get_target(tmr); + if (target) + posixtimer_queue_sigqueue(&tmr->sigq, target, tmr->it_pid_type); + else + posixtimer_putref(tmr); + rcu_read_unlock(); + } +} +#else /* CONFIG_POSIX_TIMERS */ +static inline void posixtimer_sig_unignore(struct task_struct *tsk, int si= g) { } +#endif /* !CONFIG_POSIX_TIMERS */ =20 void do_notify_pidfd(struct task_struct *task) { @@ -4219,6 +4267,8 @@ int do_sigaction(int sig, struct k_sigaction *act, st= ruct k_sigaction *oact) sigaction_compat_abi(act, oact); =20 if (act) { + bool was_ignored =3D k->sa.sa_handler =3D=3D SIG_IGN; + sigdelsetmask(&act->sa.sa_mask, sigmask(SIGKILL) | sigmask(SIGSTOP)); *k =3D *act; @@ -4239,6 +4289,8 @@ int do_sigaction(int sig, struct k_sigaction *act, st= ruct k_sigaction *oact) flush_sigqueue_mask(&mask, &p->signal->shared_pending, NULL); for_each_thread(p, t) flush_sigqueue_mask(&mask, &t->pending, NULL); + } else if (was_ignored) { + posixtimer_sig_unignore(p, sig); } } From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 445C11B375B for ; Fri, 27 Sep 2024 08:49:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426952; cv=none; b=aldg6uUIHFdG/+r8pvqn+58155ts+EYQFFOpPBD9YKvgtl+Od8OBMMDOS5LO/UYtulrSp5Rz3mAEBMT4lPV7Q5V0J6qwAxzsFvTASYG9Z7N6b1oBJDqVWIFVIbIeXn8isYmIp2B+YQBXhAfTDlzItUEimOHx7U57Tore44LNP84= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426952; c=relaxed/simple; bh=9aWJhRR/RK2CQO7SC4nFWIvUcnJd1Mkv4T+t691rosA=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=OtG094oql0cEYEzO4fsTDulQE88bLsrbJzM5sJKXHbdiF1DGiV1sEokf1zMLPNqZ51SVLBWYgx98ZTtl6U2M5L+UD7uOmIq9h64LfrnNNlaAJf1t+84Cm+9Ng8Pl8AHYrzu+3SLeaUGYOmVWSjFgfwgKjA7rP19ClH0MGJvxciU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=c53wwif7; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=+rI6XlQ2; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="c53wwif7"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="+rI6XlQ2" Message-ID: <20240927084818.369295053@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426948; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=TF+iChkDpC8djbwSiyvAn6vmK0/roDaeslI0MvC9sk4=; b=c53wwif7oNcWytZgGt2ytmXB9CaVDjLFsf8ct82ZlLKv2DJgvaTMzWDVbyq0PtwSyWSoBg JQZPJXkuuViLZXMP7ntec0gFml9uzdHlWUt/3XiQgOkv6pOPxbY1+9lq4TCPdJvoNnE8Ia /oFj2hsVAQeWdKUcbrNbjGKx/8wTmfm6bv0acmCeUritkQ6a/U+UPc0moenEkqpKV1lk7I nDVtpd3NmtaeDuTtynGGPQ/6ouBxFc+ATkAaMCo/8fXa6fRD7o61BuKbMBN6q0jcCDAkd9 d6G0maEQRxFqPMC43D52QSsGUqXFmRX9slhRtzOUx3huXOlKkSeegKSIf3NEWg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426948; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=TF+iChkDpC8djbwSiyvAn6vmK0/roDaeslI0MvC9sk4=; b=+rI6XlQ2NBAQTPR0CcxmXINMunfUQNP8MB6g7a6X9+FcIG974LJRl/SnNyC3Y/SF7vfYIg EcXQ51zjI45d4pBA== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 24/27] signal: Queue ignored posixtimers on ignore list References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:08 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Queue posixtimers which have their signal ignored on the ignored list: 1) When the timer fires and the signal has SIG_IGN set 2) When SIG_IGN is installed via sigaction() and a timer signal is already queued This completes the SIG_IGN handling and such timers are not longer self rearmed which avoids pointless wakeups. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- kernel/signal.c | 44 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 36 insertions(+), 8 deletions(-) --- diff --git a/kernel/signal.c b/kernel/signal.c index 855f19f74287..cb29f817b71a 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -722,6 +722,16 @@ void signal_wake_up_state(struct task_struct *t, unsig= ned int state) kick_process(t); } =20 +static inline void posixtimer_sig_ignore(struct task_struct *tsk, struct s= igqueue *q); + +static void sigqueue_free_ignored(struct task_struct *ptmr_tsk, struct sig= queue *q) +{ + if (likely(!ptmr_tsk || q->info.si_code !=3D SI_TIMER)) + __sigqueue_free(q); + else + posixtimer_sig_ignore(ptmr_tsk, q); +} + /* * Remove signals in mask from the pending set and queue. * @@ -740,7 +750,7 @@ static void flush_sigqueue_mask(sigset_t *mask, struct = sigpending *s, struct tas list_for_each_entry_safe(q, n, &s->list, list) { if (sigismember(mask, q->info.si_signo)) { list_del_init(&q->list); - __sigqueue_free(q); + sigqueue_free_ignored(ptmr_tsk, q); } } } @@ -1960,9 +1970,8 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr) int sig =3D q->info.si_signo; struct task_struct *t; unsigned long flags; - int ret, result; + int result; =20 - ret =3D -1; rcu_read_lock(); =20 t =3D posixtimer_get_target(tmr); @@ -2008,13 +2017,24 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr) */ q->info.si_overrun =3D 0; =20 - ret =3D 1; /* the signal is ignored */ if (!prepare_signal(sig, t, false)) { result =3D TRACE_SIGNAL_IGNORED; + + /* Paranoia check. Try to survive. */ + if (WARN_ON_ONCE(!list_empty(&q->list))) + goto out; + + if (hlist_unhashed(&tmr->ignored_list)) { + hlist_add_head(&tmr->ignored_list, &t->signal->ignored_posix_timers); + posixtimer_sigqueue_getref(q); + } goto out; } =20 - ret =3D 0; + /* This should never happen and leaks a reference count */ + if (WARN_ON_ONCE(!hlist_unhashed(&tmr->ignored_list))) + hlist_del_init(&tmr->ignored_list); + if (unlikely(!list_empty(&q->list))) { /* This holds a reference count already */ result =3D TRACE_SIGNAL_ALREADY_PENDING; @@ -2029,7 +2049,14 @@ int posixtimer_send_sigqueue(struct k_itimer *tmr) unlock_task_sighand(t, &flags); ret: rcu_read_unlock(); - return ret; + return 0; +} + +static inline void posixtimer_sig_ignore(struct task_struct *tsk, struct s= igqueue *q) +{ + struct k_itimer *tmr =3D container_of(q, struct k_itimer, sigq); + + hlist_add_head(&tmr->ignored_list, &tsk->signal->ignored_posix_timers); } =20 static void posixtimer_sig_unignore(struct task_struct *tsk, int sig) @@ -2078,6 +2105,7 @@ static void posixtimer_sig_unignore(struct task_struc= t *tsk, int sig) } } #else /* CONFIG_POSIX_TIMERS */ +static inline void posixtimer_sig_ignore(struct task_struct *tsk, struct s= igqueue *q) { } static inline void posixtimer_sig_unignore(struct task_struct *tsk, int si= g) { } #endif /* !CONFIG_POSIX_TIMERS */ =20 @@ -4286,9 +4314,9 @@ int do_sigaction(int sig, struct k_sigaction *act, st= ruct k_sigaction *oact) if (sig_handler_ignored(sig_handler(p, sig), sig)) { sigemptyset(&mask); sigaddset(&mask, sig); - flush_sigqueue_mask(&mask, &p->signal->shared_pending, NULL); + flush_sigqueue_mask(&mask, &p->signal->shared_pending, p); for_each_thread(p, t) - flush_sigqueue_mask(&mask, &t->pending, NULL); + flush_sigqueue_mask(&mask, &t->pending, p); } else if (was_ignored) { posixtimer_sig_unignore(p, sig); } From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 566531B3B07 for ; Fri, 27 Sep 2024 08:49:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426953; cv=none; b=fVh4RzRt/6Gg0wdOBEtVVCz1OUdLe62P78ANn/dy3qLpK/9JwVD7zPvC4ECrUJzAyKKJKrjS9H+2T1HaK0FH8BxHhl6+X3X15dhBwckfWR9gj5T0XXr5YKjj6/q88iHk5jjRqWus9vUvOojmR5zua4WcNE900hRIcg5pXyXFeWk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426953; c=relaxed/simple; bh=OotEkdlkvMQJgL29FdEkVAojV0i26KLmzxwQSi5vj+g=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=r+2vo/4B1y8DPtwe9bdp+rkWSDpX9NaZy3Q9Hdt9TzMPjE9r3J8DxshkmyoA0FbgWtzdVUKUyajJSFtmE9g2IliEh69u6bc4uzVm1hhp6CHHUKInGwb8GDtzv8nypB4mfal8VxiG8EieRLf4yx9M6K29b1mehz37lzJ4av3x6ic= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Ko1WePtd; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Xs7M0AcF; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Ko1WePtd"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Xs7M0AcF" Message-ID: <20240927084818.428157721@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426950; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=u11WxY/lGhbpoPTuquxmgFwL7MsbHwkGbP1bdkzo7pA=; b=Ko1WePtdbZLv4BdIySURdWnWfFArYzUWmJdNBh8AhRyWddnrv78zJFr6isIZMJw5QvywNZ fnPrEcoR+ihp0YpbtJ9lGHWYrotBeaEOGgfxlAXCmrKAlyotqmS6keGzWROyHPdZTIvVF6 OWEkMh9Bn1npMfxsOfOQKYLNBdpfE9Xpk4yE7ZLrAsnLdnFEcmNcs+gNtFkppr6AAlNwpK IMjji5TqaA8DuOhCQEJAD43nw0NLGp5OUq/ltzJP+s79ngqEnPDpr3mRC139LPkm52FxDg +jgj0mnDGuJJwLPeZhItlYUJyrJb7KWQVqt56Q8nuAS83StUtBpfOrIs+mKY3A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426950; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=u11WxY/lGhbpoPTuquxmgFwL7MsbHwkGbP1bdkzo7pA=; b=Xs7M0AcFTp/eQGxL3tOUf+F2dn7QpO2vLjM58loMQhP2Z9e6r3IrriSDP/AVvG/X5mnN5v 087i9FqUTPO/dUCA== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 25/27] posix-timers: Cleanup SIG_IGN workaround leftovers References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:09 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Now that ignored posix timer signals are requeued and the timers are rearmed on signal delivery the workaround to keep such timers alive and self rearm them is not longer required. Remove the relevant hacks and the not longer required return values from the related functions. The alarm timer workarounds will be cleaned up in a separate step. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 2 - kernel/signal.c | 3 - kernel/time/alarmtimer.c | 47 +++++------------------------ kernel/time/posix-cpu-timers.c | 18 ++--------- kernel/time/posix-timers.c | 65 +++---------------------------------= ----- kernel/time/posix-timers.h | 2 - 6 files changed, 21 insertions(+), 116 deletions(-) --- --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -111,7 +111,7 @@ static inline void posix_cputimers_rt_wa =20 void posixtimer_rearm_itimer(struct task_struct *p); bool posixtimer_init_sigqueue(struct sigqueue *q); -int posixtimer_send_sigqueue(struct k_itimer *tmr); +void posixtimer_send_sigqueue(struct k_itimer *tmr); bool posixtimer_deliver_signal(struct kernel_siginfo *info); void posixtimer_free_timer(struct k_itimer *timer); =20 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1964,7 +1964,7 @@ static inline struct task_struct *posixt return t; } =20 -int posixtimer_send_sigqueue(struct k_itimer *tmr) +void posixtimer_send_sigqueue(struct k_itimer *tmr) { struct sigqueue *q =3D &tmr->sigq; int sig =3D q->info.si_signo; @@ -2049,7 +2049,6 @@ int posixtimer_send_sigqueue(struct k_it unlock_task_sighand(t, &flags); ret: rcu_read_unlock(); - return 0; } =20 static inline void posixtimer_sig_ignore(struct task_struct *tsk, struct s= igqueue *q) --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -197,28 +197,15 @@ static enum hrtimer_restart alarmtimer_f { struct alarm *alarm =3D container_of(timer, struct alarm, timer); struct alarm_base *base =3D &alarm_bases[alarm->type]; - unsigned long flags; - int ret =3D HRTIMER_NORESTART; - int restart =3D ALARMTIMER_NORESTART; =20 - spin_lock_irqsave(&base->lock, flags); - alarmtimer_dequeue(base, alarm); - spin_unlock_irqrestore(&base->lock, flags); + scoped_guard (spinlock_irqsave, &base->lock) + alarmtimer_dequeue(base, alarm); =20 if (alarm->function) - restart =3D alarm->function(alarm, base->get_ktime()); - - spin_lock_irqsave(&base->lock, flags); - if (restart !=3D ALARMTIMER_NORESTART) { - hrtimer_set_expires(&alarm->timer, alarm->node.expires); - alarmtimer_enqueue(base, alarm); - ret =3D HRTIMER_RESTART; - } - spin_unlock_irqrestore(&base->lock, flags); + alarm->function(alarm, base->get_ktime()); =20 trace_alarmtimer_fired(alarm, base->get_ktime()); - return ret; - + return HRTIMER_NORESTART; } =20 ktime_t alarm_expires_remaining(const struct alarm *alarm) @@ -567,30 +554,14 @@ static enum alarmtimer_type clock2alarm( * * Return: whether the timer is to be restarted */ -static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, - ktime_t now) +static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, kti= me_t now) { - struct k_itimer *ptr =3D container_of(alarm, struct k_itimer, - it.alarm.alarmtimer); - enum alarmtimer_restart result =3D ALARMTIMER_NORESTART; - unsigned long flags; - - spin_lock_irqsave(&ptr->it_lock, flags); + struct k_itimer *ptr =3D container_of(alarm, struct k_itimer, it.alarm.al= armtimer); =20 - if (posix_timer_queue_signal(ptr) && ptr->it_interval) { - /* - * Handle ignored signals and rearm the timer. This will go - * away once we handle ignored signals proper. Ensure that - * small intervals cannot starve the system. - */ - ptr->it_overrun +=3D __alarm_forward_now(alarm, ptr->it_interval, true); - ++ptr->it_signal_seq; - ptr->it_status =3D POSIX_TIMER_ARMED; - result =3D ALARMTIMER_RESTART; - } - spin_unlock_irqrestore(&ptr->it_lock, flags); + guard(spinlock_irqsave)(&ptr->it_lock); + posix_timer_queue_signal(ptr); =20 - return result; + return ALARMTIMER_NORESTART; } =20 /** --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -595,21 +595,11 @@ static void cpu_timer_fire(struct k_itim */ wake_up_process(timer->it_process); cpu_timer_setexpires(ctmr, 0); - } else if (!timer->it_interval) { - /* - * One-shot timer. Clear it as soon as it's fired. - */ + } else { posix_timer_queue_signal(timer); - cpu_timer_setexpires(ctmr, 0); - } else if (posix_timer_queue_signal(timer)) { - /* - * The signal did not get queued because the signal - * was ignored, so we won't get any callback to - * reload the timer. But we need to keep it - * ticking in case the signal is deliverable next time. - */ - posix_cpu_timer_rearm(timer); - ++timer->it_signal_seq; + /* Disable oneshot timers */ + if (!timer->it_interval) + cpu_timer_setexpires(ctmr, 0); } } =20 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -300,10 +300,9 @@ bool posixtimer_deliver_signal(struct ke return ret; } =20 -int posix_timer_queue_signal(struct k_itimer *timr) +void posix_timer_queue_signal(struct k_itimer *timr) { enum posix_timer_state state =3D POSIX_TIMER_DISARMED; - int ret; =20 lockdep_assert_held(&timr->it_lock); =20 @@ -313,9 +312,7 @@ int posix_timer_queue_signal(struct k_it } timr->it_status =3D state; =20 - ret =3D posixtimer_send_sigqueue(timr); - /* If we failed to send the signal the timer stops. */ - return ret > 0; + posixtimer_send_sigqueue(timr); } =20 /* @@ -328,62 +325,10 @@ int posix_timer_queue_signal(struct k_it static enum hrtimer_restart posix_timer_fn(struct hrtimer *timer) { struct k_itimer *timr =3D container_of(timer, struct k_itimer, it.real.ti= mer); - enum hrtimer_restart ret =3D HRTIMER_NORESTART; - unsigned long flags; =20 - spin_lock_irqsave(&timr->it_lock, flags); - - if (posix_timer_queue_signal(timr)) { - /* - * The signal was not queued due to SIG_IGN. As a - * consequence the timer is not going to be rearmed from - * the signal delivery path. But as a real signal handler - * can be installed later the timer must be rearmed here. - */ - if (timr->it_interval !=3D 0) { - ktime_t now =3D hrtimer_cb_get_time(timer); - - /* - * FIXME: What we really want, is to stop this - * timer completely and restart it in case the - * SIG_IGN is removed. This is a non trivial - * change to the signal handling code. - * - * For now let timers with an interval less than a - * jiffy expire every jiffy and recheck for a - * valid signal handler. - * - * This avoids interrupt starvation in case of a - * very small interval, which would expire the - * timer immediately again. - * - * Moving now ahead of time by one jiffy tricks - * hrtimer_forward() to expire the timer later, - * while it still maintains the overrun accuracy - * for the price of a slight inconsistency in the - * timer_gettime() case. This is at least better - * than a timer storm. - * - * Only required when high resolution timers are - * enabled as the periodic tick based timers are - * automatically aligned to the next tick. - */ - if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS)) { - ktime_t kj =3D TICK_NSEC; - - if (timr->it_interval < kj) - now =3D ktime_add(now, kj); - } - - timr->it_overrun +=3D hrtimer_forward(timer, now, timr->it_interval); - ret =3D HRTIMER_RESTART; - ++timr->it_signal_seq; - timr->it_status =3D POSIX_TIMER_ARMED; - } - } - - unlock_timer(timr, flags); - return ret; + guard(spinlock_irqsave)(&timr->it_lock); + posix_timer_queue_signal(timr); + return HRTIMER_NORESTART; } =20 static struct pid *good_sigevent(sigevent_t * event) --- a/kernel/time/posix-timers.h +++ b/kernel/time/posix-timers.h @@ -42,7 +42,7 @@ extern const struct k_clock clock_proces extern const struct k_clock clock_thread; extern const struct k_clock alarm_clock; =20 -int posix_timer_queue_signal(struct k_itimer *timr); +void posix_timer_queue_signal(struct k_itimer *timr); =20 void common_timer_get(struct k_itimer *timr, struct itimerspec64 *cur_sett= ing); int common_timer_set(struct k_itimer *timr, int flags, From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B8CB1B3B13 for ; Fri, 27 Sep 2024 08:49:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426954; cv=none; b=Dc8aFqH9ySwWVWodqDlLJ5g5mo8rZAbGKN5WihvVcwb7GRFeyjbukwwajAW1vDfK3AWx9SefFGJTkDLt2oDrd+qat+RTqnT47h2lDhZVR44CgKPjE8kzq2FSgFvH0uEmEMpfUgGbX00j4G36czRHiIFev0DPhEQeR6P3e422QQ8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426954; c=relaxed/simple; bh=7e4v9WkDJuPdohdeoK6mQPaWH99Nff2q7xm62vNvfEU=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=tih/1a/epeXwKkh5aSzQZT5SoRnH6+dhAvkxku5f8/zflmDWRGxiz7Uew+oIIbtlAdDpy0s2pLuAoRXEOT6WTIIZs6Ap1TITAp7LPoP6oX615W59jyTh/Q+XG3pFbLcDLS8zGDPVLqy97lUi6J/B5Nas+L7U8OPma5Eu0hvLl9w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=Dcbf3IrY; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=ww8EUDxS; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="Dcbf3IrY"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="ww8EUDxS" Message-ID: <20240927084818.487794783@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426951; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=9D2jiH+/RxRu1E5rzqzRvNNr94gJCBzotdwDIvHO6+s=; b=Dcbf3IrYC3MQrC1pVYHVCFkv3AcLHTTiDrPbH0lnukmDCysphwCHaIXTygFN0yg0j36yvL K5MTQ4MIcSqBT9buXjoXXS1g+Y9I8AbN53B3GC1g96PfFQYkd5FhPM7zcNXT2sXmIc81g0 j2WOwCs/OKHOXkdT/d5kID+Yr/o/P3oiJtQ806FeHnn/yUPlLhJaMf3hn3OmebthWDwsIn hQRft/AesayizraYXO6eDja7cQ1wMHUfOCo2jTwY0Gm2hwJflrYr+erIOCmmsnJsi2hyp1 BsmKSnLp5H4UkLEXInUMiOOXKFprOYR98iTw40t9ine5QPe08tlKEbRL2h2Ktw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426951; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=9D2jiH+/RxRu1E5rzqzRvNNr94gJCBzotdwDIvHO6+s=; b=ww8EUDxSCTh96dsupDOpf5BN55ZMfpvmKideT3lhdgZuy3FF7Z9zSVXg8sYRq5Foi0vWR5 CaR/tcNSuG2LFDCw== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 26/27] alarmtimers: Remove the throttle mechanism from alarm_forward_now() References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:11 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Now that ignored posix timer signals are requeued and the timers are rearmed on signal delivery the workaround to keep such timers alive and self rearm them is not longer required. Remove the unused alarm timer parts. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- kernel/time/alarmtimer.c | 28 ++-------------------------- 1 file changed, 2 insertions(+), 26 deletions(-) --- --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -467,35 +467,11 @@ u64 alarm_forward(struct alarm *alarm, k } EXPORT_SYMBOL_GPL(alarm_forward); =20 -static u64 __alarm_forward_now(struct alarm *alarm, ktime_t interval, bool= throttle) +u64 alarm_forward_now(struct alarm *alarm, ktime_t interval) { struct alarm_base *base =3D &alarm_bases[alarm->type]; - ktime_t now =3D base->get_ktime(); - - if (IS_ENABLED(CONFIG_HIGH_RES_TIMERS) && throttle) { - /* - * Same issue as with posix_timer_fn(). Timers which are - * periodic but the signal is ignored can starve the system - * with a very small interval. The real fix which was - * promised in the context of posix_timer_fn() never - * materialized, but someone should really work on it. - * - * To prevent DOS fake @now to be 1 jiffy out which keeps - * the overrun accounting correct but creates an - * inconsistency vs. timer_gettime(2). - */ - ktime_t kj =3D NSEC_PER_SEC / HZ; =20 - if (interval < kj) - now =3D ktime_add(now, kj); - } - - return alarm_forward(alarm, now, interval); -} - -u64 alarm_forward_now(struct alarm *alarm, ktime_t interval) -{ - return __alarm_forward_now(alarm, interval, false); + return alarm_forward(alarm, base->get_ktime(), interval); } EXPORT_SYMBOL_GPL(alarm_forward_now); From nobody Thu Nov 28 22:27:51 2024 Received: from galois.linutronix.de (Galois.linutronix.de [193.142.43.55]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA8A51B3B2F for ; Fri, 27 Sep 2024 08:49:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=193.142.43.55 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426955; cv=none; b=BWvZl4diC/3DleY0B9HL/YAuq7xki6tQwOHzYbFFKDHFgoDLOJdg/wUoNBo9DrY6S2wYr+cDPgOyz/kqElLGX5JovieML9r6kZnTd4bOHHavw+Rcqykcq2KZ//0rQ6gnqtKM2VPMO7c6XkCxVJFRg8W3zGmMRqidMpwurRnqszE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1727426955; c=relaxed/simple; bh=7zGLzpG45aslQEdkxT7c+S67ymcLqlpUALg8nAaSMGI=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=SLmzzm8W4fA5JDaNlqnVTKX4CcIJu7VCgRB03HcQU1mRiqlHzltk0oxbcLsFu7dLuCUzOrl2u/WAZCrn2eCUuVtBVb/eEF4WFS/5eu34hPcx0epzAfdkY84p6MKf8KGSn1r4Scuw3avCZYxtW7qly6xZ8fqGdw4rp5zWLtV43TA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de; spf=pass smtp.mailfrom=linutronix.de; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=cl831p8+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=X8KuIP1H; arc=none smtp.client-ip=193.142.43.55 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linutronix.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linutronix.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="cl831p8+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="X8KuIP1H" Message-ID: <20240927084818.547327138@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1727426952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=rjS/LkNZGaAl6fB4xGY0nR6sDvgfIhY1KsxZmw2tZDI=; b=cl831p8+QUnk3jT3Oruc+wz4yoxc7aUpvYgetyRzW8GmFcYb23hM7OxOARbFNHrklPjGiZ nToM3bww96vFqO17xikvPhAIArFMh9j/CHTrkS46CYATmpDpIL440C4ynsKFYKii0CI1L9 XR/ZTMYlJnZZNTFBU41muBeoMBRUii5bl2R8lUo3uLVN5cCD87J44rBJiXW8Mtqu2Vo2O3 4ak5uLWZ72nULnf9OBDK1cnN2HC+lMAKp1PwbudL/DITudSE+rVKTvSC3cofsz6Yv+LCGS Et0gjueNZ89seySAbcLRKtBc5Y+I/qfkT5O5RedyvMLFcndiF0RB692wzEMGPQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1727426952; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: references:references; bh=rjS/LkNZGaAl6fB4xGY0nR6sDvgfIhY1KsxZmw2tZDI=; b=X8KuIP1Hob0T4wI3c3rP13XcpX8M+EQaJLJw8FJJXPEIR+qV0PDmJtEQJOQ2WJG9aEPJ2H K1RpE3YGfn9shMCA== From: Thomas Gleixner To: LKML Cc: Anna-Maria Behnsen , Frederic Weisbecker , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch v4 27/27] alarmtimers: Remove return value from alarm functions References: <20240927083900.989915582@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Fri, 27 Sep 2024 10:49:12 +0200 (CEST) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner Now that the SIG_IGN problem is solved in the core code, the alarmtimer callbacks do not require a return value anymore. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) --- drivers/power/supply/charger-manager.c | 3 +-- fs/timerfd.c | 4 +--- include/linux/alarmtimer.h | 10 ++-------- kernel/time/alarmtimer.c | 16 +++++----------- net/netfilter/xt_IDLETIMER.c | 4 +--- 5 files changed, 10 insertions(+), 27 deletions(-) --- diff --git a/drivers/power/supply/charger-manager.c b/drivers/power/supply/= charger-manager.c index 96f0a7fbf105..09ec0ecf1486 100644 --- a/drivers/power/supply/charger-manager.c +++ b/drivers/power/supply/charger-manager.c @@ -1412,10 +1412,9 @@ static inline struct charger_desc *cm_get_drv_data(s= truct platform_device *pdev) return dev_get_platdata(&pdev->dev); } =20 -static enum alarmtimer_restart cm_timer_func(struct alarm *alarm, ktime_t = now) +static void cm_timer_func(struct alarm *alarm, ktime_t now) { cm_timer_set =3D false; - return ALARMTIMER_NORESTART; } =20 static int charger_manager_probe(struct platform_device *pdev) diff --git a/fs/timerfd.c b/fs/timerfd.c index 4bf2f8bfec11..67400c9bde07 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -79,13 +79,11 @@ static enum hrtimer_restart timerfd_tmrproc(struct hrti= mer *htmr) return HRTIMER_NORESTART; } =20 -static enum alarmtimer_restart timerfd_alarmproc(struct alarm *alarm, - ktime_t now) +static void timerfd_alarmproc(struct alarm *alarm, ktime_t now) { struct timerfd_ctx *ctx =3D container_of(alarm, struct timerfd_ctx, t.alarm); timerfd_triggered(ctx); - return ALARMTIMER_NORESTART; } =20 /* diff --git a/include/linux/alarmtimer.h b/include/linux/alarmtimer.h index 05e758b8b894..3ffa5341dce2 100644 --- a/include/linux/alarmtimer.h +++ b/include/linux/alarmtimer.h @@ -20,12 +20,6 @@ enum alarmtimer_type { ALARM_BOOTTIME_FREEZER, }; =20 -enum alarmtimer_restart { - ALARMTIMER_NORESTART, - ALARMTIMER_RESTART, -}; - - #define ALARMTIMER_STATE_INACTIVE 0x00 #define ALARMTIMER_STATE_ENQUEUED 0x01 =20 @@ -42,14 +36,14 @@ enum alarmtimer_restart { struct alarm { struct timerqueue_node node; struct hrtimer timer; - enum alarmtimer_restart (*function)(struct alarm *, ktime_t now); + void (*function)(struct alarm *, ktime_t now); enum alarmtimer_type type; int state; void *data; }; =20 void alarm_init(struct alarm *alarm, enum alarmtimer_type type, - enum alarmtimer_restart (*function)(struct alarm *, ktime_t)); + void (*function)(struct alarm *, ktime_t)); void alarm_start(struct alarm *alarm, ktime_t start); void alarm_start_relative(struct alarm *alarm, ktime_t start); void alarm_restart(struct alarm *alarm); diff --git a/kernel/time/alarmtimer.c b/kernel/time/alarmtimer.c index 593e7d561fa8..37d2d79daea4 100644 --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -321,7 +321,7 @@ static int alarmtimer_resume(struct device *dev) =20 static void __alarm_init(struct alarm *alarm, enum alarmtimer_type type, - enum alarmtimer_restart (*function)(struct alarm *, ktime_t)) + void (*function)(struct alarm *, ktime_t)) { timerqueue_init(&alarm->node); alarm->timer.function =3D alarmtimer_fired; @@ -337,7 +337,7 @@ __alarm_init(struct alarm *alarm, enum alarmtimer_type = type, * @function: callback that is run when the alarm fires */ void alarm_init(struct alarm *alarm, enum alarmtimer_type type, - enum alarmtimer_restart (*function)(struct alarm *, ktime_t)) + void (*function)(struct alarm *, ktime_t)) { hrtimer_init(&alarm->timer, alarm_bases[type].base_clockid, HRTIMER_MODE_ABS); @@ -530,14 +530,12 @@ static enum alarmtimer_type clock2alarm(clockid_t clo= ckid) * * Return: whether the timer is to be restarted */ -static enum alarmtimer_restart alarm_handle_timer(struct alarm *alarm, kti= me_t now) +static void alarm_handle_timer(struct alarm *alarm, ktime_t now) { struct k_itimer *ptr =3D container_of(alarm, struct k_itimer, it.alarm.al= armtimer); =20 guard(spinlock_irqsave)(&ptr->it_lock); posix_timer_queue_signal(ptr); - - return ALARMTIMER_NORESTART; } =20 /** @@ -698,18 +696,14 @@ static int alarm_timer_create(struct k_itimer *new_ti= mer) * @now: time at the timer expiration * * Wakes up the task that set the alarmtimer - * - * Return: ALARMTIMER_NORESTART */ -static enum alarmtimer_restart alarmtimer_nsleep_wakeup(struct alarm *alar= m, - ktime_t now) +static void alarmtimer_nsleep_wakeup(struct alarm *alarm, ktime_t now) { struct task_struct *task =3D alarm->data; =20 alarm->data =3D NULL; if (task) wake_up_process(task); - return ALARMTIMER_NORESTART; } =20 /** @@ -761,7 +755,7 @@ static int alarmtimer_do_nsleep(struct alarm *alarm, kt= ime_t absexp, =20 static void alarm_init_on_stack(struct alarm *alarm, enum alarmtimer_type type, - enum alarmtimer_restart (*function)(struct alarm *, ktime_t)) + void (*function)(struct alarm *, ktime_t)) { hrtimer_init_on_stack(&alarm->timer, alarm_bases[type].base_clockid, HRTIMER_MODE_ABS); diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c index db720efa811d..5514600586a9 100644 --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -107,14 +107,12 @@ static void idletimer_tg_expired(struct timer_list *t) schedule_work(&timer->work); } =20 -static enum alarmtimer_restart idletimer_tg_alarmproc(struct alarm *alarm, - ktime_t now) +static void idletimer_tg_alarmproc(struct alarm *alarm, ktime_t now) { struct idletimer_tg *timer =3D alarm->data; =20 pr_debug("alarm %s expired\n", timer->attr.attr.name); schedule_work(&timer->work); - return ALARMTIMER_NORESTART; } =20 static int idletimer_check_sysfs_name(const char *name, unsigned int size)