Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp1067941rwb; Tue, 27 Sep 2022 08:03:37 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4Yb2M4Cl02Otfy8jop6kAaUEga1lFT6z1KHLw+3lLmwmeMs5b1vo1YNFHcMObPDEXfSPv2 X-Received: by 2002:a17:907:969e:b0:782:6b92:6b1f with SMTP id hd30-20020a170907969e00b007826b926b1fmr20702241ejc.140.1664291016959; Tue, 27 Sep 2022 08:03:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664291016; cv=none; d=google.com; s=arc-20160816; b=O599a0L5hIv6GV14fvlEz/S1vqa46oDf+3P7M7R1LWOlUOYm8JDa04DLmcloiizuNe wfYI8Uwcquakcx0PMNhXoc5tbP21/3c0iGau9ZgxplRCTs83oPX0IZFhxX3cJOZtCzby 2bCYk011ppJTpzFg1iE9QXq+7y+5vUBjVg5zriKhZg51V+xndYDxQT2pGVqSJb+ATRfM XOIa8XQPri+LsONnGDfq9+q7d3pYpvXzJuYdnOaQIsE9aPJXlZksVevaWsrHhMsASC4n EMZz8Aaup0Qk449COEjkATbrkiZ0FYK9ZXZBFiKVTLEqDeICwV8KODdigTkLKegnfBHn nqLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:dkim-signature:dkim-signature:from; bh=XoBJBmZ5UAwI42BPOdJ+eigxCsaa7zGOoB8JqcvHGZU=; b=dU+tw+Y4aKg3bjBCQp8xyxkpTbgqLvU85XiSlP7WYxlKcEy+6VyjeBtMjSqBIylZSi R17IaRMNs3i/x2PMBp5PADDU8e3WtGV3qsSW0I4PLDG/boOKIY5WaU2t7IpWWi4ndtkh B8t/xznwq7p4ffEp+aywe5ilIf5EZo5NHnR8k0JfGq9rlNYmwvOmDvTBVuKR9GjX1qxB TBHVZWEwF5OXXV1uHiowRydAZEfrI5sEzC04KdaBwFwJYkvO25/6YUwOyoWamOY42tmY ozhByihgeTyIKQWQjumXqXNzjPzgOsZeDi7d2OwWwkz0wPU2sj63HWIgQw0CNTI8z8zr JG0Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=dnIaWaAg; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=K5+W7osX; 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 gs11-20020a1709072d0b00b0078014756419si1960490ejc.66.2022.09.27.08.03.10; Tue, 27 Sep 2022 08:03:36 -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=dnIaWaAg; dkim=neutral (no key) header.i=@linutronix.de header.s=2020e header.b=K5+W7osX; 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 S231627AbiI0OrA (ORCPT + 99 others); Tue, 27 Sep 2022 10:47:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:40088 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233094AbiI0Oqh (ORCPT ); Tue, 27 Sep 2022 10:46:37 -0400 Received: from galois.linutronix.de (Galois.linutronix.de [IPv6:2a0a:51c0:0:12e:550::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A80BB57545 for ; Tue, 27 Sep 2022 07:40:49 -0700 (PDT) From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1664289647; 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: in-reply-to:in-reply-to:references:references; bh=XoBJBmZ5UAwI42BPOdJ+eigxCsaa7zGOoB8JqcvHGZU=; b=dnIaWaAg6g6tnH5NlwAQg8kS87oziPYVinVpkIlbcGIKoDeSqbFcSJwx+egsf1t/+hJXgP STLZ4mYAGH16DWBAwgiMarfRdhEKxLFUbC//+2c6YMy4l8PSdQ3LtKYO5hWOsK43cCKUU3 l5u7g32kUz3qTDw6J1mbS3JzssSAV71XmzkkFpwXHSDbdjHBS2KjNGnqU0b2RoSFT8UNHl y7ITm5qyBmOyP3pvwXCaR4Qpmdl+S4gs+bjDCGfi9kOA+d6vzbIAWgJw/Ig6nc8/gyzala POihYc/zgxafFGVJhtCIz0akpnEshhevbe20CzxDCE6Hx14V3vu+28g6oAA02A== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1664289647; 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: in-reply-to:in-reply-to:references:references; bh=XoBJBmZ5UAwI42BPOdJ+eigxCsaa7zGOoB8JqcvHGZU=; b=K5+W7osXpHjlV1/Jg3G61fqndpnAVpEKJ1UqEkaHdFLHYCVx/+HIy51o7FRaY2LGMumWwi u+v9EjYBYm4m0SDQ== To: Thomas Gleixner , LKML Cc: Petr Mladek , Sergey Senozhatsky , Steven Rostedt , Linus Torvalds , Peter Zijlstra , "Paul E. McKenney" , Daniel Vetter , Greg Kroah-Hartman , Helge Deller , Jason Wessel , Daniel Thompson Subject: Re: [patch RFC 28/29] printk: Provide functions for atomic write enforcement In-Reply-To: <20220910222301.995758602@linutronix.de> References: <20220910221947.171557773@linutronix.de> <20220910222301.995758602@linutronix.de> Date: Tue, 27 Sep 2022 16:46:46 +0206 Message-ID: <87mtaklw29.fsf@jogness.linutronix.de> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-3.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,INVALID_DATE_TZ_ABSURD, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS 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 Below is a fix that was used for the LPC2022 demo so that an interrupting context does not clobber the console state when the interrupted context was the console owner. On 2022-09-11, Thomas Gleixner wrote: > --- a/kernel/printk/printk_nobkl.c > +++ b/kernel/printk/printk_nobkl.c > +/** > + * cons_atomic_flush_one - Flush one console in atomic mode > + * @con: The console to flush > + * @prio: The priority of the current context > + */ > +static void cons_atomic_flush_one(struct console *con, enum cons_prio prio) > +{ > + struct cons_write_context *wctxt = cons_get_wctxt(con, prio); > + struct cons_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); @ctxt is per-console, per-cpu, and per-prio. But it is *not* per-context. If a CPU is in EMERGENCY priority and is interrupted by another context that calls into printk() while the first context had the console locked, the following cons_atomic_try_acquire() will use the same ctxt and clobber the values used by the first context. This corrupts the state information for the first context and results in situations where the console is never unlocked because the owner's state was corrupt. > + if (!cons_atomic_try_acquire(con, ctxt, prio)) > + return; > + > + do { > + /* > + * cons_emit_record() returns false when the console was > + * handed over or taken over. In both cases the context is > + * not longer valid. > + */ > + if (!cons_emit_record(wctxt)) > + return; > + } while (ctxt->backlog); > + > + cons_release(ctxt); > +} Since it is not desirable to actively print from nested contexts of the same priority, add an @in_use flag to wctxt, allowing to detect the situation and avoid active printing and corrupting the state. Applying the following patch on top does just that: diff --git a/include/linux/console.h b/include/linux/console.h index e6bde0e879fc..1b3028cce3f3 100644 --- a/include/linux/console.h +++ b/include/linux/console.h @@ -317,6 +317,7 @@ struct cons_context { * @len: Length to write * @pos: Current write position in @outbuf * @unsafe: Invoked in unsafe state due to force takeover + * @in_use: The context is in use */ struct cons_write_context { struct cons_context __private ctxt; @@ -324,6 +325,7 @@ struct cons_write_context { unsigned int len; unsigned int pos; bool unsafe; + bool in_use; }; #define CONS_MAX_NEST_LVL 8 diff --git a/kernel/printk/printk_nobkl.c b/kernel/printk/printk_nobkl.c index 736f71361799..b513b2fb2c2d 100644 --- a/kernel/printk/printk_nobkl.c +++ b/kernel/printk/printk_nobkl.c @@ -1338,8 +1338,12 @@ static void cons_atomic_flush_one(struct console *con, enum cons_prio prio) struct cons_write_context *wctxt = cons_get_wctxt(con, prio); struct cons_context *ctxt = &ACCESS_PRIVATE(wctxt, ctxt); - if (!cons_atomic_try_acquire(con, ctxt, prio)) + if (wctxt->in_use) return; + wctxt->in_use = true; + + if (!cons_atomic_try_acquire(con, ctxt, prio)) + goto out; do { /* @@ -1348,10 +1352,12 @@ static void cons_atomic_flush_one(struct console *con, enum cons_prio prio) * not longer valid. */ if (!cons_emit_record(wctxt)) - return; + goto out; } while (ctxt->backlog); cons_release(ctxt); +out: + wctxt->in_use = false; } /** John Ogness