Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp7211366rwd; Tue, 6 Jun 2023 07:46:20 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ44QwTPuJrzll0rCriGvXnU4UC3aJtkM+h9EW01sXTxa9VFoga8a8Kjy2fwHFcnUg4grBoI X-Received: by 2002:a17:902:d4cc:b0:1ae:35ba:8c8f with SMTP id o12-20020a170902d4cc00b001ae35ba8c8fmr2933071plg.13.1686062780290; Tue, 06 Jun 2023 07:46:20 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686062780; cv=none; d=google.com; s=arc-20160816; b=kkrQbEWPGhy7udMC/LLgE+lMK/1WD9lH+CTR+CO2NHhty8lZieLZfgc2D1Gco7Y73A IYXf5kelP3O+/lTx5SurntILOFD4IX6o2rvb1BORs/93NSZ5ZIDzGcEpzEz8CBHby6fb BgCH5Zbu6nvcfWh56p2YiUnf5PEWY92kmYxtxBz5VbW9MdKFgTK52dBvMUBmjrUkNHam P7zlsU/hDF+57L1BKBjY9GTJ1qOZVoubXVaOEtUUzfSGrZnd/oow1jFf2ZuwEXfeHLEl FSwumb4eeqCxENram6nTv1CAF9N0U4IsvgY0Hpk9P29ZxhuLYrLjcBks+i7cQvUYa50w CROw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:date:mime-version:references:subject:cc:to:from :dkim-signature:dkim-signature:message-id; bh=WBARrxgJ0Fo3O3pXIjgjYSXb/czDjqPuA7NhGPJIs00=; b=X2/gwoH6F1VTjRI5+s4marRnJKRzdiwKVdjAS1Y2eoR4JoJLDnceje7WKBPuMBbqbd bgWsXOnNjiwTKR7QOezYYBTfZQzNz8KE6qzPy3Htp633k6joYtpiT8OgfcPs7GhnIwGV U9Bt/kUH25rhVed2e9EQVKTPi2F1aafGCjvfEw+XAEt/Io1/REVUmxPiParZXsxN72ca GqLAV/T3w/gXKqHno3Vk8nEbvpjb2p9fUBhWMBQh/hF22vBbX8a63nC7Oufd/endOzBk Bn7gvQqKh1GJoR24IMDLjpjxmnVz2Lm4HDXXI5QP14dbl1iQunD2D+8eJBy6Oi4QVuhG X8Sg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=oEOxb0sU; dkim=neutral (no key) header.i=@linutronix.de header.b=EiH4wIJO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k6-20020a170902c40600b001a95c413f7csi7500239plk.550.2023.06.06.07.46.07; Tue, 06 Jun 2023 07:46:20 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=oEOxb0sU; dkim=neutral (no key) header.i=@linutronix.de header.b=EiH4wIJO; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=linutronix.de Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238262AbjFFOkZ (ORCPT + 99 others); Tue, 6 Jun 2023 10:40:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42272 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238139AbjFFOjV (ORCPT ); Tue, 6 Jun 2023 10:39:21 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC4AA10E0 for ; Tue, 6 Jun 2023 07:38:18 -0700 (PDT) Message-ID: <20230606142032.768353204@linutronix.de> DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1686062288; 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=WBARrxgJ0Fo3O3pXIjgjYSXb/czDjqPuA7NhGPJIs00=; b=oEOxb0sUym1Pwy7Z9NDCrzBqaCSSmmAuNYE8cNhD9uSA2Muk9RagSHTmhGzOUEUlWgY6mh Gh6EqnielU4dcz0Ho51Yng5JazPPiIWqHbA/EiQvyPzKjh+c+NaWZjzfA6XffeZwNJZRvn cGsHnK+TGhN1FzHt4cyF62HJCIHlokHGgqa07A8imVK6kY5bdtdEErPjSUxk0lTiyMvZwg kHR1DIJXAabMZVX4mksvN86FGlGiRfQi4f1EqtWH7evD0FwPlOz31EX4syi6IKLj0WUxQ/ +3xkOPBlEEj+bgzm18F0jdJCAMUn+dg+CUL9qpsSbxljvgRr28/ITciir3PY7g== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1686062288; 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=WBARrxgJ0Fo3O3pXIjgjYSXb/czDjqPuA7NhGPJIs00=; b=EiH4wIJOOX9gXUPVuG+4+zy6hy9FQTz/fYU92XeTosFRTHiKSnOBst+MAfEaLsjuTBN8dH sh5zPjLfVn7Wc8CA== From: Thomas Gleixner To: LKML Cc: Frederic Weisbecker , Anna-Maria Behnsen , John Stultz , Peter Zijlstra , Ingo Molnar , Stephen Boyd , Eric Biederman , Oleg Nesterov Subject: [patch 31/45] posix-timers: Add a refcount to struct k_itimer References: <20230606132949.068951363@linutronix.de> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Date: Tue, 6 Jun 2023 16:38:08 +0200 (CEST) X-Spam-Status: No, score=-4.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_PASS,T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 this work correctly this 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 --- 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,10 +6,12 @@ #include #include #include +#include #include struct kernel_siginfo; struct task_struct; +struct k_itimer; /* * Bit fields within a clockid: @@ -167,6 +169,7 @@ static inline void posix_cputimers_rt_wa void posixtimer_rearm_itimer(struct task_struct *p); bool posixtimer_deliver_signal(struct kernel_siginfo *info); +void posixtimer_free_timer(struct k_itimer *timer); /* Init task static initializer */ #define INIT_CPU_TIMERBASE(b) { \ @@ -192,6 +195,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 #ifdef CONFIG_POSIX_CPU_TIMERS_TASK_WORK @@ -219,6 +223,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. @@ -243,6 +248,7 @@ struct k_itimer { struct task_struct *it_process; }; struct sigqueue *sigq; + rcuref_t rcuref; union { struct { struct hrtimer timer; @@ -263,4 +269,12 @@ void set_process_cpu_timer(struct task_s int update_rlimit_cpu(struct task_struct *task, unsigned long rlim_new); +#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,6 +417,7 @@ static struct k_itimer * alloc_posix_tim return NULL; } clear_siginfo(&tmr->sigq->info); + rcuref_init(&tmr->rcuref, 1); return tmr; } @@ -427,7 +428,7 @@ static void k_itimer_rcu_free(struct rcu kmem_cache_free(posix_timers_cache, tmr); } -static void posix_timer_free(struct k_itimer *tmr) +void posixtimer_free_timer(struct k_itimer *tmr) { put_pid(tmr->it_pid); sigqueue_free(tmr->sigq); @@ -439,7 +440,7 @@ static void posix_timer_unhash_and_free( spin_lock(&hash_lock); hlist_del_rcu(&tmr->t_hash); spin_unlock(&hash_lock); - posix_timer_free(tmr); + posixtimer_putref(tmr); } static int common_timer_create(struct k_itimer *new_timer) @@ -474,7 +475,7 @@ static int do_timer_create(clockid_t whi */ new_timer_id = posix_timer_add(new_timer); if (new_timer_id < 0) { - posix_timer_free(new_timer); + posixtimer_free_timer(new_timer); return new_timer_id; }