Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp2133202pxk; Mon, 14 Sep 2020 05:44:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzzhLf/CFgwekxOqRWtg6T30V0SFmU8M402yTiS55uR8gn1tQmrH1auxxpyUszH/1igAFNP X-Received: by 2002:aa7:c387:: with SMTP id k7mr16615675edq.242.1600087471482; Mon, 14 Sep 2020 05:44:31 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1600087471; cv=none; d=google.com; s=arc-20160816; b=pzkVT/xJwb+gwlc3Use4boucsxQhkQF8KvhUGC+RaqHPwZsX4y3+Lmk6G2+pFfi9V/ r6W3WHNuB8AlJqBQXt7aaEvFurvHswiYOVdUxJJC8CXrtMCJA3ouBXTCC9zC+uke4xVs y+VThmOdpqGcdwXvBi72E2E09vv4PgKMmkGwnUOqP0s/v9QP2JLKmirvGNlK5909nzcu /BMFlRW5dRaeA+jxu//xL4D1GJfwtxrRoeb9qKNJJtRzeCIu/UiTl1M3O6MnFHzDxOpt yUdH9om2Lcz3ILMw5Uq23mPmCLtygfuaTW67S/XnFW8FsJsdT21xRNMWJm4zlPb1eu14 AhzQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:dkim-signature :dkim-signature:from; bh=1xO/PiOzPX9MAAKuiQYEnXlpCbivYbNxoPS3ZIcyqlQ=; b=xTUAr9HyZxvDBWvHCR/3Fq1ANC7rh0ue9Yntq5SnrcSehB9Qjl7nFBweVJP5rQiVmt LfEAettG6SOn5SIHL2mapsT4cqBnAc0nvVqlbrJL2Z5BgFBtLprEYC/zMG/zxIlyW5yy HZmog+N50wue7qIVozCEZ4cMVokU1SA9E7Twb1vmupVj/n1Jh+M1ydcmFGonaXOBqG1/ Bw6nJyf1S4WX6ulH8LeN9EZU35UWEdcLladK2Yfcm2gBdul0OGx1a5jzR3qAY0z+EouG MJx3lu3GyXc8K6UcH1PWqo7GnwhUbKp1K1z6yUxHPVk1x6O0PNUMribbnn6b3Wk124uc wUOA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=ZnZ5gsvL; dkim=neutral (no key) header.i=@vger.kernel.org header.s=2020e header.b="Vuod/Jdj"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id y19si7088956ejf.251.2020.09.14.05.44.09; Mon, 14 Sep 2020 05:44:31 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linutronix.de header.s=2020 header.b=ZnZ5gsvL; dkim=neutral (no key) header.i=@vger.kernel.org header.s=2020e header.b="Vuod/Jdj"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 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 S1726561AbgINMms (ORCPT + 99 others); Mon, 14 Sep 2020 08:42:48 -0400 Received: from Galois.linutronix.de ([193.142.43.55]:33620 "EHLO galois.linutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726489AbgINMer (ORCPT ); Mon, 14 Sep 2020 08:34:47 -0400 From: John Ogness DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020; t=1600086839; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1xO/PiOzPX9MAAKuiQYEnXlpCbivYbNxoPS3ZIcyqlQ=; b=ZnZ5gsvLsxlGAZd2YWuQ7TRRR1KsBbBaVudaRVnUsuix4gg8jgsHdgBe4s40LmB6A9+mU+ m8qefDWTBcwKO6RjJY0t3MqlogZXtInc6xnWwbwWQ2Ysw9vrroC57bF0pRkdKw7SaYuF2o y7VXD1me6tNT4UDP+/2+Dn8/Dm4192j59Q7NDxlN9DHa72/PILKWKDIAaIoS1cWrf318Jd 2BPlGYPHebOPWwevVwDNWos+gaEOnjUByqVYBoQck9be0yPx3O6KQQjzfB2iKN2vSWunRP 4oxkmDflSp7PZRe+XrSRWLhVW9jn3EcMaT+iZDV3CrC3iiEAYkbbLERbUs4FjQ== DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/relaxed; d=linutronix.de; s=2020e; t=1600086839; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1xO/PiOzPX9MAAKuiQYEnXlpCbivYbNxoPS3ZIcyqlQ=; b=Vuod/JdjC4e6m5YPYSpagR++EIZ6MDETP+BrCSnjxIgZKtfpLI3dKquvvFYqX6uxANO0qO 8Y94pBXT6D3UhuCw== To: Petr Mladek Cc: Sergey Senozhatsky , Sergey Senozhatsky , Steven Rostedt , Linus Torvalds , Greg Kroah-Hartman , Thomas Gleixner , Peter Zijlstra , Andrea Parri , Paul McKenney , kexec@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH printk v5 6/6] printk: reimplement log_cont using record extension Date: Mon, 14 Sep 2020 14:39:54 +0206 Message-Id: <20200914123354.832-7-john.ogness@linutronix.de> In-Reply-To: <20200914123354.832-1-john.ogness@linutronix.de> References: <20200914123354.832-1-john.ogness@linutronix.de> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Use the record extending feature of the ringbuffer to implement continuous messages. This preserves the existing continuous message behavior. Signed-off-by: John Ogness Reviewed-by: Petr Mladek --- kernel/printk/printk.c | 98 +++++++++--------------------------------- 1 file changed, 20 insertions(+), 78 deletions(-) diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index 964b5701688f..9a2e23191576 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c @@ -535,7 +535,10 @@ static int log_store(u32 caller_id, int facility, int level, r.info->caller_id = caller_id; /* insert message */ - prb_commit(&e); + if ((flags & LOG_CONT) || !(flags & LOG_NEWLINE)) + prb_commit(&e); + else + prb_final_commit(&e); return (text_len + trunc_msg_len); } @@ -1084,7 +1087,7 @@ static unsigned int __init add_to_rb(struct printk_ringbuffer *rb, dest_r.info->ts_nsec = r->info->ts_nsec; dest_r.info->caller_id = r->info->caller_id; - prb_commit(&e); + prb_final_commit(&e); return prb_record_text_space(&e); } @@ -1884,87 +1887,26 @@ static inline u32 printk_caller_id(void) 0x80000000 + raw_smp_processor_id(); } -/* - * Continuation lines are buffered, and not committed to the record buffer - * until the line is complete, or a race forces it. The line fragments - * though, are printed immediately to the consoles to ensure everything has - * reached the console in case of a kernel crash. - */ -static struct cont { - char buf[LOG_LINE_MAX]; - size_t len; /* length == 0 means unused buffer */ - u32 caller_id; /* printk_caller_id() of first print */ - u64 ts_nsec; /* time of first print */ - u8 level; /* log level of first message */ - u8 facility; /* log facility of first message */ - enum log_flags flags; /* prefix, newline flags */ -} cont; - -static void cont_flush(void) -{ - if (cont.len == 0) - return; - - log_store(cont.caller_id, cont.facility, cont.level, cont.flags, - cont.ts_nsec, NULL, 0, cont.buf, cont.len); - cont.len = 0; -} - -static bool cont_add(u32 caller_id, int facility, int level, - enum log_flags flags, const char *text, size_t len) -{ - /* If the line gets too long, split it up in separate records. */ - if (cont.len + len > sizeof(cont.buf)) { - cont_flush(); - return false; - } - - if (!cont.len) { - cont.facility = facility; - cont.level = level; - cont.caller_id = caller_id; - cont.ts_nsec = local_clock(); - cont.flags = flags; - } - - memcpy(cont.buf + cont.len, text, len); - cont.len += len; - - // The original flags come from the first line, - // but later continuations can add a newline. - if (flags & LOG_NEWLINE) { - cont.flags |= LOG_NEWLINE; - cont_flush(); - } - - return true; -} - static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len) { const u32 caller_id = printk_caller_id(); - /* - * If an earlier line was buffered, and we're a continuation - * write from the same context, try to add it to the buffer. - */ - if (cont.len) { - if (cont.caller_id == caller_id && (lflags & LOG_CONT)) { - if (cont_add(caller_id, facility, level, lflags, text, text_len)) - return text_len; - } - /* Otherwise, make sure it's flushed */ - cont_flush(); - } - - /* Skip empty continuation lines that couldn't be added - they just flush */ - if (!text_len && (lflags & LOG_CONT)) - return 0; - - /* If it doesn't end in a newline, try to buffer the current line */ - if (!(lflags & LOG_NEWLINE)) { - if (cont_add(caller_id, facility, level, lflags, text, text_len)) + if (lflags & LOG_CONT) { + struct prb_reserved_entry e; + struct printk_record r; + + prb_rec_init_wr(&r, text_len, 0); + if (prb_reserve_in_last(&e, prb, &r, caller_id)) { + memcpy(&r.text_buf[r.info->text_len], text, text_len); + r.info->text_len += text_len; + if (lflags & LOG_NEWLINE) { + r.info->flags |= LOG_NEWLINE; + prb_final_commit(&e); + } else { + prb_commit(&e); + } return text_len; + } } /* Store it in the record log */ -- 2.20.1