From patchwork Tue Jun 6 14:38:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thomas Gleixner X-Patchwork-Id: 103903 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp3455553vqr; Tue, 6 Jun 2023 07:59:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5XADq3hiGo8vHlYBZZFz+Oxnm35GGe505no77UdmZf++ZIQHUBfF/IAkofH48gIsIQ/e6v X-Received: by 2002:a05:620a:654a:b0:75b:23a1:8e79 with SMTP id qc10-20020a05620a654a00b0075b23a18e79mr1703010qkn.74.1686063546266; Tue, 06 Jun 2023 07:59:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1686063546; cv=none; d=google.com; s=arc-20160816; b=Tgq3jnZK+pfRp3tikXMfPKTH4skCGdP5CadNB56pSEd9lbGuZSr9cPha/W9sKkw4Vs /hDmsUtyCD2fsCE7k92LvoeBZgSwfiAh2Ozm72ih35DdUuYRvGqY4WIcw+yNB/1c8Vvj EeeVzqG5uNgT8MfvtRUr8gV1uh9Wgk7JvgUxmqsgm56KQrn87qI8iI7qD2bR5FaSoBQB eAimGS/S72kTStdyDc16HSqtwIUh6BCrrdJEgt/gWU2QWFfeOfbEj61mrRgjB6nHvnnM 3NV/R+EKzzHxlwGpEHQjR3hap640HaVO0XquWrkBDabY430HfUOd/hTYML1TJx1vaJ77 xdsA== 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.s=2020e; 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: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id z3-20020ae9c103000000b0075cf5c73f94si5981085qki.772.2023.06.06.07.58.52; Tue, 06 Jun 2023 07:59:06 -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.s=2020e; 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 S238267AbjFFOk0 (ORCPT + 99 others); Tue, 6 Jun 2023 10:40:26 -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 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 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767965768723786673?= X-GMAIL-MSGID: =?utf-8?q?1767965768723786673?= 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; }