From nobody Mon Nov 25 00:45:39 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 F15C9139579 for ; Thu, 31 Oct 2024 15:46:25 +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=1730389588; cv=none; b=Dv90dZfTtnsFsVcGpx2decL9TLUaQFFH1W3g1GBzzPi32H3vutPBejCwvr8KtT6CGNTuUgAntErCUr5AysVaXACokxMES8zSlcuP4qbvF2fcjVhAdpgtsvrplddBHKJ9y4880Vg+b+Z1QbgkI93fD9+0F3OJqOcVkB4P5Nbj+yc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389588; c=relaxed/simple; bh=XRuhxhopLzO5Vu9qd4cNixf/PZpl4ZiPpEttVfHF2Cs=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=tFm6KH1GXiAjv4RE56YhxCp+9QkTsqKq0DzxC51qMfARjN6G7NfaX6EAqd/9oJPau3bFIBRPmLX+vCn5/E4hSrLobz7kw2Wxl2u+UrDT9sMnUfkYEyeZko7IUx3h1qKo+HUJZdUTO0VUalkX0Z+C8+HQPm6ymTgQ3Vvx3gp6dw8= 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=SWFTd9ud; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=4lO0nV6r; 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="SWFTd9ud"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="4lO0nV6r" Message-ID: <20241031154424.613821401@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389584; 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=s4k0a+5vBj3M/rE56Uz/IJf6Dawsk5+OJfCywabMbsY=; b=SWFTd9udKnyNdBTtAYFS9SVIxTeSY9O3L7oqfH7eZ9jZeqfABsTzoh52oUz//RfDN4LNHW 1MVBvrMs9YAsQLvRuCYhTMqspzliS1cPiyEONbQ25p2oVzUjwi7SDyfaXgdelJlCE1o8wE XCYwYtTgeMB4HLpyZqfp6k8CGOaVEGvqsxDPWyS1tqYKFcM3PtpMlTzTdDyq5U37l8g5uK W6Mu4rMJ0cRlWk7zc/Qob905coT/NmM/hbIIsPrtMgFtI+pcDBvY4OcSU1Q+k1GOscNf59 CjiIWcSm1fS2KqqbOpLJIAF+e4KVMqOcgCuJJS1CRWRXNjh3XsVKoNy9Eg6VVQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389584; 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=s4k0a+5vBj3M/rE56Uz/IJf6Dawsk5+OJfCywabMbsY=; b=4lO0nV6rn0xzHpIkQufvGKFHb+GyogUdu6Qjti3e2/GzakIPfIWhytkPtHkFnlFaOLW/Yj guwHC42mhX7BfnAA== 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 v6 01/20] posix-timers: Make signal delivery consistent References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:24 +0100 (CET) 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 for posix timer related signals. Change posix_timer_deliver_signal() 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. This is also a preparatory change to embed the sigqueue into the k_itimer structure, which in turn allows to remove the si_sys_private magic. Signed-off-by: Thomas Gleixner Reviewed-by: Frederic Weisbecker --- V6: Remove the sequence increment from delivery and turn the requeue pending check into a WARN_ON_ONCE() (Frederic) Move the sequence increment into the delete hook so that the exit cleanup path is covered too --- include/linux/posix-timers.h | 2 -- kernel/signal.c | 6 ++---- kernel/time/posix-cpu-timers.c | 2 +- kernel/time/posix-timers.c | 28 ++++++++++++++++------------ 4 files changed, 19 insertions(+), 19 deletions(-) --- --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -137,8 +137,6 @@ static inline void clear_posix_cputimers 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 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -550,10 +550,8 @@ static void collect_signal(int sig, stru list_del_init(&first->list); copy_siginfo(info, &first->info); =20 - *resched_timer =3D - (first->flags & SIGQUEUE_PREALLOC) && - (info->si_code =3D=3D SI_TIMER) && - (info->si_sys_private); + *resched_timer =3D (first->flags & SIGQUEUE_PREALLOC) && + (info->si_code =3D=3D SI_TIMER); =20 __sigqueue_free(first); } else { --- 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 * - 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); --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -269,7 +269,10 @@ bool posixtimer_deliver_signal(struct ke 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 && !WARN_ON_ONCE(timr->it_status !=3D POSIX_TIMER_R= EQUEUE_PENDING)) { timr->kclock->timer_rearm(timr); =20 timr->it_status =3D POSIX_TIMER_ARMED; @@ -281,6 +284,7 @@ bool posixtimer_deliver_signal(struct ke } ret =3D true; =20 +out_unlock: unlock_timer(timr, flags); out: spin_lock(¤t->sighand->siglock); @@ -293,19 +297,18 @@ bool posixtimer_deliver_signal(struct ke 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) { + 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); + 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; } @@ -663,7 +666,7 @@ void common_timer_get(struct k_itimer *t * 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); @@ -863,8 +866,6 @@ void posix_timer_set_common(struct k_iti 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; @@ -882,8 +883,6 @@ int common_timer_set(struct k_itimer *ti 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. @@ -933,6 +932,9 @@ static int do_timer_settime(timer_t time 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; @@ -1001,7 +1003,6 @@ int common_timer_del(struct k_itimer *ti { 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; @@ -1012,6 +1013,9 @@ static inline int timer_delete_hook(stru { const struct k_clock *kc =3D timer->kclock; =20 + /* Prevent signal delivery and rearming. */ + timer->it_signal_seq++; + if (WARN_ON_ONCE(!kc || !kc->timer_del)) return -EINVAL; return kc->timer_del(timer); From nobody Mon Nov 25 00:45:39 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 6197133F7 for ; Thu, 31 Oct 2024 15:46:26 +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=1730389590; cv=none; b=YadWDIa0gpnANJuilN1Qx+SzaqHCVlNHn7zRDHEkRl7ZmgYzsrZY0kNhFevgMPUGio74jaw3fRAInW8cf18ywQGJz7IAs5VDwY1jW5Rxzm9qq7wfl15kwmbWvXcVJqbgZlVmCgBR1MEcAv8DjCw1ZcQrd1AFCEwQVLiaHJC28DU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389590; c=relaxed/simple; bh=KX1FFQwMnsJoVPsOnqh6Joq5g99AWzhEz+Vr7i6dJ58=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=aDc9lkmAsjysqVXqJoHgy15eMN8uokGpB8IJfNJF2WbwcoXTAqgFyM0c6ieBq2y9N0tlhxOmDRnLHOneF7eHGf2pjQVDjtLd4Q6AMwqYDbcu9MrW7zhpZtEQnQJaLl7vwP5aJe0INCDjmElMNsCey/FTONy3yKg+um/1yxluXRs= 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=ycLUHNR+; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=k8eg3rPw; 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="ycLUHNR+"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="k8eg3rPw" Message-ID: <20241031154424.677253735@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389585; 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=8Ktc/ZSZllcX0GFHzNBw2jkczc+2QhjWp2jl7bmrkpY=; b=ycLUHNR+kek0COxqqSZI4FDdnQV5XVgcVYpuylcXnLXbWu+KIg/SIr0ipc+h+hHWJ4cDO1 deWc1N6oKSThxDAS8Qn5FOenM+wgKDB8Pl8M+P0O722tEP/WkJLxgbKg0W2+CVYuOMtgoc WEpx0tqsXt03e3A0wxqerWavckH+qTJ6rZCG1bJu2dyN+x27/6DwMML7iFceMb9a9Q7IfZ 9DRoLwViqBiuxNwGFN4Qw9shkb9XbzQx0ORjYLkvLHk0D5n+GWYlkojYCjwn2egdK0+ehO f6qeXxnyS/SPIbPMGAJnPYm50YZinHRB+NjsHJMQu+0kyKpM5PfyMSUfx06Sfg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389585; 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=8Ktc/ZSZllcX0GFHzNBw2jkczc+2QhjWp2jl7bmrkpY=; b=k8eg3rPw5dnOW29o3steDs2kRPq+o4qxNwj6F7Q0FiX4GeJz3vwePCCHJjkcNgIepi1x5u x4/VJoRhgExM9EAw== 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 v6 02/20] posix-timers: Make signal overrun accounting sensible References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:25 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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. Don't touch info::si_overrun in send_sigqueue() and only store the overrun value at signal delivery time, which is computed from the timer itself relative to the expiry time. Signed-off-by: Thomas Gleixner Acked-by: Peter Zijlstra (Intel) Reviewed-by: Frederic Weisbecker --- V6: Fold the timer_overrun_to_int() cleanup from Frederic and remove all overrun fiddling from the signal path. --- kernel/signal.c | 6 ------ kernel/time/posix-timers.c | 11 ++++++----- 2 files changed, 6 insertions(+), 11 deletions(-) --- --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1968,15 +1968,9 @@ int send_sigqueue(struct sigqueue *q, st =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; --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -233,11 +233,12 @@ static __init int init_posix_timers(void * The siginfo si_overrun field and the return value of timer_getoverrun(2) * are of type int. Clamp the overrun value to INT_MAX */ -static inline int timer_overrun_to_int(struct k_itimer *timr, int baseval) +static inline int timer_overrun_to_int(struct k_itimer *timr) { - s64 sum =3D timr->it_overrun_last + (s64)baseval; + if (timr->it_overrun_last > (s64)INT_MAX) + return INT_MAX; =20 - return sum > (s64)INT_MAX ? INT_MAX : (int)sum; + return (int)timr->it_overrun_last; } =20 static void common_hrtimer_rearm(struct k_itimer *timr) @@ -280,7 +281,7 @@ bool posixtimer_deliver_signal(struct ke timr->it_overrun =3D -1LL; ++timr->it_signal_seq; =20 - info->si_overrun =3D timer_overrun_to_int(timr, info->si_overrun); + info->si_overrun =3D timer_overrun_to_int(timr); } ret =3D true; =20 @@ -774,7 +775,7 @@ SYSCALL_DEFINE1(timer_getoverrun, timer_ if (!timr) return -EINVAL; =20 - overrun =3D timer_overrun_to_int(timr, 0); + overrun =3D timer_overrun_to_int(timr); unlock_timer(timr, flags); =20 return overrun; From nobody Mon Nov 25 00:45:39 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 74E0713A87C for ; Thu, 31 Oct 2024 15:46:28 +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=1730389590; cv=none; b=LmfkA8mypQ+Z8df4BtzSt83DAQywReKBaI8K41LWpgBwBYcuvc+SRVoTBYeaetsHKzV0FLhRhdMWn2Bt9PSjkKmGNNtyP3X8/EqoNPz3Rj+sDM0ltVZCGX0uxhNho2/XruKkY2U8GxV8F4+3jF2wFZJoHzwNJ+WUZeI/VNfg9oA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389590; c=relaxed/simple; bh=0v21sYAYBwU9cXvaccySe7nMT4VWgURTxdRXng4D8Xs=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=LEEl6J7IpFj0wM3Xj8Nppagc2UWeTGAuy91aTeA6b9B6KKzwi5b8xB//cD1ySQJmSXF5UL0VT8Y6Laj0xNJbpv3MmIep8qmIbC8U/JHIBUqIB2YZ6GTOu9MqA40BwZMQbDgzVPx2PAylZX07tr7CbjwfNzhGoUstdA+YTzIJfjE= 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=zRLl5Ymu; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=XsIAbKnK; 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="zRLl5Ymu"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="XsIAbKnK" Message-ID: <20241031154424.740750741@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389586; 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=BVfbQEbMeSQwFFsPTa1V2ybU7hlWaJTbzcbnkpGZLrk=; b=zRLl5YmuxBnONSv8EN01PnKFBINwI4twB3ICfLBsnV114qZEc9tuD/qvhOXVBcH9DR/7oL NcOowmsbb9eF78NmtPrhaA/0UhLfyuFK13Mkm6u30DRgbF+SV7pgadmjvryxqWKre98ANl nDdRiMZr93PJXbJEyyFBZ73Z0I2V9Rrmu5SpXsa3weJcX6B5m//r23Vik+jRpcZZSqDxuM tpRSd6PeUrMinGQF4NtI4WrSvFnJwy3KWaQZaBCnZ+kEMYOiDtXVsrhRYNIEp3zLCgzv+a 6EWLE/TWi+gExFUYpeW5atjwA+iJqftWPKvnCgDIap7BT0pqiQrtRsVToebS/g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389586; 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=BVfbQEbMeSQwFFsPTa1V2ybU7hlWaJTbzcbnkpGZLrk=; b=XsIAbKnKJ2nGvZV6yY+tJg+NL6J7zoVmPR1Bpj60jSYWOOmGUoz8LnpCww0HSQQ/8zZoqs Bxg961Ng8lZ+tdAw== 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 v6 03/20] posix-cpu-timers: Cleanup the firing logic References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:26 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The firing flag of a posix CPU timer is tristate: 0: when the timer is not about to deliver a signal 1: when the timer has expired, but the signal has not been delivered yet -1: when the timer was queued for signal delivery and a rearm operation raced against it and supressed the signal delivery. This is a pointless exercise as this can be simply expressed with a boolean. Only if set, the signal is delivered. This makes delete and rearm consistent with the rest of the posix timers. Convert firing to bool and fixup the usage sites accordingly and add comments why the timer cannot be dequeued right away. Signed-off-by: Thomas Gleixner Reviewed-by: Frederic Weisbecker --- V6: New patch after detecting the tristate mismatch vs. bool from the patch which introduced the nanosleep flag. --- include/linux/posix-timers.h | 2 +- kernel/time/posix-cpu-timers.c | 29 +++++++++++++++++++++-------- 2 files changed, 22 insertions(+), 9 deletions(-) --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -49,7 +49,7 @@ struct cpu_timer { struct timerqueue_head *head; struct pid *pid; struct list_head elist; - int firing; + bool firing; struct task_struct __rcu *handling; }; =20 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -494,6 +494,13 @@ static int posix_cpu_timer_del(struct k_ WARN_ON_ONCE(ctmr->head || timerqueue_node_queued(&ctmr->node)); } else { if (timer->it.cpu.firing) { + /* + * Prevent signal delivery. The timer cannot be dequeued + * because it is on the firing list which is not protected + * by sighand->lock. The delivery path is waiting for + * the timer lock. So go back, unlock and retry. + */ + timer->it.cpu.firing =3D false; ret =3D TIMER_RETRY; } else { disarm_timer(timer, p); @@ -668,7 +675,13 @@ static int posix_cpu_timer_set(struct k_ old_expires =3D cpu_timer_getexpires(ctmr); =20 if (unlikely(timer->it.cpu.firing)) { - timer->it.cpu.firing =3D -1; + /* + * Prevent signal delivery. The timer cannot be dequeued + * because it is on the firing list which is not protected + * by sighand->lock. The delivery path is waiting for + * the timer lock. So go back, unlock and retry. + */ + timer->it.cpu.firing =3D false; ret =3D TIMER_RETRY; } else { cpu_timer_dequeue(ctmr); @@ -809,7 +822,7 @@ static u64 collect_timerqueue(struct tim if (++i =3D=3D MAX_COLLECTED || now < expires) return expires; =20 - ctmr->firing =3D 1; + ctmr->firing =3D true; /* See posix_cpu_timer_wait_running() */ rcu_assign_pointer(ctmr->handling, current); cpu_timer_dequeue(ctmr); @@ -1364,7 +1377,7 @@ static void handle_posix_cpu_timers(stru * timer call will interfere. */ list_for_each_entry_safe(timer, next, &firing, it.cpu.elist) { - int cpu_firing; + bool cpu_firing; =20 /* * spin_lock() is sufficient here even independent of the @@ -1376,13 +1389,13 @@ static void handle_posix_cpu_timers(stru spin_lock(&timer->it_lock); list_del_init(&timer->it.cpu.elist); cpu_firing =3D timer->it.cpu.firing; - timer->it.cpu.firing =3D 0; + timer->it.cpu.firing =3D false; /* - * The firing flag is -1 if we collided with a reset - * of the timer, which already reported this - * almost-firing as an overrun. So don't generate an event. + * If the firing flag is cleared then this raced with a + * timer rearm/delete operation. So don't generate an + * event. */ - if (likely(cpu_firing >=3D 0)) + if (likely(cpu_firing)) cpu_timer_fire(timer); /* See posix_cpu_timer_wait_running() */ rcu_assign_pointer(timer->it.cpu.handling, NULL); From nobody Mon Nov 25 00:45:39 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 7ADD21A3BC8 for ; Thu, 31 Oct 2024 15:46:29 +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=1730389591; cv=none; b=VM3wdtQveFQOCrDbZaqM6BrZXWS0mj37B7oL86jayaEztEZ17soeEo8j/E5eZDJeH2ePdiAnBXLt7fUP7iStnt1xfy7D4GQf2zkaY8xgkE7tQC+UMLEmSpMe7TgKgfUZ6ucTghtcFO2KpXg6cda9kCrZvhsr1VRJ7tvzqRObycI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389591; c=relaxed/simple; bh=6QadadNKAM5qb4g5XADfumRJa53grKZV/xEszGMAJLc=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=rm/A3IH0gO09VX0hl/HLM1oUoR6Ivx99coEWCVL157ky6WhcIbT8rMrC38oHHzInO0wlzpjLZHWi2mM5m3h/1csU6hlsg4JZDBQFtQn49ayxvI0LjIpV9vaMVcbFZ4YaSAKdL0NdbSmNF6abC2u66b38z0MR5T2JhuX0IXqtliA= 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=IXCcTG2F; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=KTunwOIf; 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="IXCcTG2F"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="KTunwOIf" Message-ID: <20241031154424.804147685@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389588; 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=fk1ptLUC33Bw0wSzd0G6hpDiLiKMBhvHROCcbCZNqe0=; b=IXCcTG2FZizq+R5JTTbIBCUmYi1XC8qP6fcIV9YUr8aoUpIVp7q9vdegqREOdkGJHjWG5P pHwL5MkInnbs0OFaqfKlrAunlJoXRD+1amrRBfSBiC28ucCH+RxfxK97i4wvR/C5GB6zpq /tSH9fi9q/AXju8pJwnf2El7orpwXT9f1FGh1G8Z7xkyC+YVAau6krkeLBCE0C6ezl/po0 BGsNOkvWpDNEi1J6sMSnCH9fA/YJoZZraukLxCmkyIm87S9FysnzsaOCKJVL8Dzte2GdIz wYoQIXH9FZzivvi/5RtcKE6X03OFeiViJOq6tRay5T97JfAeLZTmdKlg97J0bA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389588; 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=fk1ptLUC33Bw0wSzd0G6hpDiLiKMBhvHROCcbCZNqe0=; b=KTunwOIf5+8pqRv+cv3fENyBMgOR8K3lzWEE6D2M1kRG/EVqs+cEK1aIvCO1NVHFMe6QnC 9fJ818t8BOh3ylDw== 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 v6 04/20] posix-cpu-timers: Use dedicated flag for CPU timer nanosleep References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:27 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 2 ++ kernel/time/posix-cpu-timers.c | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) --- --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -42,6 +42,7 @@ static inline int clockid_to_fd(const cl * @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 { @@ -50,6 +51,7 @@ struct cpu_timer { struct pid *pid; struct list_head elist; bool firing; + bool nanosleep; struct task_struct __rcu *handling; }; =20 --- a/kernel/time/posix-cpu-timers.c +++ b/kernel/time/posix-cpu-timers.c @@ -595,7 +595,7 @@ static void cpu_timer_fire(struct k_itim =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. @@ -1492,6 +1492,7 @@ static int do_cpu_nanosleep(const clocki 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 Mon Nov 25 00:45:39 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 1AB4E1A705B for ; Thu, 31 Oct 2024 15:46:30 +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=1730389593; cv=none; b=ir8sxukEiHlPZsJAZ2FGZbMZF+2m83SNXRROtTC2iolrte6cb/2h8XjTLaO36RLYozCVCHec4Fuw0zm2mhENNGQ8Myijj39vye5iQCB85sOwpjWsvH2EbochT1IVBnaxEWob2XCDD2XksqlCulKacU9NqSQbkd+HyHEVdwfnzMY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389593; c=relaxed/simple; bh=Nemrgu/YkY5r3VRndYM1Ns/N5tWy7kTgo331RhnJT6Q=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=lIZBDWvqiLSSzmkkYVMMxBagsPeTgkXS2DDLFlXEkR0caJJTaVOPhtsddVNVUxz8p/E2h1o1yFCiwSGx8oXH32qRgSJlTGCq16Lr+bt0pr/9dofgk8ttEPhHQsIMOoVQCxTkdHnoe9EhzvoadML2L8sNznOaeiieGoKGnP1xjak= 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=2gzUTyKN; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=/hpymbeV; 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="2gzUTyKN"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="/hpymbeV" Message-ID: <20241031154424.867133269@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389589; 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=tEeFEzPNCwUi0JRaFaQ+6R6rL1sCe1K+XB0ECNCbAZY=; b=2gzUTyKNZIUhQMFVB+ANPvo0etkCBNlEVUNG6BRRNs3uELn7LoevSu5MRkJkOdBQzKAu42 3Syt2+hk/NWiKxBOhzEAluOHzhDkwzbiUXEN7TZmhtMDf+FsQ1YmhPVW1Gqu60ru5tDbsq 9rZ8LKDRS8QHFZxmwMKd52dMaGqEtwsIpO5Bf34yF9TuCg/1/JZ/zk1aMApqb+EFQKCEwL aDaVtJaT1+6RpUcfils2TFTl11swb+nsrvI9K9/DGloF6j+evRG1oD2CgVUzUD3avp3xdz jqhSEwFZ6z63pNWYHWaaCTRs52Ks6Ivblmp4JnbJQO3GioO9gTWOgczDWo9F6w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389589; 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=tEeFEzPNCwUi0JRaFaQ+6R6rL1sCe1K+XB0ECNCbAZY=; b=/hpymbeVfN8KiKopaj3A/GydAiutDOCzNhn+jCkM6P/00wbQyjPKgxsLtTzkKPi0fl2/LG /YNKw5d6pYAp8eAA== 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 v6 05/20] posix-timers: Add a refcount to struct k_itimer References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:29 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 14 ++++++++++++++ kernel/time/posix-timers.c | 7 ++++--- 2 files changed, 18 insertions(+), 3 deletions(-) --- --- 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_wa =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 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_ * @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_s =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 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -417,10 +417,11 @@ static struct k_itimer * alloc_posix_tim return NULL; } clear_siginfo(&tmr->sigq->info); + rcuref_init(&tmr->rcuref, 1); return 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); @@ -432,7 +433,7 @@ static void posix_timer_unhash_and_free( 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) @@ -467,7 +468,7 @@ static int do_timer_create(clockid_t whi */ 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 Mon Nov 25 00:45:39 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 291131BB6BC for ; Thu, 31 Oct 2024 15:46:32 +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=1730389594; cv=none; b=uRiXJfTjOLq7+dfDYoCvagog3ll1JqVeQXjkdcnEgHD2wTDpzEkKqZ2sV4X/Kg/Ay1rOtTVhVCLapaKZHnDq4h0BqjNANedoME29Slescjeir0NZix4EdlRibn6bYb50493kYcnfS2DuDgtgvy3UKDQ3g/L92NpkV31i5YQts1I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389594; c=relaxed/simple; bh=RpPe8akei2X3DFyo/GviuhYgA/IaiJ9f1ZzIceIbO44=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=dqx5NN/MbXex8l3Hc7CwJr4QOm9T6d9LGNRDDpu9a3QK8ChSxvgc5/j+ELE9osFTU1nmtJ3w1PH18mY/ibGbgmeUGt0gtESWxwq4znnNaIZeDlpI59vWTA3sWsmZp7xUtsOTRu7flYvyWnbahy+lpr38o12ckW0My7oG+hCoiRk= 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=TD86oS8R; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=oyppJDHK; 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="TD86oS8R"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="oyppJDHK" Message-ID: <20241031154424.928822095@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389590; 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=lWQ3QAq9jnqUt7hBgMDxaHm03/0EIaipDycR2Op2VkE=; b=TD86oS8R1SKv29u0CWICDsPzzN7y4U3iRNCmhTxNjHgI1c7OM4wtY4tCFBkPFIuxM3T6T0 QgqMhv+gjDRNfq8ZZhocTYaxl0Rhq/HO35qhbwp0aVbo++FVL1q/qQB6eNdFdbTlWi2EMa 7M0PNLILNUFZ46uLluvmERBvV7U8za0P8qcIJSsuyMZxxQA/wBEaJgbACYfVf1mhOxfXz6 YzcsNhEdDHbTw2GqTai9NQfvo9zvSLO6xUKevqa65bj23Q6GPa9UXltiZ5ygFRSNcGlKXW OpBFQ3JfLX2DBm9X142xOrQEXze23ktefY0QtHpfSgsFKjMPqI83R9IGpyBR6A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389590; 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=lWQ3QAq9jnqUt7hBgMDxaHm03/0EIaipDycR2Op2VkE=; b=oyppJDHKozieTZTJwt2/H36jT+L+5Nyn823Imi6gXRgeuY+vjXhCRwHZulVjn7LZyxKkd9 OAb0m6pslfp/wIAQ== 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 v6 06/20] signal: Split up __sigqueue_alloc() References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:30 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Frederic Weisbecker 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 Mon Nov 25 00:45:39 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 6E0A91BBBF4 for ; Thu, 31 Oct 2024 15:46:33 +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=1730389595; cv=none; b=G+UCBiMm/8YUHfE3m3vyI708CRYQRlu056mJO8dgLawcJSNg7oRhNxQxllgTwBFOO64FsWeQ6JVK0CXjZozS71RMODU1uf1+Hcl33j0VEujtuvmhW7CHXFWHjLpJJho/nacjTMD4AKYQuua2m9+7KBaP0xBtjAcVfuBaMPgykWg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389595; c=relaxed/simple; bh=ZVAaQanLkDGCsroH9vcnsYuRVzlKEvfr6cRqTv9u2nQ=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=EI1GcidB3Id6RqO1c39+UAJ/njYHJkj8lzNAId23i7N1kjDY+H2iGR6M1JikmQBn21PRmvNAuMJuwOgzvOHDvhykjkXX07n1MhSq5FAfIrgU232cEcB7FI+S5FKslV8tSzKVZ+Ktm/G0lUjEV47uNnJiBz//lkvtbd92Mg17ipE= 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=bDMmKxE2; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=PSBmiHCn; 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="bDMmKxE2"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="PSBmiHCn" Message-ID: <20241031154424.991571969@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389591; 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=9/sheOM3O505WEl90eWHF3ugDs9kjENsFCU+PPXorJo=; b=bDMmKxE28OUqW7zAXH3vddKk/hJ1Ere04yzx2SNvb4O/pSaHeO7OIDXN4gSg3pQvI02ZgQ 0Y0RACNEorDy+2qCSNw5rgsE78UaOg5YixVVy4XBuxmAOlYD9YygOZADHz9HASzgSdeU+2 VIW3ui4eT2QQghj8x06xLWgQdl6AbDFlG3DTPVRBCIAT92EQm/SpXIm7PbsWxKOVdoxWyV t48JGvB1f7g+pwsxW4HreSgzFIOtiIOn2ydsX+lo9py/nvuMzGpkE9MVJY2lCIpxUN8gAU ANbeyTcoKN6AMpRW8op8R9urZzLK+DGIkEqYy64XXsxgxFJD3y9Vk7CZMuWxuw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389591; 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=9/sheOM3O505WEl90eWHF3ugDs9kjENsFCU+PPXorJo=; b=PSBmiHCnDOnKb+CQ8rTZzB3sFDVKMLAuO/GSoM4j3RTrrNXbITin1aPS8b4kykVu1OgB2x YgpznJISEcNteNBw== 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 v6 07/20] signal: Provide posixtimer_sigqueue_init() References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:31 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 2 ++ kernel/signal.c | 11 +++++++++++ 2 files changed, 13 insertions(+) --- --- 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_wa } =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 --- 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 Mon Nov 25 00:45:39 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 B0C241BCA0F for ; Thu, 31 Oct 2024 15:46:34 +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=1730389597; cv=none; b=hLW0eGHgdZYJ7kwMJyzXWtICqEJ7RiBmWbyITuirn1HIwJVV06IzmPRInj8t+N1WKQb67B4RPInQva/zGDW3k+NhjoFOUPN67Eet78AwwxfQORx/YDuQjtyZGGLaQbT62quboLt550hfOs+BfujDk0DqbzJWLc4VBolmfv0LYzI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389597; c=relaxed/simple; bh=kiTXtVgw+U1qnp5FhuoXzBaBFn74/QO2mlup5NmMvn0=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=GqVhjhZnRzySTWQgpQnsP0wimBmy6Kw6709LgzWljTIdCfDxtkQLyU729OZz2dMieG4U7SRyU2ioscxWZJKCqVFotyJxy8f+i98Qv6ah6K/1dMaPy6P7vlrQmHNXQc3C57MuWPYVREwXwwiWvUjEee0DTDtws277bjYwbFJkM+4= 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=ODTkCO9l; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=iRxjzT77; 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="ODTkCO9l"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="iRxjzT77" Message-ID: <20241031154425.055076296@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389593; 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=gXCAblQOBPavs913jzKws+IyhhY6pcRYmrxp+julPVw=; b=ODTkCO9lbiF7YyXL4WclDog76nRQbAr8BC2mFv0rOWH3m86P3iSEzH4qOrav4j40pEy+Lu IJIMUscEczIA2uCZzzwhiC+BFbpcgKOK7HEBL3hra2l7dVxfdiDs0s0G51e6IxjufAWGtJ XOOy8IxXUWNhLPYWpB5ajstTD89MA9iU0by3S17VD+I03h8aFhJKgHSue4e7jXNJWnfU4Y PHtOZwXN2sU5qdjjcGJIFAFZ1900EuGlyuAdwtu7QFfWvFBJLbiOMH1uABAGpFJDi9PXF3 E5HmpF6UVJ0c6if7q+ryeGwwyZc2lIDI8ZMYEKa9We102QEOOPl4aMolgL4Kiw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389593; 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=gXCAblQOBPavs913jzKws+IyhhY6pcRYmrxp+julPVw=; b=iRxjzT778+AmaiL1UV3Z5ssMfRyuclXzmGLoixS4WpmarFBzC/yhpmBkBZfY59xp/X8Y6L BH+Yj9KS1BV4adAg== 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 v6 08/20] posix-timers: Store PID type in the timer References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:32 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" instead of re-evaluating the signal delivery mode everywhere. Signed-off-by: Thomas Gleixner Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 2 ++ kernel/time/posix-timers.c | 9 ++++++--- 2 files changed, 8 insertions(+), 3 deletions(-) --- --- 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 { --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -298,7 +298,6 @@ bool posixtimer_deliver_signal(struct ke 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); @@ -308,8 +307,7 @@ int posix_timer_queue_signal(struct k_it =20 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; } @@ -496,6 +494,11 @@ static int do_timer_create(clockid_t whi 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; From nobody Mon Nov 25 00:45:39 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 5E0DC1BD515 for ; Thu, 31 Oct 2024 15:46:36 +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=1730389599; cv=none; b=D3XeqcAc5qbd1KuvOdngmTa3STIw6edpDSIoVmtWUOMKcJd4PwTuKg6yHsIoChAlKnK517EL85IZ9ttnJPhxH0YGo5A3A1eL7xNiYP6qzcugi7lDoXGs+d4aG/JK7+9XyXWQmlBgDJv/PQQnhjYScGg06GZvrBbpyFRUHZlTcAo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389599; c=relaxed/simple; bh=CexgufO+1Osh5TMOL66HRJxKyFDyiRssUXwnxU9QZ7A=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=MJlEE96/946HhJQkaDNpQY6IPNeMXXS4YwMCdzQCl0TKmUACIjR+AAbs/ihUiyKruSTnVTh8CEpP1TWh0/yMMvJeY3V1E5tlchipf/x6X7h2wQkl9YfpGhgLaDzvRe194Z0F+SnMkjcdnMw+IBiAkALb7OQ1guD0Z0s7ltjd22k= 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=GRxH1ijY; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=o9QnRikO; 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="GRxH1ijY"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="o9QnRikO" Message-ID: <20241031154425.119202459@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389594; 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=ChIynh12PYnBXnJ3TWILE4o90Tsj+76TEesTqrWpYsU=; b=GRxH1ijYp8N1NtIJU+yFpPeI7GWAjrUJ/LA6m0sanotdE1tectOHaWYmyD2HAySlmZtvUl 7BjxXP3C/aillEvm7WYZoYVM8gVde2S8IeF1IJzNV+OE/bi8hKjVHHPhtEg3T0a0z1lsXA hi0+clRIbKWF0tzF8liNuxvuY+kIBK4lv+kDACyQ1/nBj3GvZzu422CnHdM5DrF0sRi2m8 n3JIegp7bYiiLWhyC8KQnZUD3ZEAjBy6BHFyLj/yAurUbNwWy9A801FP3M0Afg9gCJDauM osp5efm9U6m28PFgUO1bpiQqLA6FkGg5Gva6Ja9I3sj935QwdxyltLpYbr/85Q== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389594; 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=ChIynh12PYnBXnJ3TWILE4o90Tsj+76TEesTqrWpYsU=; b=o9QnRikOMkaxkTGjXEaAzzFFmGXW/0IpSuGeLe9T3n/DPcucqwc+fjSpQdLOFPDFTnVWxQ FyOUe2EkZpFeLDAw== 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 v6 09/20] signal: Refactor send_sigqueue() References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:34 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) --- include/linux/posix-timers.h | 1=20 include/linux/sched/signal.h | 1=20 kernel/signal.c | 82 +++++++++++++++++++++++---------------= ----- kernel/time/posix-timers.c | 2 - 4 files changed, 47 insertions(+), 39 deletions(-) --- --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -109,6 +109,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); bool posixtimer_deliver_signal(struct kernel_siginfo *info); void posixtimer_free_timer(struct k_itimer *timer); =20 --- a/include/linux/sched/signal.h +++ b/include/linux/sched/signal.h @@ -340,7 +340,6 @@ extern int send_sig(int, struct task_str 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) --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1947,40 +1947,54 @@ 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; + guard(rcu)(); =20 - ret =3D -1; - rcu_read_lock(); - - /* - * 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; + return -1; + if (!likely(lock_task_sighand(t, &flags))) - goto ret; + return -1; =20 /* * Update @q::info::si_sys_private for posix timer signals with @@ -1988,30 +2002,24 @@ int send_sigqueue(struct sigqueue *q, st * 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 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(); return ret; } #endif /* CONFIG_POSIX_TIMERS */ --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -307,7 +307,7 @@ int posix_timer_queue_signal(struct k_it =20 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 Mon Nov 25 00:45:39 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 E0BD61BDA9B for ; Thu, 31 Oct 2024 15:46:36 +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=1730389599; cv=none; b=s2sCQdSvBAsGLxdQ6FXEPID06zI1BKhHerYkATxRGzxtKlomf9hh1sZfxB5OmO7FXs5cTVlVskhDI6cJhg6tvN0Nfe7pQOuKmj3aSs/mUSKiwT0N2/Y3vqWd5Pane6oTH8K/aOXmS2vBo6ZTzj86lfg0WkRBX3p/tCtgtV/Fvvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389599; c=relaxed/simple; bh=W9vkcg3goHw3toa/NPatBgcGiFKl03A2/EGpx0AvsdE=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=RFwWH3wUZXN1Z+xy7WlAM3eGPug5tAkxju4meL2fYFQgjBMa1is7qXYxGYpWd2m9kKQOvMpkXUnH4pMwrdSMnD/URsBFjDjW/ZqpLcb1aibMYrLkDHrEItKxzQlb7ikzPI1k+4HhCEmWLatPBQIEPhEiF30iPsK0cENva1kGZeA= 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=nKhDVGre; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=SPJWRAbv; 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="nKhDVGre"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="SPJWRAbv" Message-ID: <20241031154425.182629074@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389595; 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=I2JKYlpS9EROm2PXQHeSksdbFrfFm6VApPBBZM9ycE4=; b=nKhDVGreMefqEU/ghR9JuGellFhk+cHje4Q2CTYAtmlhb3tQo689wfjKWL0nd5MKgygK2V CQ4DFKP/7cyr7WW9bih4YUIoHOAdNPqoKsxR4BPvpmnGgukMrH93AprLZEyzhz5TJFguhn yC7wAVuMG/+mZIufqGtHb6WBC2VNx7TF0e5j0wr8r4944RAnpy2NAy0q55ORnF72bt3MLP o88xM/DnC1T8ACTijCogiQysUE5xC3cSCo8Tjq9TLm2zBGswoY7HI7qIePH2EDbkhER3t7 QyAeTwrTUNgd/i2eKhC0Z5d/iqvRWy4vAwDp8Hs6bN/PHSvZjlnclMNkLqHK8g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389595; 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=I2JKYlpS9EROm2PXQHeSksdbFrfFm6VApPBBZM9ycE4=; b=SPJWRAbvjNxaZNeRvMUKFxQj80GpjFr6+4bkZ82NY6Xh32w+D+4+9+/c3W9KtEAbyi9Oxt NU1Y1JY0/uR0RhDg== 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 v6 10/20] signal: Replace resched_timer logic References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:35 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner In preparation for handling ignored posix timer signals correctly and embedding the sigqueue struct into struct k_itimer, hand down a pointer to the sigqueue struct into posix_timer_deliver_signal() instead of just having a boolean flag. No functional change. Suggested-by: Eric W. Biederman Signed-off-by: Thomas Gleixner Acked-by: "Eric W. Biederman" Reviewed-by: Frederic Weisbecker --- V6: NULLify timer_sigq after again: in dequeue_signal() - Frederic V5: New patch --- include/linux/posix-timers.h | 5 +++-- kernel/signal.c | 32 ++++++++++++++++++++------------ kernel/time/posix-timers.c | 2 +- 3 files changed, 24 insertions(+), 15 deletions(-) --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -110,7 +110,7 @@ static inline void posix_cputimers_rt_wa 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); +bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueu= e *timer_sigq); void posixtimer_free_timer(struct k_itimer *timer); =20 /* Init task static initializer */ @@ -135,7 +135,8 @@ static inline void posix_cputimers_init( 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 bool posixtimer_deliver_signal(struct kernel_siginfo *info) = { return false; } +static inline bool posixtimer_deliver_signal(struct kernel_siginfo *info, + struct sigqueue *timer_sigq) { return false; } static inline void posixtimer_free_timer(struct k_itimer *timer) { } #endif =20 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -545,7 +545,7 @@ bool unhandled_signal(struct task_struct } =20 static void collect_signal(int sig, struct sigpending *list, kernel_siginf= o_t *info, - bool *resched_timer) + struct sigqueue **timer_sigq) { struct sigqueue *q, *first =3D NULL; =20 @@ -568,10 +568,17 @@ static void collect_signal(int sig, stru list_del_init(&first->list); copy_siginfo(info, &first->info); =20 - *resched_timer =3D (first->flags & SIGQUEUE_PREALLOC) && - (info->si_code =3D=3D SI_TIMER); - - __sigqueue_free(first); + /* + * posix-timer signals are preallocated and freed when the + * timer goes away. Either directly or by clearing + * SIGQUEUE_PREALLOC so that the next delivery will free + * them. Spare the extra round through __sigqueue_free() + * which is ignoring preallocated signals. + */ + if (unlikely((first->flags & SIGQUEUE_PREALLOC) && (info->si_code =3D=3D= SI_TIMER))) + *timer_sigq =3D first; + else + __sigqueue_free(first); } else { /* * Ok, it wasn't in the queue. This must be @@ -588,12 +595,12 @@ static void collect_signal(int sig, stru } =20 static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, - kernel_siginfo_t *info, bool *resched_timer) + kernel_siginfo_t *info, struct sigqueue **timer_sigq) { int sig =3D next_signal(pending, mask); =20 if (sig) - collect_signal(sig, pending, info, resched_timer); + collect_signal(sig, pending, info, timer_sigq); return sig; } =20 @@ -605,18 +612,19 @@ static int __dequeue_signal(struct sigpe 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; + struct sigqueue *timer_sigq; int signr; =20 lockdep_assert_held(&tsk->sighand->siglock); =20 again: *type =3D PIDTYPE_PID; - signr =3D __dequeue_signal(&tsk->pending, mask, info, &resched_timer); + timer_sigq =3D NULL; + signr =3D __dequeue_signal(&tsk->pending, mask, info, &timer_sigq); if (!signr) { *type =3D PIDTYPE_TGID; signr =3D __dequeue_signal(&tsk->signal->shared_pending, - mask, info, &resched_timer); + mask, info, &timer_sigq); =20 if (unlikely(signr =3D=3D SIGALRM)) posixtimer_rearm_itimer(tsk); @@ -642,8 +650,8 @@ int dequeue_signal(sigset_t *mask, kerne current->jobctl |=3D JOBCTL_STOP_DEQUEUED; } =20 - if (IS_ENABLED(CONFIG_POSIX_TIMERS) && unlikely(resched_timer)) { - if (!posixtimer_deliver_signal(info)) + if (IS_ENABLED(CONFIG_POSIX_TIMERS) && unlikely(timer_sigq)) { + if (!posixtimer_deliver_signal(info, timer_sigq)) goto again; } =20 --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -254,7 +254,7 @@ static void common_hrtimer_rearm(struct * 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) +bool posixtimer_deliver_signal(struct kernel_siginfo *info, struct sigqueu= e *timer_sigq) { struct k_itimer *timr; unsigned long flags; From nobody Mon Nov 25 00:45:39 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 5DA4D1C1AB3 for ; Thu, 31 Oct 2024 15:46:38 +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=1730389602; cv=none; b=APXMs9zDQE7HDr1rjL5A4ekkcIbUFz7qtoI1dMeIgcVYO3gPUgyyhSLjtGMLdqu5Z1lIF5SknuMRqOn8S3/wCHVw79MQ0939JfNNoyYsbzyPRBgMVk+EINli5AWB0SRJ7yZG26FkoEGaEKUoZqgAi5R+POLJrUkND+wlBcpt6IE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389602; c=relaxed/simple; bh=enQyLOaHXZPmgh1pbWtFfEdPlnrVUAoE3+VZxJY+E64=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=GCSf/gpc6z4zkD/hQ4ZVxCfHxtJ/L25q9Y25+pS1xJ1CC4bTbj/LsCeGr+/IjgYtMnuo9bXvsF5+IkTFz/8GsN9d87tZ0S3jgBrzpX8wwlruyGuicb7VE909OBGJ6Yz9tO9r1Hb+zTsWWm1uBiDU/SvL2tPxEDu9ddFET4HjItU= 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=ePiAFA97; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=hgv3WtXT; 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="ePiAFA97"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="hgv3WtXT" Message-ID: <20241031154425.245095838@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389596; 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=Yyy8Ki41ZJBE+KVosF2Hc7+f2cRyz+UaB/PHCswwRHs=; b=ePiAFA97tcQ0fpK//4Xe7OR/IKl9PbpT5/qa3W3w2WddamxDl3b8+wCKe4NGukfYOhKHoY evyI5qVbnc3hGoozwuexPN2g6DCJuy/ITE+EG3SRQdsrYU+ymJg4aGZNOvGIxgElHeFzmU 42FcpwzJEEvuiFQaqWDiTELHjRDDEplr/yvKVAaw7JfTnNlFHU1rVU03bruGOkiKUA19Om 4TI8zFHbWJxKdqZLjIgwOq1R69bR9hC80xHAZ0V/d3Y6HNJb/i1RoPmuaM+tYkjVkFTnXk MbPAkMc9/VjF+JApqBbgGmDaRTtKwRq4f1VH6dJF2WzAKqLnCT8RuPevINaqzQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389596; 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=Yyy8Ki41ZJBE+KVosF2Hc7+f2cRyz+UaB/PHCswwRHs=; b=hgv3WtXTsoA7D6zvpTmAU+8cfSc4FMa08p67ckNqLFzDqKoyiqwzVaQm/L5dxTVQWGq2E/ F5GphGwkZ5wY2IAw== 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 v6 11/20] posix-timers: Embed sigqueue in struct k_itimer References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:36 +0100 (CET) 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 Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) --- V6: Split out the timer related part from the delivery function to use guard() and avoid gotos --- fs/proc/base.c | 4 - include/linux/posix-timers.h | 23 ++++++++++- kernel/signal.c | 19 +++++---- kernel/time/posix-timers.c | 88 +++++++++++++++++++++++++-------------= ----- 4 files changed, 87 insertions(+), 47 deletions(-) --- --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2553,8 +2553,8 @@ static int show_timer(struct seq_file *m =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", --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -39,6 +39,8 @@ static inline int clockid_to_fd(const cl =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 @@ -166,7 +168,7 @@ static inline void posix_cputimers_init_ * @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. @@ -190,7 +192,7 @@ struct k_itimer { struct pid *it_pid; struct task_struct *it_process; }; - struct sigqueue *sigq; + struct sigqueue sigq; rcuref_t rcuref; union { struct { @@ -218,6 +220,23 @@ static inline void posixtimer_putref(str 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 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -460,8 +460,10 @@ static struct sigqueue *__sigqueue_alloc =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; @@ -569,11 +571,11 @@ static void collect_signal(int sig, stru copy_siginfo(info, &first->info); =20 /* - * posix-timer signals are preallocated and freed when the - * timer goes away. Either directly or by clearing - * SIGQUEUE_PREALLOC so that the next delivery will free - * them. Spare the extra round through __sigqueue_free() - * which is ignoring preallocated signals. + * posix-timer signals are preallocated and freed when the last + * reference count is dropped in posixtimer_deliver_signal() or + * immediately on timer deletion when the signal is not pending. + * Spare the extra round through __sigqueue_free() which is + * ignoring preallocated signals. */ if (unlikely((first->flags & SIGQUEUE_PREALLOC) && (info->si_code =3D=3D= SI_TIMER))) *timer_sigq =3D first; @@ -1989,7 +1991,7 @@ static inline struct task_struct *posixt =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; @@ -2020,9 +2022,12 @@ int posixtimer_send_sigqueue(struct k_it =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: --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -250,15 +250,40 @@ static void common_hrtimer_rearm(struct hrtimer_restart(timer); } =20 +static bool __posixtimer_deliver_signal(struct kernel_siginfo *info, struc= t k_itimer *timr) +{ + guard(spinlock)(&timr->it_lock); + + /* + * 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_seq !=3D info->si_sys_private || WARN_ON_ONCE(!timr->= it_signal)) + return false; + + if (!timr->it_interval || WARN_ON_ONCE(timr->it_status !=3D POSIX_TIMER_R= EQUEUE_PENDING)) + return true; + + timr->kclock->timer_rearm(timr); + timr->it_status =3D POSIX_TIMER_ARMED; + timr->it_overrun_last =3D timr->it_overrun; + timr->it_overrun =3D -1LL; + ++timr->it_signal_seq; + info->si_overrun =3D timer_overrun_to_int(timr); + return true; +} + /* * 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 sigqueu= e *timer_sigq) { - struct k_itimer *timr; - unsigned long flags; - bool ret =3D false; + struct k_itimer *timr =3D container_of(timer_sigq, struct k_itimer, sigq); + bool ret; =20 /* * Release siglock to ensure proper locking order versus @@ -266,28 +291,11 @@ bool posixtimer_deliver_signal(struct ke */ spin_unlock(¤t->sighand->siglock); =20 - timr =3D lock_timer(info->si_tid, &flags); - if (!timr) - goto out; - - if (timr->it_signal_seq !=3D info->si_sys_private) - goto out_unlock; - - if (timr->it_interval && !WARN_ON_ONCE(timr->it_status !=3D POSIX_TIMER_R= EQUEUE_PENDING)) { - timr->kclock->timer_rearm(timr); + ret =3D __posixtimer_deliver_signal(info, timr); =20 - timr->it_status =3D POSIX_TIMER_ARMED; - timr->it_overrun_last =3D timr->it_overrun; - timr->it_overrun =3D -1LL; - ++timr->it_signal_seq; - - info->si_overrun =3D timer_overrun_to_int(timr); - } - ret =3D true; + /* Drop the reference which was acquired when the signal was queued */ + posixtimer_putref(timr); =20 -out_unlock: - unlock_timer(timr, flags); -out: spin_lock(¤t->sighand->siglock); =20 /* Don't expose the si_sys_private value to userspace */ @@ -404,17 +412,17 @@ static struct pid *good_sigevent(sigeven } } =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; } @@ -422,7 +430,8 @@ static struct k_itimer * alloc_posix_tim 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); kfree_rcu(tmr, rcu); } =20 @@ -484,13 +493,13 @@ static int do_timer_create(clockid_t whi 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 @@ -499,8 +508,8 @@ static int do_timer_create(clockid_t whi 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_tid =3D new_timer->it_id; + new_timer->sigq.info.si_code =3D SI_TIMER; =20 if (copy_to_user(created_timer_id, &new_timer_id, sizeof (new_timer_id)))= { error =3D -EFAULT; @@ -584,7 +593,14 @@ static struct k_itimer *__lock_timer(tim * 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 Mon Nov 25 00:45:39 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 9EEBB13AD32 for ; Thu, 31 Oct 2024 15:46:39 +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=1730389602; cv=none; b=NDSRvc/mYCqxSFUVuOq3htwjVOwOvoFXsm3xfctynpLBj42AnYVvOs4j8BA2emcTlGIcoDQ9cmzJve4/DGEIDW1LzH6rhozr7CZhF23prnlfR+rUDPgTR88rHZmk9TseO3AhruRcOqDa+aaILxiIZ42rrYtOZb9IFmZLJt9EVVw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389602; c=relaxed/simple; bh=uF8HVjyRfSfPENjUQUuN0lAxWCzSjUVmwDegLBJY1Hk=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=u3oDFa1LYWjZjh0CWtNa5R6V4YCls1RNntdBuVxQEsO1pivKwOoriFx7qIF03oJBnRaLjjXl7cAEf2ix8jhgbQacqupUYKqSFxCu2C/nOjvG7Wp+AvYAhMH2ga41srmPeqifDhyjYk+XLbjqGLDcGbYIsGvq7CMe8mVxMt6a2vc= 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=uLvvfyDh; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=zwvP9gqs; 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="uLvvfyDh"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="zwvP9gqs" Message-ID: <20241031154425.307607463@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389597; 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=QHJKT1FsG81uCFjqfXOJNacFFtoodXXL7f6S1umCJys=; b=uLvvfyDhzUvFWhf6x5s2JBlfOGZhs7lnH3IA5H8BGzAIXpC1VQeqFgFcFl0Z3A/3XIUoHG WGz3huXX5q6zQn62isQ7eNF7anrnHEIPFU7dQabkysTghv87hLEF4acroxwafqwaFcfxWz UfyhpEQsU2xJea+dGX7ybTYIvFDpq7HAGQ/Hbhxqe5iDOV0K/J2omhWFItrXWT32+LkLfA uygXKAZaOb7iMiCp00FQrSrDJFXcvCE6SbvwZVrm3+kU7hsxI8AvYEw65TlpmC+XSKgokD H4iAxwJHtPtZdiEE3mFndqMoC9Gu5r88w8G2rOkMsL7EO8C8MhGw/v19bVZDLA== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389597; 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=QHJKT1FsG81uCFjqfXOJNacFFtoodXXL7f6S1umCJys=; b=zwvP9gqsv21abafODULvw2191FcpHLB/SZsxFfKwst22zoJMM8h4DW0KgTtNvUIpr74+jr fMB/aNwynqv/AqAw== 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 v6 12/20] signal: Cleanup unused posix-timer leftovers References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:37 +0100 (CET) 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 Reviewed-by: Frederic Weisbecker Acked-by: Peter Zijlstra (Intel) --- include/linux/sched/signal.h | 2 -- kernel/signal.c | 39 ++++----------------------------------- 2 files changed, 4 insertions(+), 37 deletions(-) --- --- 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) --- a/kernel/signal.c +++ b/kernel/signal.c @@ -439,8 +439,8 @@ static void __sigqueue_init(struct sigqu * - 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,7 +454,7 @@ static struct sigqueue *__sigqueue_alloc return NULL; } =20 - __sigqueue_init(q, ucounts, sigqueue_flags); + __sigqueue_init(q, ucounts, 0); return q; } =20 @@ -1070,7 +1070,7 @@ static int __send_signal_locked(int sig, 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); @@ -1926,37 +1926,6 @@ bool posixtimer_init_sigqueue(struct sig 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 Mon Nov 25 00:45:39 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 D509F1C3F2B for ; Thu, 31 Oct 2024 15:46:40 +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=1730389604; cv=none; b=S4jA0NGs9+7w/Gn84l0Ac35XqkElJ+VM3jREu1c0WNdTQ0WRJwv66YFsZn28YpEDzm08rsvifb4DJM3a/KUpk3oCZx9bnsJWjfYL4WIrHn0yghDLxyy/JISBJEvjyLsd17+LW3ego+Gst0nY2C70pbGhDmHeqdFwcSWoX6WGYw0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389604; c=relaxed/simple; bh=ubluM7VL7U4qZdDlhPmrWete8fA4Qc5SDItcL0E4eTI=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=db00x4BqVppWELPW0grdz+OB99MwTx6aUIy4t3bbnuMpvlGRGGw2qAy7XNb+1yLlpf/U+xv4u1HKZjw5jolyIlWITe9TYUYHHItpkEJkaahubBrnKtavbqMre9gm6AAH/kz3zYZxcOGxcj1sSabnHTwE+sCjszJ7QIAtXo+DQMM= 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=eKnH5ZhL; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=V2D3JIx0; 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="eKnH5ZhL"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="V2D3JIx0" Message-ID: <20241031154425.370529748@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389599; 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=o1ks1lD5Wsww0i59mhgG4iV/2G0j+TRp1u5nKEoD0lo=; b=eKnH5ZhLiOZa4FJ5oN0MWay//wmEtk9FlgQW3prk0oEdlDlYIYe/vrNwxSZTiC8PNl6br+ x5A3DcGx9W8VMXVq1wgCOBf3GgAuOcbrZO/7Z6lDOkR+AfKrCxVFPgFfu6LQdtdQUzvp7e SLf3HEBSu0DbPoZSL6aUeQFWHTC4dASVhB/R5WtP6JXxMsqdeKWPZreP7XLVbLGs25Rpn4 JznvQf5mSFynd5BJUQgNnE/AZI/r4Vtz6Q7OuhTFAFiy9ysC2iL3TWmaDIeZIZJPYKsIbC Kcy7x7LTwSu6JkFS9jw6vpLCZHJ8ca72Vvk96HIXQdKpBjUBJnPrxDqkGUWWRg== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389599; 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=o1ks1lD5Wsww0i59mhgG4iV/2G0j+TRp1u5nKEoD0lo=; b=V2D3JIx0awQzBgQK/54BEAEzkpivtMgXdfSmR1efs+OULL6raELbdvAEjR192u+RoMl8bE EDSZ/l7rIxcwikCA== 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 v6 13/20] posix-timers: Move sequence logic into struct k_itimer References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:38 +0100 (CET) Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Thomas Gleixner The posix timer signal handling uses siginfo::si_sys_private for handling the sequence counter check. That indirection is not longer required and the sequence count value at signal queueing time can be stored in struct k_itimer itself. This removes the requirement of treating siginfo::si_sys_private special as it's now always zero as the kernel does not touch it anymore. Suggested-by: Eric W. Biederman Signed-off-by: Thomas Gleixner Reviewed-by: Frederic Weisbecker Acked-by: "Eric W. Biederman" --- V6: Update the comment in siginfo.h V5: New patch --- include/linux/posix-timers.h | 2 ++ include/uapi/asm-generic/siginfo.h | 2 +- kernel/signal.c | 8 +++----- kernel/time/posix-timers.c | 5 +---- 4 files changed, 7 insertions(+), 10 deletions(-) --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -162,6 +162,7 @@ static inline void posix_cputimers_init_ * @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 + * @it_sigqueue_seq: The sequence count at the point where the signal was = queued * @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 @@ -184,6 +185,7 @@ struct k_itimer { s64 it_overrun; s64 it_overrun_last; unsigned int it_signal_seq; + unsigned int it_sigqueue_seq; int it_sigev_notify; enum pid_type it_pid_type; ktime_t it_interval; --- a/include/uapi/asm-generic/siginfo.h +++ b/include/uapi/asm-generic/siginfo.h @@ -46,7 +46,7 @@ union __sifields { __kernel_timer_t _tid; /* timer id */ int _overrun; /* overrun count */ sigval_t _sigval; /* same as below */ - int _sys_private; /* not to be passed to user */ + int _sys_private; /* Not used by the kernel. Historic leftover. Al= ways 0. */ } _timer; =20 /* POSIX.1b signals */ --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1976,12 +1976,10 @@ int posixtimer_send_sigqueue(struct k_it return -1; =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. + * Update @tmr::sigqueue_seq for posix timer signals with sighand + * locked to prevent a race against dequeue_signal(). */ - q->info.si_sys_private =3D tmr->it_signal_seq; + tmr->it_sigqueue_seq =3D tmr->it_signal_seq; =20 ret =3D 1; /* the signal is ignored */ if (!prepare_signal(sig, t, false)) { --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -259,7 +259,7 @@ static bool __posixtimer_deliver_signal( * since the signal was queued. In either case, don't rearm and * drop the signal. */ - if (timr->it_signal_seq !=3D info->si_sys_private || WARN_ON_ONCE(!timr->= it_signal)) + if (timr->it_signal_seq !=3D timr->it_sigqueue_seq || WARN_ON_ONCE(!timr-= >it_signal)) return false; =20 if (!timr->it_interval || WARN_ON_ONCE(timr->it_status !=3D POSIX_TIMER_R= EQUEUE_PENDING)) @@ -297,9 +297,6 @@ bool posixtimer_deliver_signal(struct ke posixtimer_putref(timr); =20 spin_lock(¤t->sighand->siglock); - - /* Don't expose the si_sys_private value to userspace */ - info->si_sys_private =3D 0; return ret; } From nobody Mon Nov 25 00:45:39 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 454AC1C4614 for ; Thu, 31 Oct 2024 15:46:42 +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=1730389604; cv=none; b=C8xuJZuOE+17a/PqtzXNVgYRn00N/arjozffQqA/7QYPPKeATCGIzRwN//ndq2tGvUAFsIKqzV19WGqLHQyIneLAkGm4+eHrQxE092cr/OEnXayWA8ytQ87Q3SNxt+xwb4mOQH1cYmR+FqSTaSQF9g/BXVcXMwdTAfMs0IdJiGY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389604; c=relaxed/simple; bh=+lUP6TsMuqE3IqXpPLjwkfLL0Lw7iNcYZDOIOAM353A=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=JcCWKY8LbVZatd9DDkMBMZRYmOvz/qDblQn5gQGCX2MPyJB1P34cTzrXK6t3KprVbLgiZaf+6+a+Lkc1HjxyyQJy5VUKOle6OWl6kaRhtvoVPI9a4JCLSaT1VOcSrqmg11YMrb6lWV9G6oqG5ApjWGwwPOAMxVdUqkWCDibNNu0= 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=PuTMj1Qo; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=wtWsVJKg; 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="PuTMj1Qo"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="wtWsVJKg" Message-ID: <20241031154425.434594109@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389600; 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=P5v7WakqlAk2QTAVxuUtUxQppzdrdxi6ddqN05QxfAw=; b=PuTMj1QoRVig3O0FI9gIf2kODufkruex1LJ/IUI79/O7QUp8Ue4i7U25XVn/rfTsmLHrf8 QN9kHTDPcxXbzCSN52JpS+DihbW5E8dareLMxDgwvYtmEN11JEtfg5nxkrOEjFxAHKlYee yRRCBuDRO2xd9W+qzFLkhY9kfXczIzt82ZodC7u05IMpNcMWecJN0TE6q0pyF8f45xn0s5 c/T7Y9BGJ80o6db9i+EGQP+Frf8Gj3+v5FUeWDe4Dgs+33bAQoCJjEbIG0k49MSiQjrHrr tIY/n9BbutG6f+DHRjzx5VE4xu3UF90gOj3UCPzI0f0McinEsyzMM+uRC2hu8A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389600; 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=P5v7WakqlAk2QTAVxuUtUxQppzdrdxi6ddqN05QxfAw=; b=wtWsVJKgNdA3eHPh95+gsbFzzFux/Xhm1U/x7F4MxmXNheXeIaFrmrGAtvs4YMlDCP7CPV Bra+sHsybZi6CKAg== 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 v6 14/20] signal: Provide ignored_posix_timers list References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:40 +0100 (CET) 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 Reviewed-by: Frederic Weisbecker 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(-) --- --- 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; --- a/init/init_task.c +++ b/init/init_task.c @@ -30,8 +30,9 @@ static struct signal_struct init_signals .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 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -1864,6 +1864,7 @@ static int copy_signal(unsigned long clo =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 Mon Nov 25 00:45:39 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 0BA5F1C7B62 for ; Thu, 31 Oct 2024 15:46:43 +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=1730389605; cv=none; b=RcyCt0AqCELCx1UmP+K7b1RqI+a77LNFRyoWHZhtuxnYLbALshih3xfCl/zuLbGx3mHJgFvw+iLIZlFRhJRb7TN3+Nowme9dQTCfOLcPgmlxMTuyjIXR2mO673RdH1R05Xis4NGLIEkXqz0L36ETCG9PrBoLQoHLATgSCcH8s3M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389605; c=relaxed/simple; bh=a7KcfJ0H5yG9o+hAQ68pX3T59R0HehkYopkBoSQyZYE=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=BNLDjTVVTYuSNgvqgKjW63JDaiYsWe+V0qFmJJyIqqr/tp6BWac+T+bBVmFk3giAIc4Hjl8xaBvfkVMD9Dv4wJB+7VRK1jOLns2qnhpy9/Akv6Owai7lOukTZGlQCJ+oHUE8WJN+dCzS3+nFiYFYYJrF+T7hRmurNVroBNCNxs8= 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=kvjsj344; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=oZRZznzC; 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="kvjsj344"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="oZRZznzC" Message-ID: <20241031154425.498474639@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389601; 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=RrNJyRQje7EybxKIECKyVfE3lGKZ40kOBzWpZXbTjgk=; b=kvjsj344D0SMtaztvIFUP9tSaiq2UKdQobo6n9JWHKIeVi+fR/F9iHeCF4DgZXPG4c/LKP lrV4KWafXAiRWllX1btSbCBxXc2Whzb8aP1rI4uKb2smBRU33xNihFMhnOBQ21Gz4/9cOQ 2GVX4j1gKEpXcizqZXCjscdHbwWqE6lyITM9iDGqAkpMD2pLMosy6k/Sb6gxu+zzAJDcUn Z+rSfwVE81IRfrizgdd8mCz03rns2RJ5ygZDkQNDwxFNxrE9AZxV6Vr8/QKmV7kXXCh99a oTLpxAo2lzJZcyKESAmPxR8pRmNS0lnuhwO+cK0FQyMKH/raDvC3iKHqY5C+Aw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389601; 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=RrNJyRQje7EybxKIECKyVfE3lGKZ40kOBzWpZXbTjgk=; b=oZRZznzCLA38TqeNegvLYHRYeMDO552GTQFKUokJhhuMHNLt6NG3yJDSANRvn/ytHyUDDM wEVSB+OpZuHcPuBw== 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 v6 15/20] posix-timers: Handle ignored list on delete and exit References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:41 +0100 (CET) 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) Reviewed-by: Frederic Weisbecker --- V6: Warn when the ignored list is not empty after deleting all timers in exit_itimers() --- include/linux/posix-timers.h | 4 +++- kernel/time/posix-timers.c | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) --- --- a/include/linux/posix-timers.h +++ b/include/linux/posix-timers.h @@ -152,7 +152,8 @@ static inline void posix_cputimers_init_ =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 @@ -176,6 +177,7 @@ static inline void posix_cputimers_init_ */ 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; --- a/kernel/time/posix-timers.c +++ b/kernel/time/posix-timers.c @@ -1027,6 +1027,18 @@ int common_timer_del(struct k_itimer *ti 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; @@ -1059,6 +1071,7 @@ SYSCALL_DEFINE1(timer_delete, timer_t, t =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 @@ -1110,6 +1123,8 @@ static void itimer_delete(struct k_itime } 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 @@ -1142,6 +1157,17 @@ void exit_itimers(struct task_struct *ts /* The timers are not longer accessible via tsk::signal */ while (!hlist_empty(&timers)) itimer_delete(hlist_entry(timers.first, struct k_itimer, list)); + + /* + * There should be no timers on the ignored list. itimer_delete() has + * mopped them up. + */ + if (!WARN_ON_ONCE(!hlist_empty(&tsk->signal->ignored_posix_timers))) + return; + + 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 Mon Nov 25 00:45:39 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 61EBB1C9DFA for ; Thu, 31 Oct 2024 15:46:44 +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=1730389607; cv=none; b=QRBy+l0gM5z3YazT8Z/voQnhno7FO740/xjxsMPSFUKqWOREFdclYpv0os5fDxpVQ7L527epwzFmvhVJn2RITCBBYx7jJjW6cfreGL6WdKH5e+U1QZuI6pzN0bSunFVSrWY4n5t2e6SwCs2Wa7oisjmT3ooeYHuHYofBEp320hg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389607; c=relaxed/simple; bh=7c5QRSKQA52SKmS1EH5RYorrhCBH8qfFuGbhfocM9hk=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=nx7jJRKlfNEYv7UJKcXSVtFxj5yOJseGsrD7HWEnFCw7dD7lb8gKVovQ0kFCpJmYr9dXVT6kD+aVmYMAN30XgjqOzp9v1EMzrDGK67JqhEnwHgwTUB/dPPp3foQNZl+RtboAdfv8ASAadOXKEGEo6pwMOv7KUG8UlgvlzlPzol0= 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=Nb+sMgDd; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=X9UhTArh; 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="Nb+sMgDd"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="X9UhTArh" Message-ID: <20241031154425.561437034@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389602; 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=5cD4EWhFiwvgt4NeHdGNlwFFc6149AA5uT1Wd9/5kEI=; b=Nb+sMgDdib7fJG0kfI1Ao+Qv+U3FJQRqaqwV9c2SEgVRzCDrQ+QzFjhiqpS12bxv4Fbkrk S2JaDejlsT8C39lKTMZWt4h/66rbePKGGQjHAujb2fGh3x6jHF4GxfGENLhgf/AdGH/9b6 MSFLlsljKnfNiMSaQZlJ5Wdd70LcKOQ2g6VHco75KXH1LHfqmyBEP2T63IsfuGXmRZn1o7 bcgcBeBh7LMB7YIz81NkPz1BW9FxpdcT2yilvC5MDu8jVuN8lJXQTHCFhYnQzLBN9E/cJJ C743g1l1x2IR7CQMmgKIQxKsUrVkqR1XfMHKgLJs0exMRTto0lBOnKwEEx6Wxw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389602; 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=5cD4EWhFiwvgt4NeHdGNlwFFc6149AA5uT1Wd9/5kEI=; b=X9UhTArhE/QYhFQqAi1KRvb4QN0CbMtv3aEbyaYtsEeDDgLRSbGE8B3Jmb4pvosydPCURp ff30iBD9VEY9KjCg== 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 v6 16/20] signal: Handle ignored signals in do_sigaction(action != SIG_IGN) References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:42 +0100 (CET) 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) Reviewed-by: Frederic Weisbecker --- kernel/signal.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++= +- 1 file changed, 52 insertions(+), 1 deletion(-) --- --- a/kernel/signal.c +++ b/kernel/signal.c @@ -2030,7 +2030,54 @@ int posixtimer_send_sigqueue(struct k_it unlock_task_sighand(t, &flags); 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. + */ + guard(rcu)(); + target =3D posixtimer_get_target(tmr); + if (target) + posixtimer_queue_sigqueue(&tmr->sigq, target, tmr->it_pid_type); + else + posixtimer_putref(tmr); + } +} +#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) { @@ -4208,6 +4255,8 @@ int do_sigaction(int sig, struct k_sigac 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; @@ -4228,6 +4277,8 @@ int do_sigaction(int sig, struct k_sigac flush_sigqueue_mask(p, &mask, &p->signal->shared_pending); for_each_thread(p, t) flush_sigqueue_mask(p, &mask, &t->pending); + } else if (was_ignored) { + posixtimer_sig_unignore(p, sig); } } From nobody Mon Nov 25 00:45:39 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 6476E1C9DFB for ; Thu, 31 Oct 2024 15:46:45 +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=1730389607; cv=none; b=jg5LIkbp7TjsCRFOUugATEDEnNiNDybbqiPGOF/npxlpuhY6LXpiB4tjr0aeUupmNvn2IUQTyMz/vzSZbu/d/zTwyqMqpTTvJAjgTUfxNtrNMhWTW4IwTN6TZGOeaIVh8zZxwsHSFLxHCtIXmVgfk7/+ZA329N5IGBJ7+jVsWIY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389607; c=relaxed/simple; bh=FsZHFUc97NANFXySRtBoYWeaYGRrCOHuIEW3PWSHUNQ=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=AxxBMbzxmS0+ajcT/+nEO37GMHnxV7wthWAZTEnc5fffVXP4qzOm8RXfb9E3yUSDWpdrod2h9idiFYBSRYs1iir92r+lM29/ZOGLQpU3HfkOha4Y6Cj6Jaeez0U8KqlMV4tKYif0AcmUItYfWWrOcMyuS8du6kpNuJi8MJNScsw= 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=JA/C+Sw8; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=1CyKhAbw; 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="JA/C+Sw8"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="1CyKhAbw" Message-ID: <20241031154425.624061922@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389604; 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=p/tTn/QrnM+A/Oc6EjwYLiCaX5sZMF5Ke/nd1sitETM=; b=JA/C+Sw8MaxCNScjJB5ATywyvBvuOCOCFVZjDd+v6mSewzM4iyFrwWBTEUSwfTT0qgPhcs 3NEU7k2kEQYjBN3f8Hd1LxLN1hw9Lelu0volhsT+NKXYNkIlt9MIJMoe4svdTD9kV7IibS 2AuRfFfjWkGPeoQAq2IvZNaS7vcYG6GFTanhT+Zs0ekAezXLK4vIpQ6+aAGKN/YiSdhigO GqDhqE6OfY3BH2AUdH/Hf6CQy4+9agAffM4OQW4N249qtfASxo1MLRBkvI6mhK4pqW9BEU hd+C3YV2rT2WAJuqgJcsFCSNv4YLs70TYdKn51Jr2QHUE8mpJIHMaVKiMXD25w== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389604; 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=p/tTn/QrnM+A/Oc6EjwYLiCaX5sZMF5Ke/nd1sitETM=; b=1CyKhAbwDLkSuQP1Xz86SzPwcziAmPcI/nq1DyveTBKKlnyLHkdBWWLX+UTBoCQasACjzO 9Kh/mp34urw6IJCg== 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 v6 17/20] signal: Queue ignored posixtimers on ignore list References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:43 +0100 (CET) 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 | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) --- --- a/kernel/signal.c +++ b/kernel/signal.c @@ -731,6 +731,16 @@ void signal_wake_up_state(struct task_st 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 *tsk, struct sigqueue= *q) +{ + if (likely(!(q->flags & SIGQUEUE_PREALLOC) || q->info.si_code !=3D SI_TIM= ER)) + __sigqueue_free(q); + else + posixtimer_sig_ignore(tsk, q); +} + /* Remove signals in mask from the pending set and queue. */ static void flush_sigqueue_mask(struct task_struct *p, sigset_t *mask, str= uct sigpending *s) { @@ -747,7 +757,7 @@ static void flush_sigqueue_mask(struct t 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(p, q); } } } @@ -1964,7 +1974,7 @@ int posixtimer_send_sigqueue(struct k_it int sig =3D q->info.si_signo; struct task_struct *t; unsigned long flags; - int ret, result; + int result; =20 guard(rcu)(); =20 @@ -1981,13 +1991,24 @@ int posixtimer_send_sigqueue(struct k_it */ tmr->it_sigqueue_seq =3D tmr->it_signal_seq; =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; @@ -2000,7 +2021,14 @@ int posixtimer_send_sigqueue(struct k_it out: trace_signal_generate(sig, &q->info, t, tmr->it_pid_type !=3D PIDTYPE_PID= , result); unlock_task_sighand(t, &flags); - 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) @@ -2048,6 +2076,7 @@ static void posixtimer_sig_unignore(stru } } #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 */ From nobody Mon Nov 25 00:45:39 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 678D91CB335 for ; Thu, 31 Oct 2024 15:46: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=1730389610; cv=none; b=KGFyfA+Kt0TjQjfre9O9ny1ZrqIwt5Q08D8SS9V5pzWV+yylXAngK4yTlSeXN6S3lUEUdtx8IIFwwE9nGpzcPn0EhBLP2DVlAQQyjY1HhRaezF0CbKPQ6laWzFYACjjCroD9z1sFF4PYuJV5P0I3ZlTPesfalHXImwVojNj4EO8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389610; c=relaxed/simple; bh=0S6v5cmI08JGS+UF1clbLlSlxLBL9TCg4QWWRJyGoFE=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=hBmE/j9mi3EujQpmZzHvMD79Tu3J4SaSBs9yHYwhij7IBks13O8YjsqNqxAk0ZRARnrqUL2DynnX6jLQA1IJb/EORv8z193PRZYrTxcIxudBm9pi7Da6e22qkKV1jgO028V0k39uAaIMqWqd2pkzppmH2hfopqfuLAzQ/HVsy+8= 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=Nup2z/Rz; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=jqYf1lev; 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="Nup2z/Rz"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="jqYf1lev" Message-ID: <20241031154425.687710276@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389605; 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=VrKnVmx625TyH/XNQQf8ZY8y8fqw9F73HDiEJSthVOc=; b=Nup2z/RzS+zMVPhga8uEKgOXolC0hwLTypc9+zqZohwl0PYBKLy+rj+Lu6iXtB6rZkDaIq 4hiA87DeNK4YtoDNAAu6+Jpad6HY3mfczY8wKSNACj41U8kAutBBhc5Z1akJpbazDQWV2D UexO4W50X09eMGA9ImIJfCEhLkJwuTma8Fu4gabv4T/L2pwwpagkgAjEaHU9fB9ylX7q46 Nvsc87JeBMiD+rA/ooGCDi36JKOhL9BdCaI0xWZujSbEd0wpbSsKT/Sbw/RIzkxghmxi5+ Ooye+yRoCXZKGfSCyviZ4ADsOMzjxivbLohCEoYP8dhfjZH4JAMvjRyhc8x9AQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389605; 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=VrKnVmx625TyH/XNQQf8ZY8y8fqw9F73HDiEJSthVOc=; b=jqYf1levRWmSSbTgp6dYteukx2vZgN0x5p3LLkCQ01I6doqiE3otjSdL79GamHAo+9lkJo 1UrNAqcT1IQMPuDg== 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 v6 18/20] posix-timers: Cleanup SIG_IGN workaround leftovers References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:45 +0100 (CET) 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 | 7 +-- kernel/time/alarmtimer.c | 47 +++++--------------------- kernel/time/posix-cpu-timers.c | 18 ++-------- kernel/time/posix-timers.c | 73 +++---------------------------------= ----- kernel/time/posix-timers.h | 2 - 6 files changed, 24 insertions(+), 125 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, struct sigqueu= e *timer_sigq); void posixtimer_free_timer(struct k_itimer *timer); =20 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -1968,7 +1968,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; @@ -1980,10 +1980,10 @@ int posixtimer_send_sigqueue(struct k_it =20 t =3D posixtimer_get_target(tmr); if (!t) - return -1; + return; =20 if (!likely(lock_task_sighand(t, &flags))) - return -1; + return; =20 /* * Update @tmr::sigqueue_seq for posix timer signals with sighand @@ -2021,7 +2021,6 @@ int posixtimer_send_sigqueue(struct k_it out: trace_signal_generate(sig, &q->info, t, tmr->it_pid_type !=3D PIDTYPE_PID= , result); unlock_task_sighand(t, &flags); - 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 @@ -602,21 +602,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,21 +300,12 @@ 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; - lockdep_assert_held(&timr->it_lock); =20 - if (timr->it_interval) - state =3D POSIX_TIMER_REQUEUE_PENDING; - - timr->it_status =3D state; - - ret =3D posixtimer_send_sigqueue(timr); - /* If we failed to send the signal the timer stops. */ - return ret > 0; + timr->it_status =3D timr->it_interval ? POSIX_TIMER_REQUEUE_PENDING : POS= IX_TIMER_DISARMED; + posixtimer_send_sigqueue(timr); } =20 /* @@ -327,62 +318,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; - - 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); =20 - /* - * 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 Mon Nov 25 00:45:39 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 E8D221CB534 for ; Thu, 31 Oct 2024 15:46:48 +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=1730389610; cv=none; b=ZOEy7Y/b48qQepAmOQ0wGCTzPzGeFEI0hPBi/9TnvBo7toKWC0o3E/TJutXCiUxH2aKzu1Pw3UPEFlUFCLxE6z95HIKoAyDE+5e2KTZxNx1LT03AjOKX78A+X9U6zxHsuh24W8/RGFb7VpMybIEvdFjPWWQmfPv+Sc0YAGu4pKQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389610; c=relaxed/simple; bh=cd4sXhXakwb+fzXsqRjrgrAranc1Xfhju2HSn7PWquc=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=d5vZeujRl0eX8JeJY46g4GsEG+ytTY5vLcA5ZefXs3too3QVhkSQyaOD5cWEyPzDH7pDpz6O/ju5SUna+g7tcH5pdRGCxpM3X9EYI+H9Hp7AZz6Riu5JtnrClb0s5bDIXY7GTk3KMTE4WNhkJfXpm7rqhyaXOHHbcdB8+XxvJfo= 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=dzKxxRHZ; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=xI2FfpDy; 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="dzKxxRHZ"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="xI2FfpDy" Message-ID: <20241031154425.752089279@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389606; 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=/G9tthwBjRfRyuW6tk1m7S8dPbACqU7gfIOOQy6uXgM=; b=dzKxxRHZdVFEQ3CSWJm9hyznvf0E6q8T0OElhgho1SkLxvYZziUCyPvahANAOMUOflc9vN e6wcq84UigMgEa25oNSI1rXGxy4YSE78LrqTSh8znsW0UiISgQHBOOlv56SrbUUdZh1DaW cIiYHUuXb4DIlxkRoiqkgWbtr9kGFrMKvIw8XnmoO9/mjyfYv2yEpIZbBcJAq2CSa72RT8 nAUGAWTfn9+NQJYDHLg0Qk3WWDCXnew9dh6OfptZD7BfzJMU31+jBJuDNgAfVY0vqgwO5n 0bdHV8qOmYDWTUPLzQ6lzOo/x0vQHNH12671T6ijQ6EAozdIxi1rf4j/u7hdsw== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389606; 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=/G9tthwBjRfRyuW6tk1m7S8dPbACqU7gfIOOQy6uXgM=; b=xI2FfpDyOzkWeffV0yk+/ocILtMWvki3BViDwmThxYcBf2/Dy3Om7JsLtxpXFPXXweTCNt 3YHavJjXHqGpOICg== 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 v6 19/20] alarmtimers: Remove the throttle mechanism from alarm_forward_now() References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:46 +0100 (CET) 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 Mon Nov 25 00:45:39 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 359D71CB9F9 for ; Thu, 31 Oct 2024 15:46: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=1730389611; cv=none; b=d0JW639e8tyVof48wpZmX8BX7f6WUrnJCQ9Wx4vdfwvR6AfsHLTPJJEXgqnD58o7a76wQUFwffrkkE4tOmXvoq6+8tJW44YqGXyMAS/24gYh5QeiY/EOeoF0pkp0Q93+H/gV5FGvI8vzqeYkjc2kK3u98/iPXS/Xq1CxwtcYTbA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730389611; c=relaxed/simple; bh=pcOy4Ch+2qNU2o58NMhqPNimeFTq5CWfkqW9pKoDuEQ=; h=Message-ID:From:To:Cc:Subject:References:MIME-Version: Content-Type:Date; b=g321ViNdzIVT3MRiCNd10Nz9jvmuVum5J/vmCZ9rmLD7l1N+RG8daS96gy+Xr8WrYKwJdvqLtXXT14Mn0b081CBzklYjIwC5zzKM0Ky+OUTEDtVoyveFaLBSn6uIIGih4lKxN6kUIoRDir3J6zwhjTnC73LV+ta/nM6/C8IMYvk= 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=BUfur+30; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b=7x/ek1kz; 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="BUfur+30"; dkim=permerror (0-bit key) header.d=linutronix.de header.i=@linutronix.de header.b="7x/ek1kz" Message-ID: <20241031154425.814629453@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1730389607; 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=CPnchhOLepqueHqgrg5lKLbIFHFsL+lVYOmF9AdWSew=; b=BUfur+30iKJlqVboS2F74y3/ZfuCUINKW+VNSLL7zB4fRB53HORU6zsN29BZT/Y4ty/XD8 fXbuaK4Hj25w5cYM/DddcSyZT9WGmyMv9OGI3ZON7XQgMDMHbUnkZa0+vqnVIxxqWUWbhu 034NUISfD4TJfKmENUVxxkYqgc7Sxm3JhL+so244TSwVXZ8zzT0e3J9G+f2etUiu3/hSBv PYe4zd7JCUFxwG2Pifa3JjdbvXvPbtiE0IwK9Is84gf2N8MY/TQw/7ELDHoSdVfm3V0rcD 2kk2j97/UpyeNZ4DpZYwe/xIjjEl8pR0vkKb1eXkPZrqkOx49Ut5WqNkZyWvvQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1730389607; 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=CPnchhOLepqueHqgrg5lKLbIFHFsL+lVYOmF9AdWSew=; b=7x/ek1kzjJXV++1MM3ugxpcy3kuLSomY00no8jhCuqu/6e6otpGqzcbYM5lGmanq0GS9oM Te1nKnOhCtN1hfCw== 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 v6 20/20] alarmtimers: Remove return value from alarm functions References: <20241031151625.361697424@linutronix.de> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Date: Thu, 31 Oct 2024 16:46:47 +0100 (CET) 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(-) --- --- a/drivers/power/supply/charger-manager.c +++ b/drivers/power/supply/charger-manager.c @@ -1412,10 +1412,9 @@ static inline struct charger_desc *cm_ge 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) --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -79,13 +79,11 @@ static enum hrtimer_restart timerfd_tmrp 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 /* --- 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); --- a/kernel/time/alarmtimer.c +++ b/kernel/time/alarmtimer.c @@ -321,7 +321,7 @@ static int alarmtimer_resume(struct devi =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 @@ static void * @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( * * 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_i * @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 a =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); --- a/net/netfilter/xt_IDLETIMER.c +++ b/net/netfilter/xt_IDLETIMER.c @@ -107,14 +107,12 @@ static void idletimer_tg_expired(struct 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)