From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 74358C43334 for ; Sat, 4 Jun 2022 19:31:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239985AbiFDTa5 (ORCPT ); Sat, 4 Jun 2022 15:30:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46810 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239929AbiFDTax (ORCPT ); Sat, 4 Jun 2022 15:30:53 -0400 Received: from mail-qt1-x836.google.com (mail-qt1-x836.google.com [IPv6:2607:f8b0:4864:20::836]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BAB8922519 for ; Sat, 4 Jun 2022 12:30:52 -0700 (PDT) Received: by mail-qt1-x836.google.com with SMTP id k4so1354273qth.8 for ; Sat, 04 Jun 2022 12:30:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Pibz/KENrk8dWYPVgji9GTuoqUjjn4PZ4o1W4g097Gg=; b=e4nBobTgPn+CP4VPeQfBie8q+Tc0uce9HxMY3ySOdDDEaejD6kTUJJbMPVfsf9NJhH qP/dYAIIPCQ64UBzy3+TglHoVkl2B6YChj6UmnkRtkWVjtD+x2jVVJmHVYbKxxfokRze cCC/so1OBZfyBE3h/WXnS0wNzbXsPpg5rQ6k/sxpvtAHbYHIdVsTp5VvQwqXLHR7yD3M CqsYYrKr41Szj80vPehyPaVxnV0SQTgLeFUYp1bLzZigOatpDhu+Juk17/MoYDqe0WM3 Ef0Psb3C7zZkE6TLavDET2mYK+oVKx7VidVZYHc3nTuFzZjiy+WYnDCkAON44q6KNdW0 8MRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Pibz/KENrk8dWYPVgji9GTuoqUjjn4PZ4o1W4g097Gg=; b=DEdQvRwsvrASdQ/zsyS8ALrkLNRFzPJtfjpuBhECQ+5Sgmift/RcETcAaeSa3AIfzv YLDacfrKlRl5V3MGpT7SSKYL4PnecQZtXAmhf+oNKZhpEgNUID9yKLQXHwc1ihq66Ujq Od2F5utZOFEeirzbbQLGpUxoy7nvuHVgTCv7QbVCh3qFF36SD90Q3Uks1I5b9l8lwsMz tDRxXJcxqPq+nK+/5+EvMiOcUxBHuSdOD4AQmtMNfG0cOvwXMCbiAX9i/YUVPKWCewXk BoyBXz9rjzZ1xlQSN2q+FrauRtJfCZmNTcPCcVPOZMQuegibh+diSQA2dyeIzskbvaYj lgLA== X-Gm-Message-State: AOAM532bnq25SLCC/q+HN4L7gcLbuaEmYkfmyo3SAahzjR0D7ENcCKxX m3KBPi0hIqb4EyuSOOn9gcEUPdpgCd70 X-Google-Smtp-Source: ABdhPJymKW+MPe/S4MobSQMjYUgg5DQ1K2vtoEIDaam+ZH+mHf1pGF2CZoRaW0byl2/6KFzQYSGDiw== X-Received: by 2002:a05:622a:1101:b0:304:e4ad:f492 with SMTP id e1-20020a05622a110100b00304e4adf492mr4123050qty.452.1654371051359; Sat, 04 Jun 2022 12:30:51 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.30.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:30:50 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org, Matthew Wilcox Subject: [PATCH v3 01/33] lib/printbuf: New data structure for printing strings Date: Sat, 4 Jun 2022 15:30:10 -0400 Message-Id: <20220604193042.1674951-2-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds printbufs: a printbuf points to a char * buffer and knows the size of the output buffer as well as the current output position. Future patches will be adding more features to printbuf, but initially printbufs are targeted at refactoring and improving our existing code in lib/vsprintf.c - so this initial printbuf patch has the features required for that. Signed-off-by: Kent Overstreet Reviewed-by: Matthew Wilcox (Oracle) --- include/linux/printbuf.h | 118 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 include/linux/printbuf.h diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h new file mode 100644 index 0000000000..8b3797dc4b --- /dev/null +++ b/include/linux/printbuf.h @@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifndef _LINUX_PRINTBUF_H +#define _LINUX_PRINTBUF_H + +#include + +/* + * Printbufs: String buffer for outputting (printing) to, for vsnprintf + */ + +struct printbuf { + char *buf; + unsigned size; + unsigned pos; +}; + +/* + * Returns size remaining of output buffer: + */ +static inline unsigned printbuf_remaining_size(struct printbuf *out) +{ + return out->pos < out->size ? out->size - out->pos : 0; +} + +/* + * Returns number of characters we can print to the output buffer - i.e. + * excluding the terminating nul: + */ +static inline unsigned printbuf_remaining(struct printbuf *out) +{ + return out->pos < out->size ? out->size - out->pos - 1 : 0; +} + +static inline unsigned printbuf_written(struct printbuf *out) +{ + return min(out->pos, out->size); +} + +/* + * Returns true if output was truncated: + */ +static inline bool printbuf_overflowed(struct printbuf *out) +{ + return out->pos >=3D out->size; +} + +static inline void printbuf_nul_terminate(struct printbuf *out) +{ + if (out->pos < out->size) + out->buf[out->pos] =3D 0; + else if (out->size) + out->buf[out->size - 1] =3D 0; +} + +static inline void __prt_chars(struct printbuf *out, char c, unsigned n) +{ + memset(out->buf + out->pos, + c, + min(n, printbuf_remaining(out))); + out->pos +=3D n; +} + +static inline void prt_chars(struct printbuf *out, char c, unsigned n) +{ + __prt_chars(out, c, n); + printbuf_nul_terminate(out); +} + +static inline void __prt_char(struct printbuf *out, char c) +{ + if (printbuf_remaining(out)) + out->buf[out->pos] =3D c; + out->pos++; +} + +static inline void prt_char(struct printbuf *out, char c) +{ + __prt_char(out, c); + printbuf_nul_terminate(out); +} + +static inline void prt_bytes(struct printbuf *out, const void *b, unsigned= n) +{ + memcpy(out->buf + out->pos, + b, + min(n, printbuf_remaining(out))); + out->pos +=3D n; + printbuf_nul_terminate(out); +} + +static inline void prt_str(struct printbuf *out, const char *str) +{ + prt_bytes(out, str, strlen(str)); +} + +static inline void prt_hex_byte(struct printbuf *out, u8 byte) +{ + __prt_char(out, hex_asc_hi(byte)); + __prt_char(out, hex_asc_lo(byte)); + printbuf_nul_terminate(out); +} + +static inline void prt_hex_byte_upper(struct printbuf *out, u8 byte) +{ + __prt_char(out, hex_asc_upper_hi(byte)); + __prt_char(out, hex_asc_upper_lo(byte)); + printbuf_nul_terminate(out); +} + +#define PRINTBUF_EXTERN(_buf, _size) \ +((struct printbuf) { \ + .buf =3D _buf, \ + .size =3D _size, \ +}) + +#endif /* _LINUX_PRINTBUF_H */ --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0BCCFC43334 for ; Sat, 4 Jun 2022 19:31:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240042AbiFDTbB (ORCPT ); Sat, 4 Jun 2022 15:31:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46832 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239950AbiFDTaz (ORCPT ); Sat, 4 Jun 2022 15:30:55 -0400 Received: from mail-qk1-x736.google.com (mail-qk1-x736.google.com [IPv6:2607:f8b0:4864:20::736]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 097AA22518 for ; Sat, 4 Jun 2022 12:30:54 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id bi27so1809717qkb.10 for ; Sat, 04 Jun 2022 12:30:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=feLvusglZnmvtVTa9kR5/VeR2dvAvIYip9mj6c5ceDs=; b=qNsYIXjurPlBzItHVVOSPXWJTMf7iUxeAtowdunE7SMzy/Ny6D0T3jIBmZ7bgd3RMg /rzsKGV4v/2IyptKlY7Oh5VuyzaE/DzwMmmiyRMpbRQI+UGB3UE48oSTJLp5segiobfl UhS1b4/NFud1bxsBjRZaihY/1LGq7+zll5NKe2pK2zr4HK0mId02nr32QeJJ4EWhz8RB G3WVPyM0M9YJKmCkcZ8Orq2PDt42ThXFhRQNJsOid5+tYtmvOAP8Yx1bDV5vGPEHYbLO +vXOq5H8k6Rd8ZmYZbKFnycWYdYL+tRVbhHmMpxIeUds+/T/tlR9Oj3RLc/KoQ8gK+gE vJGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=feLvusglZnmvtVTa9kR5/VeR2dvAvIYip9mj6c5ceDs=; b=T0XOafsFT4T5AKUHdqXwpPBePKG+ZJ2tYk4smAYSsqpO4M/hRJ1QsHFMqJPusUK6lE avCkrhDe7T9tpcdgUWhgMBzynMRrFdwbnGZ80ak7bIf1Ugu6P0YSKipJ+kKRsHNmVTsQ YqcKkjSxAHLwlSTPb+WDADB9io3e5ienkB2n+phM9nv9P7ZnFPhQZ5JNYQ0xh0ziSTYM cfk/wSDZnfO9lh6GZVMqRZ2GKdhSbZOAvvXkOMUyG9HoE4btrneL7eocD8XJessnIwWy xQgKsxMFGhhHJOU2xdbPT4F2HINmy+jqafpmF6jq1X9ELb0KT6OTzeSFHGMduJCNYXBi JAtQ== X-Gm-Message-State: AOAM530A7X+J1pDO4dYIy1pIkziMrAb70Tv4VOtcvV/AM43o9Oc7JnHi rEtTERLQp4d5GWo9epYxZzAVTPgX68ry X-Google-Smtp-Source: ABdhPJzAD1uSMi8YsJUXosEwObWwUYm3gLkL2OePseWoq7hMzwl7e09jXvL5kdWYzQA3fZ+qcwlvKA== X-Received: by 2002:a37:a9c4:0:b0:6a6:8992:e400 with SMTP id s187-20020a37a9c4000000b006a68992e400mr8916475qke.494.1654371052650; Sat, 04 Jun 2022 12:30:52 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.30.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:30:52 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 02/33] lib/string_helpers: Convert string_escape_mem() to printbuf Date: Sat, 4 Jun 2022 15:30:11 -0400 Message-Id: <20220604193042.1674951-3-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Like the upcoming vsprintf.c conversion, this converts string_escape_mem to prt_escaped_string(), which uses and outputs to a printbuf, and makes string_escape_mem() a smaller wrapper to support existing users. The new printbuf helpers greatly simplify the code. Signed-off-by: Kent Overstreet --- include/linux/string_helpers.h | 4 + lib/string_helpers.c | 134 +++++++++++---------------------- 2 files changed, 49 insertions(+), 89 deletions(-) diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h index 4d72258d42..67de398944 100644 --- a/include/linux/string_helpers.h +++ b/include/linux/string_helpers.h @@ -10,6 +10,7 @@ struct device; struct file; struct task_struct; +struct printbuf; =20 /* Descriptions of the types of units to * print in */ @@ -62,6 +63,8 @@ static inline int string_unescape_any_inplace(char *buf) =20 #define ESCAPE_ALL_MASK GENMASK(8, 0) =20 +void prt_escaped_string(struct printbuf *out, const char *src, size_t isz, + unsigned int flags, const char *only); int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz, unsigned int flags, const char *only); =20 @@ -71,6 +74,7 @@ static inline int string_escape_mem_any_np(const char *sr= c, size_t isz, return string_escape_mem(src, isz, dst, osz, ESCAPE_ANY_NP, only); } =20 + static inline int string_escape_str(const char *src, char *dst, size_t sz, unsigned int flags, const char *only) { diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 4f877e9551..3b1118337e 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -301,19 +302,14 @@ int string_unescape(char *src, char *dst, size_t size= , unsigned int flags) } EXPORT_SYMBOL(string_unescape); =20 -static bool escape_passthrough(unsigned char c, char **dst, char *end) +static bool escape_passthrough(struct printbuf *out, unsigned char c) { - char *out =3D *dst; - - if (out < end) - *out =3D c; - *dst =3D out + 1; + prt_char(out, c); return true; } =20 -static bool escape_space(unsigned char c, char **dst, char *end) +static bool escape_space(struct printbuf *out, unsigned char c) { - char *out =3D *dst; unsigned char to; =20 switch (c) { @@ -336,20 +332,13 @@ static bool escape_space(unsigned char c, char **dst,= char *end) return false; } =20 - if (out < end) - *out =3D '\\'; - ++out; - if (out < end) - *out =3D to; - ++out; - - *dst =3D out; + prt_char(out, '\\'); + prt_char(out, to); return true; } =20 -static bool escape_special(unsigned char c, char **dst, char *end) +static bool escape_special(struct printbuf *out, unsigned char c) { - char *out =3D *dst; unsigned char to; =20 switch (c) { @@ -369,83 +358,43 @@ static bool escape_special(unsigned char c, char **ds= t, char *end) return false; } =20 - if (out < end) - *out =3D '\\'; - ++out; - if (out < end) - *out =3D to; - ++out; - - *dst =3D out; + prt_char(out, '\\'); + prt_char(out, to); return true; } =20 -static bool escape_null(unsigned char c, char **dst, char *end) +static bool escape_null(struct printbuf *out, unsigned char c) { - char *out =3D *dst; - if (c) return false; =20 - if (out < end) - *out =3D '\\'; - ++out; - if (out < end) - *out =3D '0'; - ++out; - - *dst =3D out; + prt_char(out, '\\'); + prt_char(out, '0'); return true; } =20 -static bool escape_octal(unsigned char c, char **dst, char *end) +static bool escape_octal(struct printbuf *out, unsigned char c) { - char *out =3D *dst; - - if (out < end) - *out =3D '\\'; - ++out; - if (out < end) - *out =3D ((c >> 6) & 0x07) + '0'; - ++out; - if (out < end) - *out =3D ((c >> 3) & 0x07) + '0'; - ++out; - if (out < end) - *out =3D ((c >> 0) & 0x07) + '0'; - ++out; - - *dst =3D out; + prt_char(out, '\\'); + prt_char(out, ((c >> 6) & 0x07) + '0'); + prt_char(out, ((c >> 3) & 0x07) + '0'); + prt_char(out, ((c >> 0) & 0x07) + '0'); return true; } =20 -static bool escape_hex(unsigned char c, char **dst, char *end) +static bool escape_hex(struct printbuf *out, unsigned char c) { - char *out =3D *dst; - - if (out < end) - *out =3D '\\'; - ++out; - if (out < end) - *out =3D 'x'; - ++out; - if (out < end) - *out =3D hex_asc_hi(c); - ++out; - if (out < end) - *out =3D hex_asc_lo(c); - ++out; - - *dst =3D out; + prt_char(out, '\\'); + prt_char(out, 'x'); + prt_hex_byte(out, c); return true; } =20 /** - * string_escape_mem - quote characters in the given memory buffer + * prt_escaped_string - quote characters in the given memory buffer + * @out: printbuf to output to (escaped) * @src: source buffer (unescaped) * @isz: source buffer size - * @dst: destination buffer (escaped) - * @osz: destination buffer size * @flags: combination of the flags * @only: NULL-terminated string containing characters used to limit * the selected escape class. If characters are included in @only @@ -517,11 +466,10 @@ static bool escape_hex(unsigned char c, char **dst, c= har *end) * truncated, compare the return value to osz. There is room left in * dst for a '\0' terminator if and only if ret < osz. */ -int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz, - unsigned int flags, const char *only) +void prt_escaped_string(struct printbuf *out, + const char *src, size_t isz, + unsigned int flags, const char *only) { - char *p =3D dst; - char *end =3D p + osz; bool is_dict =3D only && *only; bool is_append =3D flags & ESCAPE_APPEND; =20 @@ -549,41 +497,49 @@ int string_escape_mem(const char *src, size_t isz, ch= ar *dst, size_t osz, * %ESCAPE_NA cases. */ if (!(is_append || in_dict) && is_dict && - escape_passthrough(c, &p, end)) + escape_passthrough(out, c)) continue; =20 if (!(is_append && in_dict) && isascii(c) && isprint(c) && - flags & ESCAPE_NAP && escape_passthrough(c, &p, end)) + flags & ESCAPE_NAP && escape_passthrough(out, c)) continue; =20 if (!(is_append && in_dict) && isprint(c) && - flags & ESCAPE_NP && escape_passthrough(c, &p, end)) + flags & ESCAPE_NP && escape_passthrough(out, c)) continue; =20 if (!(is_append && in_dict) && isascii(c) && - flags & ESCAPE_NA && escape_passthrough(c, &p, end)) + flags & ESCAPE_NA && escape_passthrough(out, c)) continue; =20 - if (flags & ESCAPE_SPACE && escape_space(c, &p, end)) + if (flags & ESCAPE_SPACE && escape_space(out, c)) continue; =20 - if (flags & ESCAPE_SPECIAL && escape_special(c, &p, end)) + if (flags & ESCAPE_SPECIAL && escape_special(out, c)) continue; =20 - if (flags & ESCAPE_NULL && escape_null(c, &p, end)) + if (flags & ESCAPE_NULL && escape_null(out, c)) continue; =20 /* ESCAPE_OCTAL and ESCAPE_HEX always go last */ - if (flags & ESCAPE_OCTAL && escape_octal(c, &p, end)) + if (flags & ESCAPE_OCTAL && escape_octal(out, c)) continue; =20 - if (flags & ESCAPE_HEX && escape_hex(c, &p, end)) + if (flags & ESCAPE_HEX && escape_hex(out, c)) continue; =20 - escape_passthrough(c, &p, end); + escape_passthrough(out, c); } +} +EXPORT_SYMBOL(prt_escaped_string); + +int string_escape_mem(const char *src, size_t isz, char *dst, size_t osz, + unsigned int flags, const char *only) +{ + struct printbuf out =3D PRINTBUF_EXTERN(dst, osz); =20 - return p - dst; + prt_escaped_string(&out, src, isz, flags, only); + return out.pos; } EXPORT_SYMBOL(string_escape_mem); =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id AC2E3C43334 for ; Sat, 4 Jun 2022 19:31:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240119AbiFDTbR (ORCPT ); Sat, 4 Jun 2022 15:31:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47032 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239950AbiFDTbE (ORCPT ); Sat, 4 Jun 2022 15:31:04 -0400 Received: from mail-qk1-x72e.google.com (mail-qk1-x72e.google.com [IPv6:2607:f8b0:4864:20::72e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DB3C730547 for ; Sat, 4 Jun 2022 12:30:56 -0700 (PDT) Received: by mail-qk1-x72e.google.com with SMTP id c144so5882473qkg.11 for ; Sat, 04 Jun 2022 12:30:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UkPAS4liYvOTlrN2mCbMGX2bGNI539krqD2I4TdcYXI=; b=hJlOvU8jWaa+06x1j/0qIRFssme1h9Q3dE+p3/hRTcGNGSHYuFOK6l3Naqa8t2nvLd J/PHLD7GMncs8KUeLk5jPmwZ56gGdOGV4Ugdh3RnV2uJ2QPYcMYDafSpQiIch6tLEELK 9cLZNAxyTa0F5gfR9WNu/HtStPGvf3DtzZ69qAomorxD/tgOhI2twlWOurcnJrMlsS2y 4FnPsv6+9XH5gTngi66Ba1TyDZqrQGoO2yd4Wmg4OWg7LCZecU9JeWxkLJrMV30CHXnb qUTmCKAqoX1LVAWJrNx+3jPh24Wdy0hDQuAbONI5TKidB9GMIdJ94dX+xEg2ybKJ6lA4 uxlQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UkPAS4liYvOTlrN2mCbMGX2bGNI539krqD2I4TdcYXI=; b=jqYr2E/Z0LeCBkEa/DxVtVTxXuZBiiN6/CziQY7BIQZF0f/cEuhMoqawu3qexMJ4cw VTWAyfwC7+W+AorHZoi1dGnY7gpZMVJ60u3QEhqJuZ0h8K9MdNORMa9kAIvk6+mw/fn9 QcxM17qCC9yoAZdYLO1HwNKKnvYLrEbnpBfWpuHz8laoDDh0P7kKKU100vfc2iqbwC0v KRjbtT/MvnM4utye3/DVH+w+kNBETCNuIq8cdg9l2RuD1bNoe+LFBUcdCM8f5GLwYhnC YORa1VRJpeG1gHabNSBwktDfjO9FtwDzfVpFGClzWhRUWnopA6jcejWet1zFPasqLQD6 R35g== X-Gm-Message-State: AOAM5310rTdfWQTxW2irOzQYHZJiziE8hKKsL8EJOZXtLmXweVEjJfQz 6gVv436b1SzA0JuZJzkKFPpxGWH4LD/f X-Google-Smtp-Source: ABdhPJxZJlSDtjelxbjtpFmx79UGsutzCbAbuhfuIrPWLOdYLNkk4Mi7PsBq5xxLkSNAYmK8rJOzvw== X-Received: by 2002:a05:620a:4084:b0:6a0:4561:399f with SMTP id f4-20020a05620a408400b006a04561399fmr11049675qko.569.1654371054362; Sat, 04 Jun 2022 12:30:54 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.30.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:30:53 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 03/33] vsprintf: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:12 -0400 Message-Id: <20220604193042.1674951-4-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts vsnprintf() to printbufs: instead of passing around raw char * pointers for current buf position and end of buf, we have a real type! This makes the calling convention for our existing pretty printers a lot saner and less error prone, plus printbufs add some new helpers that make the code smaller and more readable, with a lot less crazy pointer arithmetic. There are a lot more refactorings to be done: this patch tries to stick to just converting the calling conventions, as that needs to be done all at once in order to avoid introducing a ton of wrappers that will just be deleted. Thankfully we have good unit tests for printf, and they have been run and are all passing with this patch. We have two new exported functions with this patch: - prt_printf(), which is like snprintf but outputs to a printbuf - prt_vprintf, like vsnprintf These are the actual core print routines now - vsnprintf() is a wrapper around prt_vprintf(). Signed-off-by: Kent Overstreet --- include/linux/kernel.h | 4 + include/linux/string.h | 5 + lib/vsprintf.c | 1362 +++++++++++++++++++--------------------- 3 files changed, 640 insertions(+), 731 deletions(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index fe6efb24d1..5c4f4b6d36 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -207,6 +207,10 @@ extern int num_to_str(char *buf, int size, =20 /* lib/printf utilities */ =20 +struct printbuf; +extern __printf(2, 3) void prt_printf(struct printbuf *out, const char *fm= t, ...); +extern __printf(2, 0) void prt_vprintf(struct printbuf *out, const char *f= mt, va_list); + extern __printf(2, 3) int sprintf(char *buf, const char * fmt, ...); extern __printf(2, 0) int vsprintf(char *buf, const char *, va_list); extern __printf(3, 4) diff --git a/include/linux/string.h b/include/linux/string.h index b6572aeca2..0a737d5b92 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -195,7 +195,12 @@ int __sysfs_match_string(const char * const *array, si= ze_t n, const char *s); */ #define sysfs_match_string(_a, _s) __sysfs_match_string(_a, ARRAY_SIZE(_a)= , _s) =20 +struct printbuf; + #ifdef CONFIG_BINARY_PRINTF +void prt_vbinprintf(struct printbuf *out, const char *fmt, va_list args); +void prt_bstrprintf(struct printbuf *out, const char *fmt, const u32 *bin_= buf); +void prt_bprintf(struct printbuf *out, const char *fmt, ...) __printf(2, 3= ); int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args); int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_bu= f); int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4= ); diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 40d26a07a1..b686dafb2f 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -44,6 +44,7 @@ #ifdef CONFIG_BLOCK #include #endif +#include =20 #include "../mm/internal.h" /* For the trace_print_flags arrays */ =20 @@ -451,8 +452,8 @@ static_assert(sizeof(struct printf_spec) =3D=3D 8); #define PRECISION_MAX ((1 << 15) - 1) =20 static noinline_for_stack -char *number(char *buf, char *end, unsigned long long num, - struct printf_spec spec) +void number(struct printbuf *out, unsigned long long num, + struct printf_spec spec) { /* put_dec requires 2-byte alignment of the buffer. */ char tmp[3 * sizeof(num)] __aligned(2); @@ -512,67 +513,42 @@ char *number(char *buf, char *end, unsigned long long= num, if (i > precision) precision =3D i; /* leading space padding */ - field_width -=3D precision; + field_width =3D max(0, field_width - precision); if (!(spec.flags & (ZEROPAD | LEFT))) { - while (--field_width >=3D 0) { - if (buf < end) - *buf =3D ' '; - ++buf; - } + __prt_chars(out, ' ', field_width); + field_width =3D 0; } /* sign */ - if (sign) { - if (buf < end) - *buf =3D sign; - ++buf; - } + if (sign) + __prt_char(out, sign); /* "0x" / "0" prefix */ if (need_pfx) { - if (spec.base =3D=3D 16 || !is_zero) { - if (buf < end) - *buf =3D '0'; - ++buf; - } - if (spec.base =3D=3D 16) { - if (buf < end) - *buf =3D ('X' | locase); - ++buf; - } + if (spec.base =3D=3D 16 || !is_zero) + __prt_char(out, '0'); + if (spec.base =3D=3D 16) + __prt_char(out, 'X' | locase); } /* zero or space padding */ if (!(spec.flags & LEFT)) { char c =3D ' ' + (spec.flags & ZEROPAD); =20 - while (--field_width >=3D 0) { - if (buf < end) - *buf =3D c; - ++buf; - } + __prt_chars(out, c, field_width); + field_width =3D 0; } /* hmm even more zero padding? */ - while (i <=3D --precision) { - if (buf < end) - *buf =3D '0'; - ++buf; - } + if (precision > i) + __prt_chars(out, '0', precision - i); /* actual digits of result */ - while (--i >=3D 0) { - if (buf < end) - *buf =3D tmp[i]; - ++buf; - } + while (--i >=3D 0) + __prt_char(out, tmp[i]); /* trailing space padding */ - while (--field_width >=3D 0) { - if (buf < end) - *buf =3D ' '; - ++buf; - } + __prt_chars(out, ' ', field_width); =20 - return buf; + printbuf_nul_terminate(out); } =20 static noinline_for_stack -char *special_hex_number(char *buf, char *end, unsigned long long num, int= size) +void special_hex_number(struct printbuf *out, unsigned long long num, int = size) { struct printf_spec spec; =20 @@ -582,25 +558,28 @@ char *special_hex_number(char *buf, char *end, unsign= ed long long num, int size) spec.base =3D 16; spec.precision =3D -1; =20 - return number(buf, end, num, spec); + number(out, num, spec); } =20 -static void move_right(char *buf, char *end, unsigned len, unsigned spaces) +/* + * inserts @spaces spaces @len from the end of @out + */ +static void move_right(struct printbuf *out, + unsigned len, unsigned spaces) { - size_t size; - if (buf >=3D end) /* nowhere to put anything */ - return; - size =3D end - buf; - if (size <=3D spaces) { - memset(buf, ' ', size); - return; - } - if (len) { - if (len > size - spaces) - len =3D size - spaces; - memmove(buf + spaces, buf, len); - } - memset(buf, ' ', spaces); + unsigned move_src =3D out->pos - len; + unsigned move_dst =3D move_src + spaces; + unsigned remaining_from_dst =3D move_dst < out->size ? out->size - move_d= st : 0; + unsigned remaining_from_src =3D move_src < out->size ? out->size - move_s= rc : 0; + + BUG_ON(len > out->pos); + + memmove(out->buf + move_dst, + out->buf + move_src, + min(remaining_from_dst, len)); + memset(out->buf + move_src, ' ', + min(remaining_from_src, spaces)); + out->pos +=3D spaces; } =20 /* @@ -612,67 +591,55 @@ static void move_right(char *buf, char *end, unsigned= len, unsigned spaces) * Returns: new buffer position after padding. */ static noinline_for_stack -char *widen_string(char *buf, int n, char *end, struct printf_spec spec) +void widen_string(struct printbuf *out, int n, + struct printf_spec spec) { unsigned spaces; =20 if (likely(n >=3D spec.field_width)) - return buf; + return; /* we want to pad the sucker */ spaces =3D spec.field_width - n; - if (!(spec.flags & LEFT)) { - move_right(buf - n, end, n, spaces); - return buf + spaces; - } - while (spaces--) { - if (buf < end) - *buf =3D ' '; - ++buf; - } - return buf; + if (!(spec.flags & LEFT)) + move_right(out, n, spaces); + else + prt_chars(out, ' ', spaces); } =20 /* Handle string from a well known address. */ -static char *string_nocheck(char *buf, char *end, const char *s, - struct printf_spec spec) +static void string_nocheck(struct printbuf *out, + const char *s, + struct printf_spec spec) { - int len =3D 0; - int lim =3D spec.precision; + int len =3D min_t(unsigned, strlen(s), spec.precision); =20 - while (lim--) { - char c =3D *s++; - if (!c) - break; - if (buf < end) - *buf =3D c; - ++buf; - ++len; - } - return widen_string(buf, len, end, spec); + prt_bytes(out, s, len); + widen_string(out, len, spec); } =20 -static char *err_ptr(char *buf, char *end, void *ptr, - struct printf_spec spec) +static void err_ptr(struct printbuf *out, void *ptr, + struct printf_spec spec) { int err =3D PTR_ERR(ptr); const char *sym =3D errname(err); =20 - if (sym) - return string_nocheck(buf, end, sym, spec); - - /* - * Somebody passed ERR_PTR(-1234) or some other non-existing - * Efoo - or perhaps CONFIG_SYMBOLIC_ERRNAME=3Dn. Fall back to - * printing it as its decimal representation. - */ - spec.flags |=3D SIGN; - spec.base =3D 10; - return number(buf, end, err, spec); + if (sym) { + string_nocheck(out, sym, spec); + } else { + /* + * Somebody passed ERR_PTR(-1234) or some other non-existing + * Efoo - or perhaps CONFIG_SYMBOLIC_ERRNAME=3Dn. Fall back to + * printing it as its decimal representation. + */ + spec.flags |=3D SIGN; + spec.base =3D 10; + number(out, err, spec); + } } =20 /* Be careful: error messages must fit into the given buffer. */ -static char *error_string(char *buf, char *end, const char *s, - struct printf_spec spec) +static void error_string(struct printbuf *out, const char *s, + struct printf_spec spec) { /* * Hard limit to avoid a completely insane messages. It actually @@ -682,7 +649,7 @@ static char *error_string(char *buf, char *end, const c= har *s, if (spec.precision =3D=3D -1) spec.precision =3D 2 * sizeof(void *); =20 - return string_nocheck(buf, end, s, spec); + string_nocheck(out, s, spec); } =20 /* @@ -701,14 +668,15 @@ static const char *check_pointer_msg(const void *ptr) return NULL; } =20 -static int check_pointer(char **buf, char *end, const void *ptr, +static int check_pointer(struct printbuf *out, + const void *ptr, struct printf_spec spec) { const char *err_msg; =20 err_msg =3D check_pointer_msg(ptr); if (err_msg) { - *buf =3D error_string(*buf, end, err_msg, spec); + error_string(out, err_msg, spec); return -EFAULT; } =20 @@ -716,18 +684,19 @@ static int check_pointer(char **buf, char *end, const= void *ptr, } =20 static noinline_for_stack -char *string(char *buf, char *end, const char *s, - struct printf_spec spec) +void string(struct printbuf *out, + const char *s, + struct printf_spec spec) { - if (check_pointer(&buf, end, s, spec)) - return buf; + if (check_pointer(out, s, spec)) + return; =20 - return string_nocheck(buf, end, s, spec); + string_nocheck(out, s, spec); } =20 -static char *pointer_string(char *buf, char *end, - const void *ptr, - struct printf_spec spec) +static void pointer_string(struct printbuf *out, + const void *ptr, + struct printf_spec spec) { spec.base =3D 16; spec.flags |=3D SMALL; @@ -736,7 +705,7 @@ static char *pointer_string(char *buf, char *end, spec.flags |=3D ZEROPAD; } =20 - return number(buf, end, (unsigned long int)ptr, spec); + number(out, (unsigned long int)ptr, spec); } =20 /* Make pointers available for printing early in the boot sequence. */ @@ -825,8 +794,9 @@ int ptr_to_hashval(const void *ptr, unsigned long *hash= val_out) return __ptr_to_hashval(ptr, hashval_out); } =20 -static char *ptr_to_id(char *buf, char *end, const void *ptr, - struct printf_spec spec) +static void ptr_to_id(struct printbuf *out, + const void *ptr, + struct printf_spec spec) { const char *str =3D sizeof(ptr) =3D=3D 8 ? "(____ptrval____)" : "(ptrval)= "; unsigned long hashval; @@ -837,47 +807,49 @@ static char *ptr_to_id(char *buf, char *end, const vo= id *ptr, * as they are not actual addresses. */ if (IS_ERR_OR_NULL(ptr)) - return pointer_string(buf, end, ptr, spec); + return pointer_string(out, ptr, spec); =20 /* When debugging early boot use non-cryptographically secure hash. */ if (unlikely(debug_boot_weak_hash)) { hashval =3D hash_long((unsigned long)ptr, 32); - return pointer_string(buf, end, (const void *)hashval, spec); + return pointer_string(out, (const void *)hashval, spec); } =20 ret =3D __ptr_to_hashval(ptr, &hashval); if (ret) { spec.field_width =3D 2 * sizeof(ptr); /* string length must be less than default_width */ - return error_string(buf, end, str, spec); + return error_string(out, str, spec); } =20 - return pointer_string(buf, end, (const void *)hashval, spec); + pointer_string(out, (const void *)hashval, spec); } =20 -static char *default_pointer(char *buf, char *end, const void *ptr, - struct printf_spec spec) +static void default_pointer(struct printbuf *out, + const void *ptr, + struct printf_spec spec) { /* * default is to _not_ leak addresses, so hash before printing, * unless no_hash_pointers is specified on the command line. */ if (unlikely(no_hash_pointers)) - return pointer_string(buf, end, ptr, spec); + return pointer_string(out, ptr, spec); =20 - return ptr_to_id(buf, end, ptr, spec); + return ptr_to_id(out, ptr, spec); } =20 int kptr_restrict __read_mostly; =20 static noinline_for_stack -char *restricted_pointer(char *buf, char *end, const void *ptr, - struct printf_spec spec) +void restricted_pointer(struct printbuf *out, + const void *ptr, + struct printf_spec spec) { switch (kptr_restrict) { case 0: /* Handle as %p, hash and do _not_ leak addresses. */ - return default_pointer(buf, end, ptr, spec); + return default_pointer(out, ptr, spec); case 1: { const struct cred *cred; =20 @@ -888,7 +860,7 @@ char *restricted_pointer(char *buf, char *end, const vo= id *ptr, if (in_irq() || in_serving_softirq() || in_nmi()) { if (spec.field_width =3D=3D -1) spec.field_width =3D 2 * sizeof(ptr); - return error_string(buf, end, "pK-error", spec); + return error_string(out, "pK-error", spec); } =20 /* @@ -914,12 +886,13 @@ char *restricted_pointer(char *buf, char *end, const = void *ptr, break; } =20 - return pointer_string(buf, end, ptr, spec); + return pointer_string(out, ptr, spec); } =20 static noinline_for_stack -char *dentry_name(char *buf, char *end, const struct dentry *d, struct pri= ntf_spec spec, - const char *fmt) +void dentry_name(struct printbuf *out, + const struct dentry *d, struct printf_spec spec, + const char *fmt) { const char *array[4], *s; const struct dentry *p; @@ -936,9 +909,9 @@ char *dentry_name(char *buf, char *end, const struct de= ntry *d, struct printf_sp =20 rcu_read_lock(); for (i =3D 0; i < depth; i++, d =3D p) { - if (check_pointer(&buf, end, d, spec)) { + if (check_pointer(out, d, spec)) { rcu_read_unlock(); - return buf; + return; } =20 p =3D READ_ONCE(d->d_parent); @@ -951,7 +924,7 @@ char *dentry_name(char *buf, char *end, const struct de= ntry *d, struct printf_sp } } s =3D array[--i]; - for (n =3D 0; n !=3D spec.precision; n++, buf++) { + for (n =3D 0; n !=3D spec.precision; n++) { char c =3D *s++; if (!c) { if (!i) @@ -959,49 +932,47 @@ char *dentry_name(char *buf, char *end, const struct = dentry *d, struct printf_sp c =3D '/'; s =3D array[--i]; } - if (buf < end) - *buf =3D c; + prt_char(out, c); } rcu_read_unlock(); - return widen_string(buf, n, end, spec); + + widen_string(out, n, spec); } =20 static noinline_for_stack -char *file_dentry_name(char *buf, char *end, const struct file *f, - struct printf_spec spec, const char *fmt) +void file_dentry_name(struct printbuf *out, + const struct file *f, + struct printf_spec spec, const char *fmt) { - if (check_pointer(&buf, end, f, spec)) - return buf; + if (check_pointer(out, f, spec)) + return; =20 - return dentry_name(buf, end, f->f_path.dentry, spec, fmt); + return dentry_name(out, f->f_path.dentry, spec, fmt); } #ifdef CONFIG_BLOCK static noinline_for_stack -char *bdev_name(char *buf, char *end, struct block_device *bdev, - struct printf_spec spec, const char *fmt) +void bdev_name(struct printbuf *out, + struct block_device *bdev, + struct printf_spec spec, const char *fmt) { struct gendisk *hd; =20 - if (check_pointer(&buf, end, bdev, spec)) - return buf; + if (check_pointer(out, bdev, spec)) + return; =20 hd =3D bdev->bd_disk; - buf =3D string(buf, end, hd->disk_name, spec); + string(out, hd->disk_name, spec); if (bdev->bd_partno) { - if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) { - if (buf < end) - *buf =3D 'p'; - buf++; - } - buf =3D number(buf, end, bdev->bd_partno, spec); + if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) + prt_char(out, 'p'); + number(out, bdev->bd_partno, spec); } - return buf; } #endif =20 static noinline_for_stack -char *symbol_string(char *buf, char *end, void *ptr, - struct printf_spec spec, const char *fmt) +void symbol_string(struct printbuf *out, void *ptr, + struct printf_spec spec, const char *fmt) { unsigned long value; #ifdef CONFIG_KALLSYMS @@ -1024,9 +995,9 @@ char *symbol_string(char *buf, char *end, void *ptr, else sprint_symbol_no_offset(sym, value); =20 - return string_nocheck(buf, end, sym, spec); + string_nocheck(out, sym, spec); #else - return special_hex_number(buf, end, value, sizeof(void *)); + special_hex_number(out, value, sizeof(void *)); #endif } =20 @@ -1061,8 +1032,8 @@ static const struct printf_spec default_dec04_spec = =3D { }; =20 static noinline_for_stack -char *resource_string(char *buf, char *end, struct resource *res, - struct printf_spec spec, const char *fmt) +void resource_string(struct printbuf *out, struct resource *res, + struct printf_spec spec, const char *fmt) { #ifndef IO_RSRC_PRINTK_SIZE #define IO_RSRC_PRINTK_SIZE 6 @@ -1101,69 +1072,67 @@ char *resource_string(char *buf, char *end, struct = resource *res, #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]") #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") - char sym[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, + char sym_buf[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; - - char *p =3D sym, *pend =3D sym + sizeof(sym); + struct printbuf sym =3D PRINTBUF_EXTERN(sym_buf, sizeof(sym_buf)); int decode =3D (fmt[0] =3D=3D 'R') ? 1 : 0; const struct printf_spec *specp; =20 - if (check_pointer(&buf, end, res, spec)) - return buf; + if (check_pointer(out, res, spec)) + return; =20 - *p++ =3D '['; + prt_char(&sym, '['); if (res->flags & IORESOURCE_IO) { - p =3D string_nocheck(p, pend, "io ", str_spec); + string_nocheck(&sym, "io ", str_spec); specp =3D &io_spec; } else if (res->flags & IORESOURCE_MEM) { - p =3D string_nocheck(p, pend, "mem ", str_spec); + string_nocheck(&sym, "mem ", str_spec); specp =3D &mem_spec; } else if (res->flags & IORESOURCE_IRQ) { - p =3D string_nocheck(p, pend, "irq ", str_spec); + string_nocheck(&sym, "irq ", str_spec); specp =3D &default_dec_spec; } else if (res->flags & IORESOURCE_DMA) { - p =3D string_nocheck(p, pend, "dma ", str_spec); + string_nocheck(&sym, "dma ", str_spec); specp =3D &default_dec_spec; } else if (res->flags & IORESOURCE_BUS) { - p =3D string_nocheck(p, pend, "bus ", str_spec); + string_nocheck(&sym, "bus ", str_spec); specp =3D &bus_spec; } else { - p =3D string_nocheck(p, pend, "??? ", str_spec); + string_nocheck(&sym, "??? ", str_spec); specp =3D &mem_spec; decode =3D 0; } if (decode && res->flags & IORESOURCE_UNSET) { - p =3D string_nocheck(p, pend, "size ", str_spec); - p =3D number(p, pend, resource_size(res), *specp); + string_nocheck(&sym, "size ", str_spec); + number(&sym, resource_size(res), *specp); } else { - p =3D number(p, pend, res->start, *specp); + number(&sym, res->start, *specp); if (res->start !=3D res->end) { - *p++ =3D '-'; - p =3D number(p, pend, res->end, *specp); + prt_char(&sym, '-'); + number(&sym, res->end, *specp); } } if (decode) { if (res->flags & IORESOURCE_MEM_64) - p =3D string_nocheck(p, pend, " 64bit", str_spec); + string_nocheck(&sym, " 64bit", str_spec); if (res->flags & IORESOURCE_PREFETCH) - p =3D string_nocheck(p, pend, " pref", str_spec); + string_nocheck(&sym, " pref", str_spec); if (res->flags & IORESOURCE_WINDOW) - p =3D string_nocheck(p, pend, " window", str_spec); + string_nocheck(&sym, " window", str_spec); if (res->flags & IORESOURCE_DISABLED) - p =3D string_nocheck(p, pend, " disabled", str_spec); + string_nocheck(&sym, " disabled", str_spec); } else { - p =3D string_nocheck(p, pend, " flags ", str_spec); - p =3D number(p, pend, res->flags, default_flag_spec); + string_nocheck(&sym, " flags ", str_spec); + number(&sym, res->flags, default_flag_spec); } - *p++ =3D ']'; - *p =3D '\0'; + prt_char(&sym, ']'); =20 - return string_nocheck(buf, end, sym, spec); + string_nocheck(out, sym_buf, spec); } =20 static noinline_for_stack -char *hex_string(char *buf, char *end, u8 *addr, struct printf_spec spec, - const char *fmt) +void hex_string(struct printbuf *out, u8 *addr, + struct printf_spec spec, const char *fmt) { int i, len =3D 1; /* if we pass '%ph[CDN]', field width remains negative value, fallback to the default */ @@ -1171,10 +1140,10 @@ char *hex_string(char *buf, char *end, u8 *addr, st= ruct printf_spec spec, =20 if (spec.field_width =3D=3D 0) /* nothing to print */ - return buf; + return; =20 - if (check_pointer(&buf, end, addr, spec)) - return buf; + if (check_pointer(out, addr, spec)) + return; =20 switch (fmt[1]) { case 'C': @@ -1195,34 +1164,27 @@ char *hex_string(char *buf, char *end, u8 *addr, st= ruct printf_spec spec, len =3D min_t(int, spec.field_width, 64); =20 for (i =3D 0; i < len; ++i) { - if (buf < end) - *buf =3D hex_asc_hi(addr[i]); - ++buf; - if (buf < end) - *buf =3D hex_asc_lo(addr[i]); - ++buf; - - if (separator && i !=3D len - 1) { - if (buf < end) - *buf =3D separator; - ++buf; - } + __prt_char(out, hex_asc_hi(addr[i])); + __prt_char(out, hex_asc_lo(addr[i])); + + if (separator && i !=3D len - 1) + __prt_char(out, separator); } =20 - return buf; + printbuf_nul_terminate(out); } =20 static noinline_for_stack -char *bitmap_string(char *buf, char *end, unsigned long *bitmap, - struct printf_spec spec, const char *fmt) +void bitmap_string(struct printbuf *out, unsigned long *bitmap, + struct printf_spec spec, const char *fmt) { const int CHUNKSZ =3D 32; int nr_bits =3D max_t(int, spec.field_width, 0); int i, chunksz; bool first =3D true; =20 - if (check_pointer(&buf, end, bitmap, spec)) - return buf; + if (check_pointer(out, bitmap, spec)) + return; =20 /* reused to print numbers */ spec =3D (struct printf_spec){ .flags =3D SMALL | ZEROPAD, .base =3D 16 }; @@ -1241,54 +1203,45 @@ char *bitmap_string(char *buf, char *end, unsigned = long *bitmap, bit =3D i % BITS_PER_LONG; val =3D (bitmap[word] >> bit) & chunkmask; =20 - if (!first) { - if (buf < end) - *buf =3D ','; - buf++; - } + if (!first) + prt_char(out, ','); first =3D false; =20 spec.field_width =3D DIV_ROUND_UP(chunksz, 4); - buf =3D number(buf, end, val, spec); + number(out, val, spec); =20 chunksz =3D CHUNKSZ; } - return buf; } =20 static noinline_for_stack -char *bitmap_list_string(char *buf, char *end, unsigned long *bitmap, - struct printf_spec spec, const char *fmt) +void bitmap_list_string(struct printbuf *out, unsigned long *bitmap, + struct printf_spec spec, const char *fmt) { int nr_bits =3D max_t(int, spec.field_width, 0); bool first =3D true; int rbot, rtop; =20 - if (check_pointer(&buf, end, bitmap, spec)) - return buf; + if (check_pointer(out, bitmap, spec)) + return ; =20 for_each_set_bitrange(rbot, rtop, bitmap, nr_bits) { - if (!first) { - if (buf < end) - *buf =3D ','; - buf++; - } + if (!first) + prt_char(out, ','); first =3D false; =20 - buf =3D number(buf, end, rbot, default_dec_spec); + number(out, rbot, default_dec_spec); if (rtop =3D=3D rbot + 1) continue; =20 - if (buf < end) - *buf =3D '-'; - buf =3D number(++buf, end, rtop - 1, default_dec_spec); + prt_char(out, '-'); + number(out, rtop - 1, default_dec_spec); } - return buf; } =20 static noinline_for_stack -char *mac_address_string(char *buf, char *end, u8 *addr, - struct printf_spec spec, const char *fmt) +void mac_address_string(struct printbuf *out, u8 *addr, + struct printf_spec spec, const char *fmt) { char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")]; char *p =3D mac_addr; @@ -1296,8 +1249,8 @@ char *mac_address_string(char *buf, char *end, u8 *ad= dr, char separator; bool reversed =3D false; =20 - if (check_pointer(&buf, end, addr, spec)) - return buf; + if (check_pointer(out, addr, spec)) + return; =20 switch (fmt[1]) { case 'F': @@ -1324,11 +1277,12 @@ char *mac_address_string(char *buf, char *end, u8 *= addr, } *p =3D '\0'; =20 - return string_nocheck(buf, end, mac_addr, spec); + string_nocheck(out, mac_addr, spec); } =20 static noinline_for_stack -char *ip4_string(char *p, const u8 *addr, const char *fmt) +void ip4_string(struct printbuf *out, + const u8 *addr, const char *fmt) { int i; bool leading_zeros =3D (fmt[0] =3D=3D 'i'); @@ -1361,24 +1315,21 @@ char *ip4_string(char *p, const u8 *addr, const cha= r *fmt) int digits =3D put_dec_trunc8(temp, addr[index]) - temp; if (leading_zeros) { if (digits < 3) - *p++ =3D '0'; + prt_char(out, '0'); if (digits < 2) - *p++ =3D '0'; + prt_char(out, '0'); } /* reverse the digits in the quad */ while (digits--) - *p++ =3D temp[digits]; + prt_char(out, temp[digits]); if (i < 3) - *p++ =3D '.'; + prt_char(out, '.'); index +=3D step; } - *p =3D '\0'; - - return p; } =20 static noinline_for_stack -char *ip6_compressed_string(char *p, const char *addr) +void ip6_compressed_string(struct printbuf *out, const char *addr) { int i, j, range; unsigned char zerolength[8]; @@ -1422,14 +1373,14 @@ char *ip6_compressed_string(char *p, const char *ad= dr) for (i =3D 0; i < range; i++) { if (i =3D=3D colonpos) { if (needcolon || i =3D=3D 0) - *p++ =3D ':'; - *p++ =3D ':'; + __prt_char(out, ':'); + __prt_char(out, ':'); needcolon =3D false; i +=3D longest - 1; continue; } if (needcolon) { - *p++ =3D ':'; + __prt_char(out, ':'); needcolon =3D false; } /* hex u16 without leading 0s */ @@ -1438,81 +1389,79 @@ char *ip6_compressed_string(char *p, const char *ad= dr) lo =3D word & 0xff; if (hi) { if (hi > 0x0f) - p =3D hex_byte_pack(p, hi); + prt_hex_byte(out, hi); else - *p++ =3D hex_asc_lo(hi); - p =3D hex_byte_pack(p, lo); + __prt_char(out, hex_asc_lo(hi)); + prt_hex_byte(out, lo); } else if (lo > 0x0f) - p =3D hex_byte_pack(p, lo); + prt_hex_byte(out, lo); else - *p++ =3D hex_asc_lo(lo); + __prt_char(out, hex_asc_lo(lo)); needcolon =3D true; } =20 if (useIPv4) { if (needcolon) - *p++ =3D ':'; - p =3D ip4_string(p, &in6.s6_addr[12], "I4"); + __prt_char(out, ':'); + ip4_string(out, &in6.s6_addr[12], "I4"); } - *p =3D '\0'; =20 - return p; + printbuf_nul_terminate(out); } =20 static noinline_for_stack -char *ip6_string(char *p, const char *addr, const char *fmt) +void ip6_string(struct printbuf *out, const char *addr, const char *fmt) { int i; =20 for (i =3D 0; i < 8; i++) { - p =3D hex_byte_pack(p, *addr++); - p =3D hex_byte_pack(p, *addr++); + prt_hex_byte(out, *addr++); + prt_hex_byte(out, *addr++); if (fmt[0] =3D=3D 'I' && i !=3D 7) - *p++ =3D ':'; + prt_char(out, ':'); } - *p =3D '\0'; - - return p; } =20 static noinline_for_stack -char *ip6_addr_string(char *buf, char *end, const u8 *addr, - struct printf_spec spec, const char *fmt) +void ip6_addr_string(struct printbuf *out, const u8 *addr, + struct printf_spec spec, const char *fmt) { - char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")]; + char ip6_addr_buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")= ]; + struct printbuf ip6_addr =3D PRINTBUF_EXTERN(ip6_addr_buf, sizeof(ip6_add= r_buf)); =20 if (fmt[0] =3D=3D 'I' && fmt[2] =3D=3D 'c') - ip6_compressed_string(ip6_addr, addr); + ip6_compressed_string(&ip6_addr, addr); else - ip6_string(ip6_addr, addr, fmt); + ip6_string(&ip6_addr, addr, fmt); =20 - return string_nocheck(buf, end, ip6_addr, spec); + string_nocheck(out, ip6_addr_buf, spec); } =20 static noinline_for_stack -char *ip4_addr_string(char *buf, char *end, const u8 *addr, - struct printf_spec spec, const char *fmt) +void ip4_addr_string(struct printbuf *out, const u8 *addr, + struct printf_spec spec, const char *fmt) { - char ip4_addr[sizeof("255.255.255.255")]; + char ip4_addr_buf[sizeof("255.255.255.255")]; + struct printbuf ip4_addr =3D PRINTBUF_EXTERN(ip4_addr_buf, sizeof(ip4_add= r_buf)); =20 - ip4_string(ip4_addr, addr, fmt); + ip4_string(&ip4_addr, addr, fmt); =20 - return string_nocheck(buf, end, ip4_addr, spec); + string_nocheck(out, ip4_addr_buf, spec); } =20 static noinline_for_stack -char *ip6_addr_string_sa(char *buf, char *end, const struct sockaddr_in6 *= sa, - struct printf_spec spec, const char *fmt) +void ip6_addr_string_sa(struct printbuf *out, + const struct sockaddr_in6 *sa, + struct printf_spec spec, const char *fmt) { bool have_p =3D false, have_s =3D false, have_f =3D false, have_c =3D fal= se; - char ip6_addr[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]") + - sizeof(":12345") + sizeof("/123456789") + - sizeof("%1234567890")]; - char *p =3D ip6_addr, *pend =3D ip6_addr + sizeof(ip6_addr); + char ip6_addr_buf[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]= ") + + sizeof(":12345") + sizeof("/123456789") + + sizeof("%1234567890")]; + struct printbuf ip6_addr =3D PRINTBUF_EXTERN(ip6_addr_buf, sizeof(ip6_add= r_buf)); const u8 *addr =3D (const u8 *) &sa->sin6_addr; char fmt6[2] =3D { fmt[0], '6' }; - u8 off =3D 0; =20 fmt++; while (isalpha(*++fmt)) { @@ -1532,44 +1481,42 @@ char *ip6_addr_string_sa(char *buf, char *end, cons= t struct sockaddr_in6 *sa, } } =20 - if (have_p || have_s || have_f) { - *p =3D '['; - off =3D 1; - } + if (have_p || have_s || have_f) + prt_char(&ip6_addr, '['); =20 if (fmt6[0] =3D=3D 'I' && have_c) - p =3D ip6_compressed_string(ip6_addr + off, addr); + ip6_compressed_string(&ip6_addr, addr); else - p =3D ip6_string(ip6_addr + off, addr, fmt6); + ip6_string(&ip6_addr, addr, fmt6); =20 if (have_p || have_s || have_f) - *p++ =3D ']'; + prt_char(&ip6_addr, ']'); =20 if (have_p) { - *p++ =3D ':'; - p =3D number(p, pend, ntohs(sa->sin6_port), spec); + prt_char(&ip6_addr, ':'); + number(&ip6_addr, ntohs(sa->sin6_port), spec); } if (have_f) { - *p++ =3D '/'; - p =3D number(p, pend, ntohl(sa->sin6_flowinfo & - IPV6_FLOWINFO_MASK), spec); + prt_char(&ip6_addr, '/'); + number(&ip6_addr, ntohl(sa->sin6_flowinfo & + IPV6_FLOWINFO_MASK), spec); } if (have_s) { - *p++ =3D '%'; - p =3D number(p, pend, sa->sin6_scope_id, spec); + prt_char(&ip6_addr, '%'); + number(&ip6_addr, sa->sin6_scope_id, spec); } - *p =3D '\0'; =20 - return string_nocheck(buf, end, ip6_addr, spec); + string_nocheck(out, ip6_addr_buf, spec); } =20 static noinline_for_stack -char *ip4_addr_string_sa(char *buf, char *end, const struct sockaddr_in *s= a, - struct printf_spec spec, const char *fmt) +void ip4_addr_string_sa(struct printbuf *out, + const struct sockaddr_in *sa, + struct printf_spec spec, const char *fmt) { bool have_p =3D false; - char *p, ip4_addr[sizeof("255.255.255.255") + sizeof(":12345")]; - char *pend =3D ip4_addr + sizeof(ip4_addr); + char ip4_addr_buf[sizeof("255.255.255.255") + sizeof(":12345")]; + struct printbuf ip4_addr =3D PRINTBUF_EXTERN(ip4_addr_buf, sizeof(ip4_add= r_buf)); const u8 *addr =3D (const u8 *) &sa->sin_addr.s_addr; char fmt4[3] =3D { fmt[0], '4', 0 }; =20 @@ -1588,30 +1535,29 @@ char *ip4_addr_string_sa(char *buf, char *end, cons= t struct sockaddr_in *sa, } } =20 - p =3D ip4_string(ip4_addr, addr, fmt4); + ip4_string(&ip4_addr, addr, fmt4); if (have_p) { - *p++ =3D ':'; - p =3D number(p, pend, ntohs(sa->sin_port), spec); + prt_char(&ip4_addr, ':'); + number(&ip4_addr, ntohs(sa->sin_port), spec); } - *p =3D '\0'; =20 - return string_nocheck(buf, end, ip4_addr, spec); + string_nocheck(out, ip4_addr_buf, spec); } =20 static noinline_for_stack -char *ip_addr_string(char *buf, char *end, const void *ptr, - struct printf_spec spec, const char *fmt) +void ip_addr_string(struct printbuf *out, const void *ptr, + struct printf_spec spec, const char *fmt) { char *err_fmt_msg; =20 - if (check_pointer(&buf, end, ptr, spec)) - return buf; + if (check_pointer(out, ptr, spec)) + return; =20 switch (fmt[1]) { case '6': - return ip6_addr_string(buf, end, ptr, spec, fmt); + return ip6_addr_string(out, ptr, spec, fmt); case '4': - return ip4_addr_string(buf, end, ptr, spec, fmt); + return ip4_addr_string(out, ptr, spec, fmt); case 'S': { const union { struct sockaddr raw; @@ -1621,21 +1567,21 @@ char *ip_addr_string(char *buf, char *end, const vo= id *ptr, =20 switch (sa->raw.sa_family) { case AF_INET: - return ip4_addr_string_sa(buf, end, &sa->v4, spec, fmt); + return ip4_addr_string_sa(out, &sa->v4, spec, fmt); case AF_INET6: - return ip6_addr_string_sa(buf, end, &sa->v6, spec, fmt); + return ip6_addr_string_sa(out, &sa->v6, spec, fmt); default: - return error_string(buf, end, "(einval)", spec); + return error_string(out, "(einval)", spec); }} } =20 err_fmt_msg =3D fmt[0] =3D=3D 'i' ? "(%pi?)" : "(%pI?)"; - return error_string(buf, end, err_fmt_msg, spec); + return error_string(out, err_fmt_msg, spec); } =20 static noinline_for_stack -char *escaped_string(char *buf, char *end, u8 *addr, struct printf_spec sp= ec, - const char *fmt) +void escaped_string(struct printbuf *out, u8 *addr, + struct printf_spec spec, const char *fmt) { bool found =3D true; int count =3D 1; @@ -1643,10 +1589,10 @@ char *escaped_string(char *buf, char *end, u8 *addr= , struct printf_spec spec, int len; =20 if (spec.field_width =3D=3D 0) - return buf; /* nothing to print */ + return; /* nothing to print */ =20 - if (check_pointer(&buf, end, addr, spec)) - return buf; + if (check_pointer(out, addr, spec)) + return; =20 do { switch (fmt[count++]) { @@ -1681,44 +1627,35 @@ char *escaped_string(char *buf, char *end, u8 *addr= , struct printf_spec spec, flags =3D ESCAPE_ANY_NP; =20 len =3D spec.field_width < 0 ? 1 : spec.field_width; - - /* - * string_escape_mem() writes as many characters as it can to - * the given buffer, and returns the total size of the output - * had the buffer been big enough. - */ - buf +=3D string_escape_mem(addr, len, buf, buf < end ? end - buf : 0, fla= gs, NULL); - - return buf; + prt_escaped_string(out, addr, len, flags, NULL); } =20 -static char *va_format(char *buf, char *end, struct va_format *va_fmt, - struct printf_spec spec, const char *fmt) +static void va_format(struct printbuf *out, + struct va_format *va_fmt, + struct printf_spec spec, const char *fmt) { va_list va; =20 - if (check_pointer(&buf, end, va_fmt, spec)) - return buf; + if (check_pointer(out, va_fmt, spec)) + return; =20 va_copy(va, *va_fmt->va); - buf +=3D vsnprintf(buf, end > buf ? end - buf : 0, va_fmt->fmt, va); + prt_vprintf(out, va_fmt->fmt, va); va_end(va); - - return buf; } =20 static noinline_for_stack -char *uuid_string(char *buf, char *end, const u8 *addr, - struct printf_spec spec, const char *fmt) +void uuid_string(struct printbuf *out, const u8 *addr, + struct printf_spec spec, const char *fmt) { - char uuid[UUID_STRING_LEN + 1]; - char *p =3D uuid; + char uuid_buf[UUID_STRING_LEN + 1]; + struct printbuf uuid =3D PRINTBUF_EXTERN(uuid_buf, sizeof(uuid_buf)); int i; const u8 *index =3D uuid_index; bool uc =3D false; =20 - if (check_pointer(&buf, end, addr, spec)) - return buf; + if (check_pointer(out, addr, spec)) + return; =20 switch (*(++fmt)) { case 'L': @@ -1734,60 +1671,58 @@ char *uuid_string(char *buf, char *end, const u8 *a= ddr, =20 for (i =3D 0; i < 16; i++) { if (uc) - p =3D hex_byte_pack_upper(p, addr[index[i]]); + prt_hex_byte_upper(&uuid, addr[index[i]]); else - p =3D hex_byte_pack(p, addr[index[i]]); + prt_hex_byte(&uuid, addr[index[i]]); switch (i) { case 3: case 5: case 7: case 9: - *p++ =3D '-'; + prt_char(&uuid, '-'); break; } } =20 - *p =3D 0; - - return string_nocheck(buf, end, uuid, spec); + string_nocheck(out, uuid_buf, spec); } =20 static noinline_for_stack -char *netdev_bits(char *buf, char *end, const void *addr, - struct printf_spec spec, const char *fmt) +void netdev_bits(struct printbuf *out, const void *addr, + struct printf_spec spec, const char *fmt) { unsigned long long num; int size; =20 - if (check_pointer(&buf, end, addr, spec)) - return buf; + if (check_pointer(out, addr, spec)) + return; =20 switch (fmt[1]) { case 'F': num =3D *(const netdev_features_t *)addr; size =3D sizeof(netdev_features_t); + special_hex_number(out, num, size); break; default: - return error_string(buf, end, "(%pN?)", spec); + error_string(out, "(%pN?)", spec); + break; } - - return special_hex_number(buf, end, num, size); } =20 static noinline_for_stack -char *fourcc_string(char *buf, char *end, const u32 *fourcc, - struct printf_spec spec, const char *fmt) +void fourcc_string(struct printbuf *out, const u32 *fourcc, + struct printf_spec spec, const char *fmt) { - char output[sizeof("0123 little-endian (0x01234567)")]; - char *p =3D output; + char output_buf[sizeof("0123 little-endian (0x01234567)")]; + struct printbuf output =3D PRINTBUF_EXTERN(output_buf, sizeof(output_buf)= ); unsigned int i; u32 orig, val; =20 if (fmt[1] !=3D 'c' || fmt[2] !=3D 'c') - return error_string(buf, end, "(%p4?)", spec); + return error_string(out, "(%p4?)", spec); =20 - if (check_pointer(&buf, end, fourcc, spec)) - return buf; + if (check_pointer(out, fourcc, spec)) + return; =20 orig =3D get_unaligned(fourcc); val =3D orig & ~BIT(31); @@ -1796,31 +1731,29 @@ char *fourcc_string(char *buf, char *end, const u32= *fourcc, unsigned char c =3D val >> (i * 8); =20 /* Print non-control ASCII characters as-is, dot otherwise */ - *p++ =3D isascii(c) && isprint(c) ? c : '.'; + prt_char(&output, isascii(c) && isprint(c) ? c : '.'); } =20 - *p++ =3D ' '; - strcpy(p, orig & BIT(31) ? "big-endian" : "little-endian"); - p +=3D strlen(p); + prt_char(&output, ' '); + prt_str(&output, orig & BIT(31) ? "big-endian" : "little-endian"); =20 - *p++ =3D ' '; - *p++ =3D '('; - p =3D special_hex_number(p, output + sizeof(output) - 2, orig, sizeof(u32= )); - *p++ =3D ')'; - *p =3D '\0'; + prt_char(&output, ' '); + prt_char(&output, '('); + special_hex_number(&output, orig, sizeof(u32)); + prt_char(&output, ')'); =20 - return string(buf, end, output, spec); + string(out, output_buf, spec); } =20 static noinline_for_stack -char *address_val(char *buf, char *end, const void *addr, - struct printf_spec spec, const char *fmt) +void address_val(struct printbuf *out, const void *addr, + struct printf_spec spec, const char *fmt) { unsigned long long num; int size; =20 - if (check_pointer(&buf, end, addr, spec)) - return buf; + if (check_pointer(out, addr, spec)) + return; =20 switch (fmt[1]) { case 'd': @@ -1834,55 +1767,44 @@ char *address_val(char *buf, char *end, const void = *addr, break; } =20 - return special_hex_number(buf, end, num, size); + special_hex_number(out, num, size); } =20 static noinline_for_stack -char *date_str(char *buf, char *end, const struct rtc_time *tm, bool r) +void date_str(struct printbuf *out, + const struct rtc_time *tm, bool r) { int year =3D tm->tm_year + (r ? 0 : 1900); int mon =3D tm->tm_mon + (r ? 0 : 1); =20 - buf =3D number(buf, end, year, default_dec04_spec); - if (buf < end) - *buf =3D '-'; - buf++; - - buf =3D number(buf, end, mon, default_dec02_spec); - if (buf < end) - *buf =3D '-'; - buf++; - - return number(buf, end, tm->tm_mday, default_dec02_spec); + number(out, year, default_dec04_spec); + prt_char(out, '-'); + number(out, mon, default_dec02_spec); + prt_char(out, '-'); + number(out, tm->tm_mday, default_dec02_spec); } =20 static noinline_for_stack -char *time_str(char *buf, char *end, const struct rtc_time *tm, bool r) +void time_str(struct printbuf *out, const struct rtc_time *tm, bool r) { - buf =3D number(buf, end, tm->tm_hour, default_dec02_spec); - if (buf < end) - *buf =3D ':'; - buf++; - - buf =3D number(buf, end, tm->tm_min, default_dec02_spec); - if (buf < end) - *buf =3D ':'; - buf++; - - return number(buf, end, tm->tm_sec, default_dec02_spec); + number(out, tm->tm_hour, default_dec02_spec); + prt_char(out, ':'); + number(out, tm->tm_min, default_dec02_spec); + prt_char(out, ':'); + number(out, tm->tm_sec, default_dec02_spec); } =20 static noinline_for_stack -char *rtc_str(char *buf, char *end, const struct rtc_time *tm, - struct printf_spec spec, const char *fmt) +void rtc_str(struct printbuf *out, const struct rtc_time *tm, + struct printf_spec spec, const char *fmt) { bool have_t =3D true, have_d =3D true; bool raw =3D false, iso8601_separator =3D true; bool found =3D true; int count =3D 2; =20 - if (check_pointer(&buf, end, tm, spec)) - return buf; + if (check_pointer(out, tm, spec)) + return; =20 switch (fmt[count]) { case 'd': @@ -1910,21 +1832,16 @@ char *rtc_str(char *buf, char *end, const struct rt= c_time *tm, } while (found); =20 if (have_d) - buf =3D date_str(buf, end, tm, raw); - if (have_d && have_t) { - if (buf < end) - *buf =3D iso8601_separator ? 'T' : ' '; - buf++; - } + date_str(out, tm, raw); + if (have_d && have_t) + prt_char(out, iso8601_separator ? 'T' : ' '); if (have_t) - buf =3D time_str(buf, end, tm, raw); - - return buf; + time_str(out, tm, raw); } =20 static noinline_for_stack -char *time64_str(char *buf, char *end, const time64_t time, - struct printf_spec spec, const char *fmt) +void time64_str(struct printbuf *out, const time64_t time, + struct printf_spec spec, const char *fmt) { struct rtc_time rtc_time; struct tm tm; @@ -1942,47 +1859,48 @@ char *time64_str(char *buf, char *end, const time64= _t time, =20 rtc_time.tm_isdst =3D 0; =20 - return rtc_str(buf, end, &rtc_time, spec, fmt); + rtc_str(out, &rtc_time, spec, fmt); } =20 static noinline_for_stack -char *time_and_date(char *buf, char *end, void *ptr, struct printf_spec sp= ec, - const char *fmt) +void time_and_date(struct printbuf *out, + void *ptr, struct printf_spec spec, + const char *fmt) { switch (fmt[1]) { case 'R': - return rtc_str(buf, end, (const struct rtc_time *)ptr, spec, fmt); + return rtc_str(out, (const struct rtc_time *)ptr, spec, fmt); case 'T': - return time64_str(buf, end, *(const time64_t *)ptr, spec, fmt); + return time64_str(out, *(const time64_t *)ptr, spec, fmt); default: - return error_string(buf, end, "(%pt?)", spec); + return error_string(out, "(%pt?)", spec); } } =20 static noinline_for_stack -char *clock(char *buf, char *end, struct clk *clk, struct printf_spec spec, - const char *fmt) +void clock(struct printbuf *out, struct clk *clk, + struct printf_spec spec, const char *fmt) { if (!IS_ENABLED(CONFIG_HAVE_CLK)) - return error_string(buf, end, "(%pC?)", spec); + return error_string(out, "(%pC?)", spec); =20 - if (check_pointer(&buf, end, clk, spec)) - return buf; + if (check_pointer(out, clk, spec)) + return; =20 switch (fmt[1]) { case 'n': default: #ifdef CONFIG_COMMON_CLK - return string(buf, end, __clk_get_name(clk), spec); + return string(out, __clk_get_name(clk), spec); #else - return ptr_to_id(buf, end, clk, spec); + return ptr_to_id(out, clk, spec); #endif } } =20 static -char *format_flags(char *buf, char *end, unsigned long flags, - const struct trace_print_flags *names) +void format_flags(struct printbuf *out, unsigned long flags, + const struct trace_print_flags *names) { unsigned long mask; =20 @@ -1991,20 +1909,15 @@ char *format_flags(char *buf, char *end, unsigned l= ong flags, if ((flags & mask) !=3D mask) continue; =20 - buf =3D string(buf, end, names->name, default_str_spec); + string(out, names->name, default_str_spec); =20 flags &=3D ~mask; - if (flags) { - if (buf < end) - *buf =3D '|'; - buf++; - } + if (flags) + prt_char(out, '|'); } =20 if (flags) - buf =3D number(buf, end, flags, default_flag_spec); - - return buf; + number(out, flags, default_flag_spec); } =20 struct page_flags_fields { @@ -2029,20 +1942,18 @@ static const struct page_flags_fields pff[] =3D { }; =20 static -char *format_page_flags(char *buf, char *end, unsigned long flags) +void format_page_flags(struct printbuf *out, unsigned long flags) { unsigned long main_flags =3D flags & PAGEFLAGS_MASK; bool append =3D false; int i; =20 - buf =3D number(buf, end, flags, default_flag_spec); - if (buf < end) - *buf =3D '('; - buf++; + number(out, flags, default_flag_spec); + prt_char(out, '('); =20 /* Page flags from the main area. */ if (main_flags) { - buf =3D format_flags(buf, end, main_flags, pageflag_names); + format_flags(out, main_flags, pageflag_names); append =3D true; } =20 @@ -2053,41 +1964,31 @@ char *format_page_flags(char *buf, char *end, unsig= ned long flags) continue; =20 /* Format: Flag Name + '=3D' (equals sign) + Number + '|' (separator) */ - if (append) { - if (buf < end) - *buf =3D '|'; - buf++; - } + if (append) + prt_char(out, '|'); =20 - buf =3D string(buf, end, pff[i].name, default_str_spec); - if (buf < end) - *buf =3D '=3D'; - buf++; - buf =3D number(buf, end, (flags >> pff[i].shift) & pff[i].mask, - *pff[i].spec); + string(out, pff[i].name, default_str_spec); + prt_char(out, '=3D'); + number(out, (flags >> pff[i].shift) & pff[i].mask, *pff[i].spec); =20 append =3D true; } - if (buf < end) - *buf =3D ')'; - buf++; - - return buf; + prt_char(out, ')'); } =20 static noinline_for_stack -char *flags_string(char *buf, char *end, void *flags_ptr, - struct printf_spec spec, const char *fmt) +void flags_string(struct printbuf *out, void *flags_ptr, + struct printf_spec spec, const char *fmt) { unsigned long flags; const struct trace_print_flags *names; =20 - if (check_pointer(&buf, end, flags_ptr, spec)) - return buf; + if (check_pointer(out, flags_ptr, spec)) + return; =20 switch (fmt[1]) { case 'p': - return format_page_flags(buf, end, *(unsigned long *)flags_ptr); + return format_page_flags(out, *(unsigned long *)flags_ptr); case 'v': flags =3D *(unsigned long *)flags_ptr; names =3D vmaflag_names; @@ -2097,15 +1998,15 @@ char *flags_string(char *buf, char *end, void *flag= s_ptr, names =3D gfpflag_names; break; default: - return error_string(buf, end, "(%pG?)", spec); + return error_string(out, "(%pG?)", spec); } =20 - return format_flags(buf, end, flags, names); + return format_flags(out, flags, names); } =20 static noinline_for_stack -char *fwnode_full_name_string(struct fwnode_handle *fwnode, char *buf, - char *end) +void fwnode_full_name_string(struct printbuf *out, + struct fwnode_handle *fwnode) { int depth; =20 @@ -2114,25 +2015,23 @@ char *fwnode_full_name_string(struct fwnode_handle = *fwnode, char *buf, struct fwnode_handle *__fwnode =3D fwnode_get_nth_parent(fwnode, depth); =20 - buf =3D string(buf, end, fwnode_get_name_prefix(__fwnode), - default_str_spec); - buf =3D string(buf, end, fwnode_get_name(__fwnode), - default_str_spec); + string(out, fwnode_get_name_prefix(__fwnode), + default_str_spec); + string(out, fwnode_get_name(__fwnode), + default_str_spec); =20 fwnode_handle_put(__fwnode); } - - return buf; } =20 static noinline_for_stack -char *device_node_string(char *buf, char *end, struct device_node *dn, - struct printf_spec spec, const char *fmt) +void device_node_string(struct printbuf *out, struct device_node *dn, + struct printf_spec spec, const char *fmt) { char tbuf[sizeof("xxxx") + 1]; const char *p; int ret; - char *buf_start =3D buf; + unsigned start =3D out->pos; struct property *prop; bool has_mult, pass; =20 @@ -2140,13 +2039,13 @@ char *device_node_string(char *buf, char *end, stru= ct device_node *dn, str_spec.field_width =3D -1; =20 if (fmt[0] !=3D 'F') - return error_string(buf, end, "(%pO?)", spec); + return error_string(out, "(%pO?)", spec); =20 if (!IS_ENABLED(CONFIG_OF)) - return error_string(buf, end, "(%pOF?)", spec); + return error_string(out, "(%pOF?)", spec); =20 - if (check_pointer(&buf, end, dn, spec)) - return buf; + if (check_pointer(out, dn, spec)) + return; =20 /* simple case without anything any more format specifiers */ fmt++; @@ -2155,32 +2054,28 @@ char *device_node_string(char *buf, char *end, stru= ct device_node *dn, =20 for (pass =3D false; strspn(fmt,"fnpPFcC"); fmt++, pass =3D true) { int precision; - if (pass) { - if (buf < end) - *buf =3D ':'; - buf++; - } + if (pass) + prt_char(out, ':'); =20 switch (*fmt) { case 'f': /* full_name */ - buf =3D fwnode_full_name_string(of_fwnode_handle(dn), buf, - end); + fwnode_full_name_string(out, of_fwnode_handle(dn)); break; case 'n': /* name */ p =3D fwnode_get_name(of_fwnode_handle(dn)); precision =3D str_spec.precision; str_spec.precision =3D strchrnul(p, '@') - p; - buf =3D string(buf, end, p, str_spec); + string(out, p, str_spec); str_spec.precision =3D precision; break; case 'p': /* phandle */ - buf =3D number(buf, end, (unsigned int)dn->phandle, default_dec_spec); + number(out, (unsigned int)dn->phandle, default_dec_spec); break; case 'P': /* path-spec */ p =3D fwnode_get_name(of_fwnode_handle(dn)); if (!p[1]) p =3D "/"; - buf =3D string(buf, end, p, str_spec); + string(out, p, str_spec); break; case 'F': /* flags */ tbuf[0] =3D of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-'; @@ -2188,21 +2083,21 @@ char *device_node_string(char *buf, char *end, stru= ct device_node *dn, tbuf[2] =3D of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-'; tbuf[3] =3D of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-'; tbuf[4] =3D 0; - buf =3D string_nocheck(buf, end, tbuf, str_spec); + string_nocheck(out, tbuf, str_spec); break; case 'c': /* major compatible string */ ret =3D of_property_read_string(dn, "compatible", &p); if (!ret) - buf =3D string(buf, end, p, str_spec); + string(out, p, str_spec); break; case 'C': /* full compatible string */ has_mult =3D false; of_property_for_each_string(dn, "compatible", prop, p) { if (has_mult) - buf =3D string_nocheck(buf, end, ",", str_spec); - buf =3D string_nocheck(buf, end, "\"", str_spec); - buf =3D string(buf, end, p, str_spec); - buf =3D string_nocheck(buf, end, "\"", str_spec); + string_nocheck(out, ",", str_spec); + string_nocheck(out, "\"", str_spec); + string(out, p, str_spec); + string_nocheck(out, "\"", str_spec); =20 has_mult =3D true; } @@ -2212,37 +2107,38 @@ char *device_node_string(char *buf, char *end, stru= ct device_node *dn, } } =20 - return widen_string(buf, buf - buf_start, end, spec); + widen_string(out, out->pos - start, spec); } =20 static noinline_for_stack -char *fwnode_string(char *buf, char *end, struct fwnode_handle *fwnode, - struct printf_spec spec, const char *fmt) +void fwnode_string(struct printbuf *out, + struct fwnode_handle *fwnode, + struct printf_spec spec, const char *fmt) { struct printf_spec str_spec =3D spec; - char *buf_start =3D buf; + unsigned start =3D out->pos; =20 str_spec.field_width =3D -1; =20 if (*fmt !=3D 'w') - return error_string(buf, end, "(%pf?)", spec); + return error_string(out, "(%pf?)", spec); =20 - if (check_pointer(&buf, end, fwnode, spec)) - return buf; + if (check_pointer(out, fwnode, spec)) + return; =20 fmt++; =20 switch (*fmt) { case 'P': /* name */ - buf =3D string(buf, end, fwnode_get_name(fwnode), str_spec); + string(out, fwnode_get_name(fwnode), str_spec); break; case 'f': /* full_name */ default: - buf =3D fwnode_full_name_string(fwnode, buf, end); + fwnode_full_name_string(out, fwnode); break; } =20 - return widen_string(buf, buf - buf_start, end, spec); + widen_string(out, out->pos - start, spec); } =20 int __init no_hash_pointers_enable(char *str) @@ -2398,8 +2294,8 @@ early_param("no_hash_pointers", no_hash_pointers_enab= le); * rendering it useful as a unique identifier. */ static noinline_for_stack -char *pointer(const char *fmt, char *buf, char *end, void *ptr, - struct printf_spec spec) +void pointer(struct printbuf *out, const char *fmt, + void *ptr, struct printf_spec spec) { switch (*fmt) { case 'S': @@ -2407,24 +2303,24 @@ char *pointer(const char *fmt, char *buf, char *end= , void *ptr, ptr =3D dereference_symbol_descriptor(ptr); fallthrough; case 'B': - return symbol_string(buf, end, ptr, spec, fmt); + return symbol_string(out, ptr, spec, fmt); case 'R': case 'r': - return resource_string(buf, end, ptr, spec, fmt); + return resource_string(out, ptr, spec, fmt); case 'h': - return hex_string(buf, end, ptr, spec, fmt); + return hex_string(out, ptr, spec, fmt); case 'b': switch (fmt[1]) { case 'l': - return bitmap_list_string(buf, end, ptr, spec, fmt); + return bitmap_list_string(out, ptr, spec, fmt); default: - return bitmap_string(buf, end, ptr, spec, fmt); + return bitmap_string(out, ptr, spec, fmt); } case 'M': /* Colon separated: 00:01:02:03:04:05 */ case 'm': /* Contiguous: 000102030405 */ /* [mM]F (FDDI) */ /* [mM]R (Reverse order; Bluetooth) */ - return mac_address_string(buf, end, ptr, spec, fmt); + return mac_address_string(out, ptr, spec, fmt); case 'I': /* Formatted IP supported * 4: 1.2.3.4 * 6: 0001:0203:...:0708 @@ -2434,57 +2330,57 @@ char *pointer(const char *fmt, char *buf, char *end= , void *ptr, * 4: 001.002.003.004 * 6: 000102...0f */ - return ip_addr_string(buf, end, ptr, spec, fmt); + return ip_addr_string(out, ptr, spec, fmt); case 'E': - return escaped_string(buf, end, ptr, spec, fmt); + return escaped_string(out, ptr, spec, fmt); case 'U': - return uuid_string(buf, end, ptr, spec, fmt); + return uuid_string(out, ptr, spec, fmt); case 'V': - return va_format(buf, end, ptr, spec, fmt); + return va_format(out, ptr, spec, fmt); case 'K': - return restricted_pointer(buf, end, ptr, spec); + return restricted_pointer(out, ptr, spec); case 'N': - return netdev_bits(buf, end, ptr, spec, fmt); + return netdev_bits(out, ptr, spec, fmt); case '4': - return fourcc_string(buf, end, ptr, spec, fmt); + return fourcc_string(out, ptr, spec, fmt); case 'a': - return address_val(buf, end, ptr, spec, fmt); + return address_val(out, ptr, spec, fmt); case 'd': - return dentry_name(buf, end, ptr, spec, fmt); + return dentry_name(out, ptr, spec, fmt); case 't': - return time_and_date(buf, end, ptr, spec, fmt); + return time_and_date(out, ptr, spec, fmt); case 'C': - return clock(buf, end, ptr, spec, fmt); + return clock(out, ptr, spec, fmt); case 'D': - return file_dentry_name(buf, end, ptr, spec, fmt); + return file_dentry_name(out, ptr, spec, fmt); #ifdef CONFIG_BLOCK case 'g': - return bdev_name(buf, end, ptr, spec, fmt); + return bdev_name(out, ptr, spec, fmt); #endif =20 case 'G': - return flags_string(buf, end, ptr, spec, fmt); + return flags_string(out, ptr, spec, fmt); case 'O': - return device_node_string(buf, end, ptr, spec, fmt + 1); + return device_node_string(out, ptr, spec, fmt + 1); case 'f': - return fwnode_string(buf, end, ptr, spec, fmt + 1); + return fwnode_string(out, ptr, spec, fmt + 1); case 'x': - return pointer_string(buf, end, ptr, spec); + return pointer_string(out, ptr, spec); case 'e': /* %pe with a non-ERR_PTR gets treated as plain %p */ if (!IS_ERR(ptr)) - return default_pointer(buf, end, ptr, spec); - return err_ptr(buf, end, ptr, spec); + return default_pointer(out, ptr, spec); + return err_ptr(out, ptr, spec); case 'u': case 'k': switch (fmt[1]) { case 's': - return string(buf, end, ptr, spec); + return string(out, ptr, spec); default: - return error_string(buf, end, "(einval)", spec); + return error_string(out, "(einval)", spec); } default: - return default_pointer(buf, end, ptr, spec); + return default_pointer(out, ptr, spec); } } =20 @@ -2706,52 +2602,27 @@ set_precision(struct printf_spec *spec, int prec) } =20 /** - * vsnprintf - Format a string and place it in a buffer - * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space + * prt_vprintf - Format a string, outputting to a printbuf + * @out: The printbuf to output to * @fmt: The format string to use * @args: Arguments for the format string * - * This function generally follows C99 vsnprintf, but has some - * extensions and a few limitations: - * - * - ``%n`` is unsupported - * - ``%p*`` is handled by pointer() - * - * See pointer() or Documentation/core-api/printk-formats.rst for more - * extensive description. - * - * **Please update the documentation in both places when making changes** + * prt_vprintf works much like the traditional vsnprintf(), but outputs to= a + * printbuf instead of raw pointer/size. * - * The return value is the number of characters which would - * be generated for the given input, excluding the trailing - * '\0', as per ISO C99. If you want to have the exact - * number of characters written into @buf as return value - * (not including the trailing '\0'), use vscnprintf(). If the - * return is greater than or equal to @size, the resulting - * string is truncated. + * If you're not already dealing with a va_list consider using prt_printf(= ). * - * If you're not already dealing with a va_list consider using snprintf(). + * See the vsnprintf() documentation for format string extensions over C99. */ -int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) +void prt_vprintf(struct printbuf *out, const char *fmt, va_list args) { unsigned long long num; - char *str, *end; struct printf_spec spec =3D {0}; =20 /* Reject out-of-range values early. Large positive sizes are used for unknown buffer sizes. */ - if (WARN_ON_ONCE(size > INT_MAX)) - return 0; - - str =3D buf; - end =3D buf + size; - - /* Make sure end is always >=3D buf */ - if (end < buf) { - end =3D ((void *)-1); - size =3D end - buf; - } + if (WARN_ON_ONCE(out->size > INT_MAX)) + return; =20 while (*fmt) { const char *old_fmt =3D fmt; @@ -2760,16 +2631,9 @@ int vsnprintf(char *buf, size_t size, const char *fm= t, va_list args) fmt +=3D read; =20 switch (spec.type) { - case FORMAT_TYPE_NONE: { - int copy =3D read; - if (str < end) { - if (copy > end - str) - copy =3D end - str; - memcpy(str, old_fmt, copy); - } - str +=3D read; + case FORMAT_TYPE_NONE: + prt_bytes(out, old_fmt, read); break; - } =20 case FORMAT_TYPE_WIDTH: set_field_width(&spec, va_arg(args, int)); @@ -2779,44 +2643,29 @@ int vsnprintf(char *buf, size_t size, const char *f= mt, va_list args) set_precision(&spec, va_arg(args, int)); break; =20 - case FORMAT_TYPE_CHAR: { - char c; + case FORMAT_TYPE_CHAR: + if (spec.field_width > 0 && !(spec.flags & LEFT)) + prt_chars(out, spec.field_width, ' '); =20 - if (!(spec.flags & LEFT)) { - while (--spec.field_width > 0) { - if (str < end) - *str =3D ' '; - ++str; + __prt_char(out, (unsigned char) va_arg(args, int)); =20 - } - } - c =3D (unsigned char) va_arg(args, int); - if (str < end) - *str =3D c; - ++str; - while (--spec.field_width > 0) { - if (str < end) - *str =3D ' '; - ++str; - } + if (spec.field_width > 0 && (spec.flags & LEFT)) + prt_chars(out, spec.field_width, ' '); + spec.field_width =3D 0; break; - } =20 case FORMAT_TYPE_STR: - str =3D string(str, end, va_arg(args, char *), spec); + string(out, va_arg(args, char *), spec); break; =20 case FORMAT_TYPE_PTR: - str =3D pointer(fmt, str, end, va_arg(args, void *), - spec); + pointer(out, fmt, va_arg(args, void *), spec); while (isalnum(*fmt)) fmt++; break; =20 case FORMAT_TYPE_PERCENT_CHAR: - if (str < end) - *str =3D '%'; - ++str; + __prt_char(out, '%'); break; =20 case FORMAT_TYPE_INVALID: @@ -2869,21 +2718,70 @@ int vsnprintf(char *buf, size_t size, const char *f= mt, va_list args) num =3D va_arg(args, unsigned int); } =20 - str =3D number(str, end, num, spec); + number(out, num, spec); } } - out: - if (size > 0) { - if (str < end) - *str =3D '\0'; - else - end[-1] =3D '\0'; - } + printbuf_nul_terminate(out); +} +EXPORT_SYMBOL(prt_vprintf); =20 - /* the trailing null byte doesn't count towards the total */ - return str-buf; +/** + * prt_printf - Format a string, outputting to a printbuf + * @out: The printbuf to output to + * @fmt: The format string to use + * @args: Arguments for the format string + * + * + * prt_printf works much like the traditional sprintf(), but outputs to a + * printbuf instead of raw pointer/size. + * + * See the vsnprintf() documentation for format string extensions over C99. + */ +void prt_printf(struct printbuf *out, const char *fmt, ...) +{ + va_list args; =20 + va_start(args, fmt); + prt_vprintf(out, fmt, args); + va_end(args); +} +EXPORT_SYMBOL(prt_printf); + +/** + * vsnprintf - Format a string and place it in a buffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @args: Arguments for the format string + * + * This function generally follows C99 vsnprintf, but has some + * extensions and a few limitations: + * + * - ``%n`` is unsupported + * - ``%p*`` is handled by pointer() + * + * See pointer() or Documentation/core-api/printk-formats.rst for more + * extensive description. + * + * **Please update the documentation in both places when making changes** + * + * The return value is the number of characters which would + * be generated for the given input, excluding the trailing + * '\0', as per ISO C99. If you want to have the exact + * number of characters written into @buf as return value + * (not including the trailing '\0'), use vscnprintf(). If the + * return is greater than or equal to @size, the resulting + * string is truncated. + * + * If you're not already dealing with a va_list consider using snprintf(). + */ +int vsnprintf(char *buf, size_t size, const char *fmt, va_list args) +{ + struct printbuf out =3D PRINTBUF_EXTERN(buf, size); + + prt_vprintf(&out, fmt, args); + return out.pos; } EXPORT_SYMBOL(vsnprintf); =20 @@ -3021,53 +2919,46 @@ EXPORT_SYMBOL(sprintf); * bstr_printf() - Binary data to text string */ =20 +static inline void printbuf_align(struct printbuf *out, unsigned align) +{ + /* Assumes output buffer is correctly aligned: */ + out->pos +=3D align - 1; + out->pos &=3D ~(align - 1); +} + /** - * vbin_printf - Parse a format string and place args' binary value in a b= uffer - * @bin_buf: The buffer to place args' binary value - * @size: The size of the buffer(by words(32bits), not characters) + * prt_vbinprintf - Parse a format string and place args' binary value in = a buffer + * @out: The buffer to place args' binary value * @fmt: The format string to use * @args: Arguments for the format string * * The format follows C99 vsnprintf, except %n is ignored, and its argument * is skipped. * - * The return value is the number of words(32bits) which would be generate= d for - * the given input. - * * NOTE: * If the return value is greater than @size, the resulting bin_buf is NOT * valid for bstr_printf(). */ -int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) +void prt_vbinprintf(struct printbuf *out, const char *fmt, va_list args) { struct printf_spec spec =3D {0}; - char *str, *end; int width; =20 - str =3D (char *)bin_buf; - end =3D (char *)(bin_buf + size); - #define save_arg(type) \ ({ \ unsigned long long value; \ if (sizeof(type) =3D=3D 8) { \ - unsigned long long val8; \ - str =3D PTR_ALIGN(str, sizeof(u32)); \ - val8 =3D va_arg(args, unsigned long long); \ - if (str + sizeof(type) <=3D end) { \ - *(u32 *)str =3D *(u32 *)&val8; \ - *(u32 *)(str + 4) =3D *((u32 *)&val8 + 1); \ - } \ + u64 val8 =3D va_arg(args, u64); \ + printbuf_align(out, sizeof(u32)); \ + prt_bytes(out, (u32 *) &val8, 4); \ + prt_bytes(out, ((u32 *) &val8) + 1, 4); \ value =3D val8; \ } else { \ - unsigned int val4; \ - str =3D PTR_ALIGN(str, sizeof(type)); \ - val4 =3D va_arg(args, int); \ - if (str + sizeof(type) <=3D end) \ - *(typeof(type) *)str =3D (type)(long)val4; \ + u32 val4 =3D va_arg(args, u32); \ + printbuf_align(out, sizeof(type)); \ + prt_bytes(out, &val4, sizeof(type)); \ value =3D (unsigned long long)val4; \ } \ - str +=3D sizeof(type); \ value; \ }) =20 @@ -3098,16 +2989,12 @@ int vbin_printf(u32 *bin_buf, size_t size, const ch= ar *fmt, va_list args) case FORMAT_TYPE_STR: { const char *save_str =3D va_arg(args, char *); const char *err_msg; - size_t len; =20 err_msg =3D check_pointer_msg(save_str); if (err_msg) save_str =3D err_msg; =20 - len =3D strlen(save_str) + 1; - if (str + len < end) - memcpy(str, save_str, len); - str +=3D len; + prt_str(out, save_str); break; } =20 @@ -3127,12 +3014,7 @@ int vbin_printf(u32 *bin_buf, size_t size, const cha= r *fmt, va_list args) save_arg(void *); break; } - str =3D pointer(fmt, str, end, va_arg(args, void *), - spec); - if (str + 1 < end) - *str++ =3D '\0'; - else - end[-1] =3D '\0'; /* Must be nul terminated */ + pointer(out, fmt, va_arg(args, void *), spec); } /* skip all alphanumeric pointer suffixes */ while (isalnum(*fmt)) @@ -3170,15 +3052,15 @@ int vbin_printf(u32 *bin_buf, size_t size, const ch= ar *fmt, va_list args) } =20 out: - return (u32 *)(PTR_ALIGN(str, sizeof(u32))) - bin_buf; + printbuf_nul_terminate(out); + printbuf_align(out, 4); #undef save_arg } -EXPORT_SYMBOL_GPL(vbin_printf); +EXPORT_SYMBOL_GPL(prt_vbinprintf); =20 /** - * bstr_printf - Format a string from binary arguments and place it in a b= uffer + * prt_bstrprintf - Format a string from binary arguments and place it in = a buffer * @buf: The buffer to place the result into - * @size: The size of the buffer, including the trailing null space * @fmt: The format string to use * @bin_buf: Binary arguments for the format string * @@ -3188,26 +3070,14 @@ EXPORT_SYMBOL_GPL(vbin_printf); * * The format follows C99 vsnprintf, but has some extensions: * see vsnprintf comment for details. - * - * The return value is the number of characters which would - * be generated for the given input, excluding the trailing - * '\0', as per ISO C99. If you want to have the exact - * number of characters written into @buf as return value - * (not including the trailing '\0'), use vscnprintf(). If the - * return is greater than or equal to @size, the resulting - * string is truncated. */ -int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_bu= f) +void prt_bstrprintf(struct printbuf *out, const char *fmt, const u32 *bin_= buf) { struct printf_spec spec =3D {0}; - char *str, *end; const char *args =3D (const char *)bin_buf; =20 - if (WARN_ON_ONCE(size > INT_MAX)) - return 0; - - str =3D buf; - end =3D buf + size; + if (WARN_ON_ONCE(out->size > INT_MAX)) + return; =20 #define get_arg(type) \ ({ \ @@ -3224,12 +3094,6 @@ int bstr_printf(char *buf, size_t size, const char *= fmt, const u32 *bin_buf) value; \ }) =20 - /* Make sure end is always >=3D buf */ - if (end < buf) { - end =3D ((void *)-1); - size =3D end - buf; - } - while (*fmt) { const char *old_fmt =3D fmt; int read =3D format_decode(fmt, &spec); @@ -3237,16 +3101,9 @@ int bstr_printf(char *buf, size_t size, const char *= fmt, const u32 *bin_buf) fmt +=3D read; =20 switch (spec.type) { - case FORMAT_TYPE_NONE: { - int copy =3D read; - if (str < end) { - if (copy > end - str) - copy =3D end - str; - memcpy(str, old_fmt, copy); - } - str +=3D read; + case FORMAT_TYPE_NONE: + prt_bytes(out, old_fmt, read); break; - } =20 case FORMAT_TYPE_WIDTH: set_field_width(&spec, get_arg(int)); @@ -3256,38 +3113,24 @@ int bstr_printf(char *buf, size_t size, const char = *fmt, const u32 *bin_buf) set_precision(&spec, get_arg(int)); break; =20 - case FORMAT_TYPE_CHAR: { - char c; - - if (!(spec.flags & LEFT)) { - while (--spec.field_width > 0) { - if (str < end) - *str =3D ' '; - ++str; - } - } - c =3D (unsigned char) get_arg(char); - if (str < end) - *str =3D c; - ++str; - while (--spec.field_width > 0) { - if (str < end) - *str =3D ' '; - ++str; - } + case FORMAT_TYPE_CHAR: + if (!(spec.flags & LEFT)) + prt_chars(out, spec.field_width, ' '); + __prt_char(out, (unsigned char) get_arg(char)); + if ((spec.flags & LEFT)) + prt_chars(out, spec.field_width, ' '); break; - } =20 case FORMAT_TYPE_STR: { const char *str_arg =3D args; args +=3D strlen(str_arg) + 1; - str =3D string(str, end, (char *)str_arg, spec); + string(out, (char *)str_arg, spec); break; } =20 case FORMAT_TYPE_PTR: { bool process =3D false; - int copy, len; + int len; /* Non function dereferences were already done */ switch (*fmt) { case 'S': @@ -3303,17 +3146,12 @@ int bstr_printf(char *buf, size_t size, const char = *fmt, const u32 *bin_buf) break; } /* Pointer dereference was already processed */ - if (str < end) { - len =3D copy =3D strlen(args); - if (copy > end - str) - copy =3D end - str; - memcpy(str, args, copy); - str +=3D len; - args +=3D len + 1; - } + len =3D strlen(args); + prt_bytes(out, args, len); + args +=3D len + 1; } if (process) - str =3D pointer(fmt, str, end, get_arg(void *), spec); + pointer(out, fmt, get_arg(void *), spec); =20 while (isalnum(*fmt)) fmt++; @@ -3321,9 +3159,7 @@ int bstr_printf(char *buf, size_t size, const char *f= mt, const u32 *bin_buf) } =20 case FORMAT_TYPE_PERCENT_CHAR: - if (str < end) - *str =3D '%'; - ++str; + __prt_char(out, '%'); break; =20 case FORMAT_TYPE_INVALID: @@ -3366,23 +3202,87 @@ int bstr_printf(char *buf, size_t size, const char = *fmt, const u32 *bin_buf) num =3D get_arg(int); } =20 - str =3D number(str, end, num, spec); + number(out, num, spec); } /* default: */ } /* switch(spec.type) */ } /* while(*fmt) */ =20 out: - if (size > 0) { - if (str < end) - *str =3D '\0'; - else - end[-1] =3D '\0'; - } - #undef get_arg + printbuf_nul_terminate(out); +} +EXPORT_SYMBOL_GPL(prt_bstrprintf); + +/** + * prt_bprintf - Parse a format string and place args' binary value in a b= uffer + * @out: The buffer to place args' binary value + * @fmt: The format string to use + * @...: Arguments for the format string + */ +void prt_bprintf(struct printbuf *out, const char *fmt, ...) +{ + va_list args; + + va_start(args, fmt); + prt_vbinprintf(out, fmt, args); + va_end(args); +} +EXPORT_SYMBOL_GPL(prt_bprintf); + +/** + * vbin_printf - Parse a format string and place args' binary value in a b= uffer + * @bin_buf: The buffer to place args' binary value + * @size: The size of the buffer(by words(32bits), not characters) + * @fmt: The format string to use + * @args: Arguments for the format string + * + * The format follows C99 vsnprintf, except %n is ignored, and its argument + * is skipped. + * + * The return value is the number of words(32bits) which would be generate= d for + * the given input. + * + * NOTE: + * If the return value is greater than @size, the resulting bin_buf is NOT + * valid for bstr_printf(). + */ +int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args) +{ + struct printbuf out =3D PRINTBUF_EXTERN((char *) bin_buf, size); + + prt_vbinprintf(&out, fmt, args); + return out.pos; +} +EXPORT_SYMBOL_GPL(vbin_printf); + +/** + * bstr_printf - Format a string from binary arguments and place it in a b= uffer + * @buf: The buffer to place the result into + * @size: The size of the buffer, including the trailing null space + * @fmt: The format string to use + * @bin_buf: Binary arguments for the format string + * + * This function like C99 vsnprintf, but the difference is that vsnprintf = gets + * arguments from stack, and bstr_printf gets arguments from @bin_buf whic= h is + * a binary buffer that generated by vbin_printf. + * + * The format follows C99 vsnprintf, but has some extensions: + * see vsnprintf comment for details. + * + * The return value is the number of characters which would + * be generated for the given input, excluding the trailing + * '\0', as per ISO C99. If you want to have the exact + * number of characters written into @buf as return value + * (not including the trailing '\0'), use vscnprintf(). If the + * return is greater than or equal to @size, the resulting + * string is truncated. + */ +int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_bu= f) +{ + struct printbuf out =3D PRINTBUF_EXTERN(buf, size); =20 - /* the trailing null byte doesn't count towards the total */ - return str - buf; + prt_bstrprintf(&out, fmt, bin_buf); + return out.pos; } EXPORT_SYMBOL_GPL(bstr_printf); =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 31C4AC43334 for ; Sat, 4 Jun 2022 19:31:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240169AbiFDTbI (ORCPT ); Sat, 4 Jun 2022 15:31:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46900 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240001AbiFDTa7 (ORCPT ); Sat, 4 Jun 2022 15:30:59 -0400 Received: from mail-qk1-x72c.google.com (mail-qk1-x72c.google.com [IPv6:2607:f8b0:4864:20::72c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70A45340EF for ; Sat, 4 Jun 2022 12:30:57 -0700 (PDT) Received: by mail-qk1-x72c.google.com with SMTP id br33so6651041qkb.0 for ; Sat, 04 Jun 2022 12:30:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=99r+5/vRUGhJSKZt1j7G05fBKkay2azibBnxMCo4mAc=; b=ne35BTBcp5szdMiUZlgM/9j3ghl+LXRZhI9QyFMXLphEAjd2KC+bxv+Gu9y8R7LmTS /ytc8gPBleqDWxlLtouiLkM0a5yrN9rTgbTyhZLd8NL7mFarpK8Cp3WP4u+becmhLbYH 6ZKpOnKKXKFSpE5kOBYJY7Q8+sU38lckM9C8BMM+335xNLIwZ12dIwi47yLj3lhegyIA w520P5fzvspe5TQQfMA2NVvn7gDU6lsUUC44ivWjKpHonm/35XdcUISTngLb8i07BOPp sLjpnpcAYe1ua40niKk/ytB0ODaPptNOadeIgUSqT3jCog2ZsIWo1Eo+DclxrDpwz0Ix 93sQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=99r+5/vRUGhJSKZt1j7G05fBKkay2azibBnxMCo4mAc=; b=XiqifSnAgyN05oE/7DsJHCMvmN92FrHuD7TFxF8INHnY6IuYu3pXvmoy6WBS+oHvl1 HyoI3eTPSuKxPVQn77fp5SqolfUTh0lhspMGl8nuManbqfWD14ZwgpT6nPxNCJ0O3QZi 5JBOZBDH8I0ikHS3aKI/3NnyyIxJou51NWJnchuWasj6uOEwUJ0/E0+tUg4/sXbxJFLK CG6fSOnS2/bZ9/mbFzV1JWvmRG9GXcPyoIKirUyl20eNbqCrPTNXvcxoJ/98zFrauKZf v5txbf7X8qOePXjWsRyKbGsJkcW3tjQdQMQq1cAYA5gFvZckjCkJb5LvnQciJiVLuWk+ Wchw== X-Gm-Message-State: AOAM530ogDgvW44ajVO6MzMCv1taTRDr1oCXesg6oNlTG9cqGFfTlVqL Tw2p6cY3HT47Xd0s+ui/BCAKhvPONYJS X-Google-Smtp-Source: ABdhPJwFhIgdKooD8IMyT2eyOcHH8c/8hdynxIzGjwTbVHubleL9Ij3NIxO0vVHny+1GUFUPqPcGsA== X-Received: by 2002:a05:620a:d4f:b0:67e:9cbf:a969 with SMTP id o15-20020a05620a0d4f00b0067e9cbfa969mr10970820qkl.509.1654371055580; Sat, 04 Jun 2022 12:30:55 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.30.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:30:54 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 04/33] lib/hexdump: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:13 -0400 Message-Id: <20220604193042.1674951-5-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts most of the hexdump code to printbufs, along with some significant cleanups and a bit of reorganization. The old non-printbuf functions are mostly left as wrappers around the new printbuf versions. Big note: byte swabbing behaviour Previously, hex_dump_to_buffer() would byteswab the groups of bytes being printed on little endian machines. This behaviour is... not standard or typical for a hex dumper, and this behaviour was silently added/changed without documentation (in 2007). Given that the hex dumpers are just used for debugging output, nothing is likely to break, and hopefully by reverting to more standard behaviour the end result will be _less_ confusion, modulo a few kernel developers who will certainly be annoyed by their tools changing. Signed-off-by: Kent Overstreet --- include/linux/kernel.h | 6 + lib/hexdump.c | 246 ++++++++++++++++++++++++----------------- lib/test_hexdump.c | 30 +---- 3 files changed, 159 insertions(+), 123 deletions(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5c4f4b6d36..1906861ece 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -293,6 +293,12 @@ extern int hex_to_bin(unsigned char ch); extern int __must_check hex2bin(u8 *dst, const char *src, size_t count); extern char *bin2hex(char *dst, const void *src, size_t count); =20 +struct printbuf; +void prt_hex_bytes(struct printbuf *, const void *, unsigned, unsigned, un= signed); +void prt_hex_line(struct printbuf *, const void *, size_t, int, int, bool); +void prt_hex_dump(struct printbuf *, const void *, size_t, + const char *, int, unsigned, unsigned, bool); + bool mac_pton(const char *s, u8 *mac); =20 /* diff --git a/lib/hexdump.c b/lib/hexdump.c index 06833d4043..9556f15ad2 100644 --- a/lib/hexdump.c +++ b/lib/hexdump.c @@ -9,6 +9,7 @@ #include #include #include +#include #include =20 const char hex_asc[] =3D "0123456789abcdef"; @@ -79,32 +80,40 @@ int hex2bin(u8 *dst, const char *src, size_t count) EXPORT_SYMBOL(hex2bin); =20 /** - * bin2hex - convert binary data to an ascii hexadecimal string - * @dst: ascii hexadecimal result - * @src: binary data - * @count: binary data length + * prt_hex_bytes - Print a string of hex bytes, with optional separator + * + * @out: The printbuf to output to + * @addr: Buffer to print + * @nr: Number of bytes to print + * @separator: Optional separator character between each byte */ -char *bin2hex(char *dst, const void *src, size_t count) +void prt_hex_bytes(struct printbuf *out, const void *buf, unsigned len, + unsigned groupsize, unsigned separator) { - const unsigned char *_src =3D src; + const u8 *ptr =3D buf; + unsigned i; =20 - while (count--) - dst =3D hex_byte_pack(dst, *_src++); - return dst; + if (!groupsize) + groupsize =3D 1; + + for (i =3D 0; i < len ; ++i) { + if (i && separator && !(i % groupsize)) + __prt_char(out, separator); + prt_hex_byte(out, ptr[i]); + } } -EXPORT_SYMBOL(bin2hex); +EXPORT_SYMBOL(prt_hex_bytes); =20 /** - * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory + * prt_hex_line - convert a blob of data to "hex ASCII" in memory + * @out: printbuf to output to * @buf: data blob to dump * @len: number of bytes in the @buf * @rowsize: number of bytes to print per line; must be 16 or 32 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default =3D= 1) - * @linebuf: where to put the converted data - * @linebuflen: total size of @linebuf, including space for terminating NUL * @ascii: include ASCII after the hex output * - * hex_dump_to_buffer() works on one "line" of output at a time, i.e., + * prt_hex_line() works on one "line" of output at a time, i.e., * 16 or 32 bytes of input data converted to hex + ASCII output. * * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data @@ -117,22 +126,13 @@ EXPORT_SYMBOL(bin2hex); * * example output buffer: * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO - * - * Return: - * The amount of bytes placed in the buffer without terminating NUL. If the - * output was truncated, then the return value is the number of bytes - * (excluding the terminating NUL) which would have been written to the fi= nal - * string if enough space had been available. */ -int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int group= size, - char *linebuf, size_t linebuflen, bool ascii) +void prt_hex_line(struct printbuf *out, const void *buf, size_t len, + int rowsize, int groupsize, bool ascii) { + unsigned saved_pos =3D out->pos; const u8 *ptr =3D buf; - int ngroups; - u8 ch; - int j, lx =3D 0; - int ascii_column; - int ret; + int i, ngroups; =20 if (rowsize !=3D 16 && rowsize !=3D 32) rowsize =3D 16; @@ -145,84 +145,127 @@ int hex_dump_to_buffer(const void *buf, size_t len, = int rowsize, int groupsize, groupsize =3D 1; =20 ngroups =3D len / groupsize; - ascii_column =3D rowsize * 2 + rowsize / groupsize + 1; - - if (!linebuflen) - goto overflow1; =20 if (!len) - goto nil; - - if (groupsize =3D=3D 8) { - const u64 *ptr8 =3D buf; - - for (j =3D 0; j < ngroups; j++) { - ret =3D snprintf(linebuf + lx, linebuflen - lx, - "%s%16.16llx", j ? " " : "", - get_unaligned(ptr8 + j)); - if (ret >=3D linebuflen - lx) - goto overflow1; - lx +=3D ret; - } - } else if (groupsize =3D=3D 4) { - const u32 *ptr4 =3D buf; - - for (j =3D 0; j < ngroups; j++) { - ret =3D snprintf(linebuf + lx, linebuflen - lx, - "%s%8.8x", j ? " " : "", - get_unaligned(ptr4 + j)); - if (ret >=3D linebuflen - lx) - goto overflow1; - lx +=3D ret; - } - } else if (groupsize =3D=3D 2) { - const u16 *ptr2 =3D buf; - - for (j =3D 0; j < ngroups; j++) { - ret =3D snprintf(linebuf + lx, linebuflen - lx, - "%s%4.4x", j ? " " : "", - get_unaligned(ptr2 + j)); - if (ret >=3D linebuflen - lx) - goto overflow1; - lx +=3D ret; - } - } else { - for (j =3D 0; j < len; j++) { - if (linebuflen < lx + 2) - goto overflow2; - ch =3D ptr[j]; - linebuf[lx++] =3D hex_asc_hi(ch); - if (linebuflen < lx + 2) - goto overflow2; - linebuf[lx++] =3D hex_asc_lo(ch); - if (linebuflen < lx + 2) - goto overflow2; - linebuf[lx++] =3D ' '; + return; + + prt_hex_bytes(out, ptr, len, groupsize, ' '); + + if (ascii) { + unsigned ascii_column =3D rowsize * 2 + rowsize / groupsize + 1; + + prt_chars(out, ' ', max_t(int, 0, ascii_column - (out->pos - saved_pos))= ); + + for (i =3D 0; i < len; i++) { + u8 ch =3D ptr[i]; + prt_char(out, isascii(ch) && isprint(ch) ? ch : '.'); } - if (j) - lx--; } - if (!ascii) - goto nil; +} +EXPORT_SYMBOL(prt_hex_line); =20 - while (lx < ascii_column) { - if (linebuflen < lx + 2) - goto overflow2; - linebuf[lx++] =3D ' '; - } - for (j =3D 0; j < len; j++) { - if (linebuflen < lx + 2) - goto overflow2; - ch =3D ptr[j]; - linebuf[lx++] =3D (isascii(ch) && isprint(ch)) ? ch : '.'; +/** + * prt_hex_dump - print multiline formatted hex dump + * @out: printbuf to output to + * @buf: data blob to dump + * @len: number of bytes in the @buf + * @prefix_str: string to prefix each line with; + * caller supplies trailing spaces for alignment if desired + * @prefix_type: controls whether prefix of an offset, address, or none + * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NO= NE) + * @rowsize: number of bytes to print per line; must be 16 or 32 + * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default =3D= 1) + * @ascii: include ASCII after the hex output + * + * Function is an analogue of print_hex_dump() and thus has similar interf= ace. + * + * linebuf size is maximal length for one line. + * 32 * 3 - maximum bytes per line, each printed into 2 chars + 1 for + * separating space + * 2 - spaces separating hex dump and ascii representation + * 32 - ascii representation + * 1 - terminating '\0' + */ +void prt_hex_dump(struct printbuf *out, const void *buf, size_t len, + const char *prefix_str, int prefix_type, + unsigned rowsize, unsigned groupsize, bool ascii) +{ + const u8 *ptr =3D buf; + size_t i; + + if (rowsize !=3D 16 && rowsize !=3D 32) + rowsize =3D 16; + + for (i =3D 0; i < len; i +=3D rowsize) { + prt_str(out, prefix_str); + + switch (prefix_type) { + case DUMP_PREFIX_ADDRESS: + prt_printf(out, "%p: ", ptr + i); + break; + case DUMP_PREFIX_OFFSET: + prt_printf(out, "%.8zx: ", i); + break; + } + + prt_hex_line(out, ptr + i, min_t(size_t, len - i, rowsize), + rowsize, groupsize, ascii); + prt_char(out, '\n'); } -nil: - linebuf[lx] =3D '\0'; - return lx; -overflow2: - linebuf[lx++] =3D '\0'; -overflow1: - return ascii ? ascii_column + len : (groupsize * 2 + 1) * ngroups - 1; +} + +/** + * bin2hex - convert binary data to an ascii hexadecimal string + * @dst: ascii hexadecimal result + * @src: binary data + * @count: binary data length + */ +char *bin2hex(char *dst, const void *src, size_t count) +{ + struct printbuf out =3D PRINTBUF_EXTERN(dst, count * 4); + + prt_hex_bytes(&out, src, count, 0, 0); + return dst + out.pos; +} +EXPORT_SYMBOL(bin2hex); + +/** + * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory + * @buf: data blob to dump + * @len: number of bytes in the @buf + * @rowsize: number of bytes to print per line; must be 16 or 32 + * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default =3D= 1) + * @linebuf: where to put the converted data + * @linebuflen: total size of @linebuf, including space for terminating NUL + * @ascii: include ASCII after the hex output + * + * hex_dump_to_buffer() works on one "line" of output at a time, i.e., + * 16 or 32 bytes of input data converted to hex + ASCII output. + * + * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data + * to a hex + ASCII dump at the supplied memory location. + * The converted output is always NUL-terminated. + * + * E.g.: + * hex_dump_to_buffer(frame->data, frame->len, 16, 1, + * linebuf, sizeof(linebuf), true); + * + * example output buffer: + * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO + * + * Return: + * The amount of bytes placed in the buffer without terminating NUL. If the + * output was truncated, then the return value is the number of bytes + * (excluding the terminating NUL) which would have been written to the fi= nal + * string if enough space had been available. + */ +int hex_dump_to_buffer(const void *buf, size_t len, int rowsize, int group= size, + char *linebuf, size_t linebuflen, bool ascii) +{ + struct printbuf out =3D PRINTBUF_EXTERN(linebuf, linebuflen); + + prt_hex_line(&out, buf, len, rowsize, groupsize, ascii); + return out.pos; } EXPORT_SYMBOL(hex_dump_to_buffer); =20 @@ -262,6 +305,11 @@ void print_hex_dump(const char *level, const char *pre= fix_str, int prefix_type, int rowsize, int groupsize, const void *buf, size_t len, bool ascii) { + /* + * XXX: this code does the exact same thing as prt_hex_dump(): we should + * be able to call that and printk() the result, except printk is + * restricted to 1024 bytes of output per call + */ const u8 *ptr =3D buf; int i, linelen, remaining =3D len; unsigned char linebuf[32 * 3 + 2 + 32 + 1]; diff --git a/lib/test_hexdump.c b/lib/test_hexdump.c index 5144899d3c..f9e97879dc 100644 --- a/lib/test_hexdump.c +++ b/lib/test_hexdump.c @@ -25,36 +25,19 @@ static const char * const test_data_1[] __initconst =3D= { "4c", "d1", "19", "99", "43", "b1", "af", "0c", }; =20 -static const char * const test_data_2_le[] __initconst =3D { - "32be", "7bdb", "180a", "b293", - "ba70", "24c4", "837d", "9b34", - "9ca6", "ad31", "0f9c", "e9ac", - "d14c", "9919", "b143", "0caf", -}; - -static const char * const test_data_2_be[] __initconst =3D { +static const char * const test_data_2[] __initconst =3D { "be32", "db7b", "0a18", "93b2", "70ba", "c424", "7d83", "349b", "a69c", "31ad", "9c0f", "ace9", "4cd1", "1999", "43b1", "af0c", }; =20 -static const char * const test_data_4_le[] __initconst =3D { - "7bdb32be", "b293180a", "24c4ba70", "9b34837d", - "ad319ca6", "e9ac0f9c", "9919d14c", "0cafb143", -}; - -static const char * const test_data_4_be[] __initconst =3D { +static const char * const test_data_4[] __initconst =3D { "be32db7b", "0a1893b2", "70bac424", "7d83349b", "a69c31ad", "9c0face9", "4cd11999", "43b1af0c", }; =20 -static const char * const test_data_8_le[] __initconst =3D { - "b293180a7bdb32be", "9b34837d24c4ba70", - "e9ac0f9cad319ca6", "0cafb1439919d14c", -}; - -static const char * const test_data_8_be[] __initconst =3D { +static const char * const test_data_8[] __initconst =3D { "be32db7b0a1893b2", "70bac4247d83349b", "a69c31ad9c0face9", "4cd1199943b1af0c", }; @@ -73,7 +56,6 @@ static void __init test_hexdump_prepare_test(size_t len, = int rowsize, size_t l =3D len; int gs =3D groupsize, rs =3D rowsize; unsigned int i; - const bool is_be =3D IS_ENABLED(CONFIG_CPU_BIG_ENDIAN); =20 if (rs !=3D 16 && rs !=3D 32) rs =3D 16; @@ -85,11 +67,11 @@ static void __init test_hexdump_prepare_test(size_t len= , int rowsize, gs =3D 1; =20 if (gs =3D=3D 8) - result =3D is_be ? test_data_8_be : test_data_8_le; + result =3D test_data_8; else if (gs =3D=3D 4) - result =3D is_be ? test_data_4_be : test_data_4_le; + result =3D test_data_4; else if (gs =3D=3D 2) - result =3D is_be ? test_data_2_be : test_data_2_le; + result =3D test_data_2; else result =3D test_data_1; =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4982FC433EF for ; Sat, 4 Jun 2022 19:31:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240165AbiFDTbK (ORCPT ); Sat, 4 Jun 2022 15:31:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46910 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239929AbiFDTa7 (ORCPT ); Sat, 4 Jun 2022 15:30:59 -0400 Received: from mail-qk1-x733.google.com (mail-qk1-x733.google.com [IPv6:2607:f8b0:4864:20::733]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C7F902251B for ; Sat, 4 Jun 2022 12:30:58 -0700 (PDT) Received: by mail-qk1-x733.google.com with SMTP id o73so3422380qke.7 for ; Sat, 04 Jun 2022 12:30:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mjIR862E2LgyLcevyWp6TfuujVUQc54PnX3xUP5Jd7s=; b=HZDC0bmvjT+5VYL8OWw1rlUHmleIDkpsoMtEAaxU6RtY8fBSfM++3BC4ATxmUGjvk9 eOf02mksA7GrEH+902oe1lLDHcH10nZBypNBT/loFrW9ymeX4Fhahe9+yFYmbOLrEMvX CPKGKJlw6QHoVVviqgk7J1zD8DwLuVfjXURQs5XJZ22px17VNdNI03xmiSI0IzTBSzF+ TjHwjNjk52CSLwTyCLJNlKS4c6CCgTyV2j/MTAObl/vDh/vF1wO4gLz6lIoDpQd5vuQ+ ENJ91x/847fTSRtv/irEeghUnvqZXFS/0FMMEr5WPMUHMs0M43bVBqQtxzJLTSncD2ih f8Tg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mjIR862E2LgyLcevyWp6TfuujVUQc54PnX3xUP5Jd7s=; b=swl4FUQsLiYxlCZLirHDDvXIN6/ArazDov1DcfdEzwowc6ifEX3U94TuH2yB2NJ98a 44A1RP89tA5uGEo/vC2iaWaBHQxHV0x7IcIA0vQNFR/UmRxw0fff2I2PJzC6pIuDYj97 SIlh0QwQqVUbwjEUUl+65+qlXyKcPTGhSF1MQPp9X3R6f0hCV2EoEU5gU3RGGaZxfEEL HJuigKYlNWLKycS0U7lGx46NRlsae3PpCNPiyBSBoqise434aZegXY5tHDDVWlH15Obp UaznEQ0KDqtl6LB9AA9MmjqjQIAN2bYbT2d7taezqBFzROFGivF16maXGKdLtwY4UurB qyig== X-Gm-Message-State: AOAM533MLSkq/RhMSXnqT5KTuJpmRVTq5eQPwCWrUXBmi0E8L4w1TiKB B2aFPecPVBF2Yx82zX4x048pJOe8LeW6 X-Google-Smtp-Source: ABdhPJxMzLkksh4MvUhAIW5st+lWRa57IlBLJv/z5SNW0fec1gYOd5ho2vvHutWglThuCMWRzi9ORw== X-Received: by 2002:a37:a683:0:b0:6a6:ae13:7df8 with SMTP id p125-20020a37a683000000b006a6ae137df8mr2472594qke.385.1654371057456; Sat, 04 Jun 2022 12:30:57 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.30.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:30:56 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org, Matthew Wilcox Subject: [PATCH v3 05/33] vsprintf: %pf(%p) Date: Sat, 4 Jun 2022 15:30:14 -0400 Message-Id: <20220604193042.1674951-6-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This implements two new format strings: both do the same thing, one more compatible with current gcc format string checking, the other that we'd like to standardize: %pf(%p) - more compatible %(%p) - more prettier Both can take variable numbers of arguments, i.e. %(%p,%p,%p). They're used to indicate that snprintf or pr_buf should interpret the next argument as a pretty-printer function to call, and subsequent arguments within the parentheses should be passed to the pretty-printer. A pretty printer takes as its first argument a printbuf, and then zero or more pointer arguments - integer arguments are not (currently) supported. Example usage: static void foo_to_text(struct printbuf *out, struct foo *foo) { pr_buf(out, "bar=3D%u baz=3D%u", foo->bar, foo->baz); } printf("%(%p)", foo_to_text, foo); The goal is to replace most of our %p format extensions with this interface, and to move pretty-printers out of the core vsprintf.c code - this will get us better organization and better discoverability (you'll be able to cscope to pretty printer calls!), as well as eliminate a lot of dispatch code in vsprintf.c. Currently, we can only call pretty printers with pointer arguments. This could be changed to also allow at least integer arguments in the future by using libffi. Signed-off-by: Kent Overstreet Reviewed-by: Matthew Wilcox (Oracle) --- Documentation/core-api/printk-formats.rst | 22 ++++++ lib/test_printf.c | 20 ++++++ lib/vsprintf.c | 81 ++++++++++++++++++++++- 3 files changed, 121 insertions(+), 2 deletions(-) diff --git a/Documentation/core-api/printk-formats.rst b/Documentation/core= -api/printk-formats.rst index 5e89497ba3..8fc0b62af1 100644 --- a/Documentation/core-api/printk-formats.rst +++ b/Documentation/core-api/printk-formats.rst @@ -625,6 +625,28 @@ Examples:: %p4cc Y10 little-endian (0x20303159) %p4cc NV12 big-endian (0xb231564e) =20 +Calling a pretty printer function +--------------------------------- + +:: + + %pf(%p) pretty printer function taking one argument + %pf(%p,%p) pretty printer function taking two arguments + +For calling generic pretty printers. A pretty printer is a function that t= akes +as its first argument a pointer to a printbuf, and then zero or more addit= ional +pointer arguments. For example: + + void foo_to_text(struct printbuf *out, struct foo *foo) + { + pr_buf(out, "bar=3D%u baz=3D%u", foo->bar, foo->baz); + } + + printf("%pf(%p)", foo_to_text, foo); + +Note that a pretty-printer may not sleep, if called from printk(). If call= ed +from pr_buf() or sprintf() there are no such restrictions. + Thanks =3D=3D=3D=3D=3D=3D =20 diff --git a/lib/test_printf.c b/lib/test_printf.c index 07309c45f3..ff833870f5 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -783,6 +783,25 @@ test_pointer(void) fourcc_pointer(); } =20 +static void printf_test_fn(struct printbuf *out, void *p) +{ + int *i =3D p; + + prt_printf(out, "%i", *i); +} + +static void __init +test_fn(void) +{ + int i =3D 1; + + test("1", "%pf(%p)", printf_test_fn, &i); + /* + * Not tested, so we don't fail the build with -Werror: + */ + //test("1", "%(%p)", printf_test_fn, &i); +} + static void __init selftest(void) { alloced_buffer =3D kmalloc(BUF_SIZE + 2*PAD_SIZE, GFP_KERNEL); @@ -794,6 +813,7 @@ static void __init selftest(void) test_number(); test_string(); test_pointer(); + test_fn(); =20 kfree(alloced_buffer); } diff --git a/lib/vsprintf.c b/lib/vsprintf.c index b686dafb2f..118d6f65c3 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -436,7 +436,8 @@ enum format_type { FORMAT_TYPE_UINT, FORMAT_TYPE_INT, FORMAT_TYPE_SIZE_T, - FORMAT_TYPE_PTRDIFF + FORMAT_TYPE_PTRDIFF, + FORMAT_TYPE_FN, }; =20 struct printf_spec { @@ -2519,7 +2520,16 @@ int format_decode(const char *fmt, struct printf_spe= c *spec) return ++fmt - start; =20 case 'p': - spec->type =3D FORMAT_TYPE_PTR; + fmt++; + if (fmt[0] =3D=3D 'f' && + fmt[1] =3D=3D '(') { + fmt +=3D 2; + spec->type =3D FORMAT_TYPE_FN; + } else + spec->type =3D FORMAT_TYPE_PTR; + return fmt - start; + case '(': + spec->type =3D FORMAT_TYPE_FN; return ++fmt - start; =20 case '%': @@ -2601,6 +2611,49 @@ set_precision(struct printf_spec *spec, int prec) } } =20 +static void call_prt_fn(struct printbuf *out, void *fn, void **fn_args, un= signed nr_args) +{ + typedef void (*printf_fn_0)(struct printbuf *); + typedef void (*printf_fn_1)(struct printbuf *, void *); + typedef void (*printf_fn_2)(struct printbuf *, void *, void *); + typedef void (*printf_fn_3)(struct printbuf *, void *, void *, void *); + typedef void (*printf_fn_4)(struct printbuf *, void *, void *, void *, vo= id *); + typedef void (*printf_fn_5)(struct printbuf *, void *, void *, void *, vo= id *, void *); + typedef void (*printf_fn_6)(struct printbuf *, void *, void *, void *, vo= id *, void *, void *); + typedef void (*printf_fn_7)(struct printbuf *, void *, void *, void *, vo= id *, void *, void *, void *); + typedef void (*printf_fn_8)(struct printbuf *, void *, void *, void *, vo= id *, void *, void *, void *, void *); + + switch (nr_args) { + case 0: + ((printf_fn_0)fn)(out); + break; + case 1: + ((printf_fn_1)fn)(out, fn_args[0]); + break; + case 2: + ((printf_fn_2)fn)(out, fn_args[0], fn_args[1]); + break; + case 3: + ((printf_fn_3)fn)(out, fn_args[0], fn_args[1], fn_args[2]); + break; + case 4: + ((printf_fn_4)fn)(out, fn_args[0], fn_args[1], fn_args[2], fn_args[3]); + break; + case 5: + ((printf_fn_5)fn)(out, fn_args[0], fn_args[1], fn_args[2], fn_args[3], f= n_args[4]); + break; + case 6: + ((printf_fn_6)fn)(out, fn_args[0], fn_args[1], fn_args[2], fn_args[3], f= n_args[4], fn_args[5]); + break; + case 7: + ((printf_fn_7)fn)(out, fn_args[0], fn_args[1], fn_args[2], fn_args[3], f= n_args[4], fn_args[5], fn_args[6]); + break; + case 8: + ((printf_fn_8)fn)(out, fn_args[0], fn_args[1], fn_args[2], fn_args[3], f= n_args[4], fn_args[5], fn_args[6], fn_args[7]); + break; + } +} + /** * prt_vprintf - Format a string, outputting to a printbuf * @out: The printbuf to output to @@ -2664,6 +2717,30 @@ void prt_vprintf(struct printbuf *out, const char *f= mt, va_list args) fmt++; break; =20 + case FORMAT_TYPE_FN: { + unsigned nr_args =3D 0; + void *fn_args[8]; + void *fn =3D va_arg(args, void *); + + while (1) { + if (WARN_ON_ONCE(nr_args =3D=3D ARRAY_SIZE(fn_args))) + goto out; + if (*fmt++ !=3D '%') + goto out; + if (*fmt++ !=3D 'p') + goto out; + fn_args[nr_args++] =3D va_arg(args, void *); + if (*fmt =3D=3D ')') + break; + if (*fmt++ !=3D ',') + goto out; + } + + call_prt_fn(out, fn, fn_args, nr_args); + fmt++; /* past trailing ) */ + break; + } + case FORMAT_TYPE_PERCENT_CHAR: __prt_char(out, '%'); break; --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3CFBAC43334 for ; Sat, 4 Jun 2022 19:31:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240263AbiFDTbW (ORCPT ); Sat, 4 Jun 2022 15:31:22 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240076AbiFDTbE (ORCPT ); Sat, 4 Jun 2022 15:31:04 -0400 Received: from mail-qk1-x72c.google.com (mail-qk1-x72c.google.com [IPv6:2607:f8b0:4864:20::72c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 294764F479 for ; Sat, 4 Jun 2022 12:31:00 -0700 (PDT) Received: by mail-qk1-x72c.google.com with SMTP id br33so6651041qkb.0 for ; Sat, 04 Jun 2022 12:30:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VuSGpywTiP+XNlJFgYYd30bm0eWVeLuCUR5InbQcSJk=; b=aRcJJPa0fMAqsl7O6dSdeTYtZq958RKkNPREaJ9rAb4nFT93yGzWSGbwI5vjehvPuo 2w7oJzlYK1iOtNA3+kuLL4EfQxcufSTiKCG5YHx0xJ/LEDdcD8mYTFL/QkRWvMxqyzBd k8E+cs5XWl1QfVLklBWDy6NS20CI6tcDGDpt2TYQJFTqvq5tNkdnLhmEnaXaN7YLu4bb 3OVs6dEQwM7sVoWB67IRPum1FEf7FvvZQvB8BpJWcEqQIPgrVfmUZnNuBNhMIFajIsEl H4AXTXWrUlzVMtqA8hIav8D+gaSGGhYcVZKCo1PF/nBJnDejdkQJQkliW1i9JFwuu+Ss 4/2Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VuSGpywTiP+XNlJFgYYd30bm0eWVeLuCUR5InbQcSJk=; b=oRcHpNnsneN4mV1E4ccRGwCW1FYJbzpIBkkJxibhvzNm0+k7K2ly1hc4ck+70dB60W +iaxQHRu4giVyoZ++gQPDHjhlt54vga4FJajRZaTw5vMVNr1DsEGu7drxY+R24llTFP7 9y/9RrfEwiNUd6vzfPkZsda6zwiCdN++xHI5EIu2/ODEB/r+yx2KBZ1vFFQtseDgC3RD 1JiGYcKwuWBpBzpu4vZvZYb402DlTXyvPiz2xu0L9TFi1E9HrcROsFtjkHjYDOVxX4Tx fZegg95dQ9m2QkN1RRLV2jrc4sUlOm3pxCakN6C9AAWsM81BsgQwSWZYtWHS2HMuhEpo 7nYQ== X-Gm-Message-State: AOAM530WHHjcBm5i+b89aHA7JQiOPsE0/8AnEkxPc6VfSKDhW3viAdTD 5sD+QznbGxi27iBd6QmkK+srEstQnTJO X-Google-Smtp-Source: ABdhPJwAzHY46X7uc03KPavJ/ytAC51QD5yixFjg1AjRyfYaUCtWbbAJf7CGspJ/+Z8M9PyN9pAKQQ== X-Received: by 2002:a05:620a:44c6:b0:6a5:a3c9:bf6b with SMTP id y6-20020a05620a44c600b006a5a3c9bf6bmr11082955qkp.100.1654371059128; Sat, 04 Jun 2022 12:30:59 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.30.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:30:58 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 06/33] lib/string_helpers: string_get_size() now returns characters wrote Date: Sat, 4 Jun 2022 15:30:15 -0400 Message-Id: <20220604193042.1674951-7-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" printbuf now needs to know the number of characters that would have been written if the buffer was too small, like snprintf(); this changes string_get_size() to return the the return value of snprintf(). Signed-off-by: Kent Overstreet --- include/linux/string_helpers.h | 4 ++-- lib/string_helpers.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/include/linux/string_helpers.h b/include/linux/string_helpers.h index 67de398944..52e0f1d283 100644 --- a/include/linux/string_helpers.h +++ b/include/linux/string_helpers.h @@ -19,8 +19,8 @@ enum string_size_units { STRING_UNITS_2, /* use binary powers of 2^10 */ }; =20 -void string_get_size(u64 size, u64 blk_size, enum string_size_units units, - char *buf, int len); +int string_get_size(u64 size, u64 blk_size, enum string_size_units units, + char *buf, int len); =20 #define UNESCAPE_SPACE BIT(0) #define UNESCAPE_OCTAL BIT(1) diff --git a/lib/string_helpers.c b/lib/string_helpers.c index 3b1118337e..22aa161005 100644 --- a/lib/string_helpers.c +++ b/lib/string_helpers.c @@ -33,8 +33,8 @@ * at least 9 bytes and will always be zero terminated. * */ -void string_get_size(u64 size, u64 blk_size, const enum string_size_units = units, - char *buf, int len) +int string_get_size(u64 size, u64 blk_size, const enum string_size_units u= nits, + char *buf, int len) { static const char *const units_10[] =3D { "B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" @@ -127,8 +127,7 @@ void string_get_size(u64 size, u64 blk_size, const enum= string_size_units units, else unit =3D units_str[units][i]; =20 - snprintf(buf, len, "%u%s %s", (u32)size, - tmp, unit); + return snprintf(buf, len, "%u%s %s", (u32)size, tmp, unit); } EXPORT_SYMBOL(string_get_size); =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C037C43334 for ; Sat, 4 Jun 2022 19:31:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240200AbiFDTbx (ORCPT ); Sat, 4 Jun 2022 15:31:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240123AbiFDTbH (ORCPT ); Sat, 4 Jun 2022 15:31:07 -0400 Received: from mail-qk1-x736.google.com (mail-qk1-x736.google.com [IPv6:2607:f8b0:4864:20::736]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DBBD04F9CC for ; Sat, 4 Jun 2022 12:31:01 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id m68so8372010qkb.9 for ; Sat, 04 Jun 2022 12:31:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=MU9DtaSuF50B3IjXtdJRPfGcH4KUhigTNIeUQnFwNis=; b=I6O6qa9R3mrhrhGhFya4ywOG0hY24R5AAUSmtWprus0S2GogvRjDBcOlBqZ8dvVqBN 2CkX9+A0uBITuwjHnP8EqW3TspJAO5MYRgVent0RWEwzyVQRi1TC9AnzjHWXK7EGKKsk jbohjgq2g6DKOY7QYHeppJCZCTWkR5uqm9erwmo1RH3unu0QniO7HjaG8g3Bthyoosqz 7e5tIXNLAKvyBgCYCbdcjRfZSo0NzQbL4/o6QzOtmQEPEaPN8xCXFm4mQbd52CMGujNE 1YH4S+13liqReBsswAl9hn1hmph07qO8Qgf2CtYVaLEcwd9H/Qgzn12QgA/RL8T+OkeL TM9w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=MU9DtaSuF50B3IjXtdJRPfGcH4KUhigTNIeUQnFwNis=; b=TCb8aX1kSFVTvn0Ea9ptkEyG8bEkyByOh3yZE5CxUR/TOzy+8vICkh2yWl/SJ5gIn6 5PANj/bCsBmcWthBzHIe62ax7il8rlN9dB+0eXPZ4fnX9VI9sghfiE8/cbfFGCEylabs mLtRFARxo1m3StIJA/M6eqpBHddBHadVT1z+wX1v/bt8XvKpODAgg32mcl7Qt1h0NroS psPpdDV+LhiWw8owGOvEyv+Q+v3YBaO7KQqBx2BFDR98VHjVDHf9a0GDTu7G166Ur+ns 94ppHkJro0Hb6w3QwBFVghQvjNy9tSieW2uI+ioeyo66nhlnAWpV/05TE6azPUxDgA6T TrIg== X-Gm-Message-State: AOAM5301v4UKuyU8XjH+8tVLBQL9FE2m9R1D9aXUk67ECI1hDmKjBLCU HpxOzgrboCcf4gGvZMiqhzS6046HlWZG X-Google-Smtp-Source: ABdhPJx5b7OWtFu4vTDQFtt0vq8apRehNU0egcz3GMQXo6Mgh524Y0Tc5CwIbDP7NPXrtuBAWIpUkA== X-Received: by 2002:a05:620a:2586:b0:680:f846:4708 with SMTP id x6-20020a05620a258600b00680f8464708mr10997183qko.654.1654371060527; Sat, 04 Jun 2022 12:31:00 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.30.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:30:59 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 07/33] lib/printbuf: Heap allocation Date: Sat, 4 Jun 2022 15:30:16 -0400 Message-Id: <20220604193042.1674951-8-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This makes printbufs optionally heap allocated: a printbuf initialized with the PRINTBUF initializer will automatically heap allocate and resize as needed. Allocations are done with GFP_KERNEL: code should use e.g. memalloc_nofs_save()/restore() as needed. Since we do not currently have memalloc_nowait_save()/restore(), in contexts where it is not safe to block we provide the helpers printbuf_atomic_inc() printbuf_atomic_dec() When the atomic count is nonzero, memory allocations will be done with GFP_NOWAIT. On memory allocation failure, output will be truncated. Code that wishes to check for memory allocation failure (in contexts where we should return -ENOMEM) should check if printbuf->allocation_failure is set. Since printbufs are expected to be typically used for log messages and on a best effort basis, we don't return errors directly. Other helpers provided by this patch: - printbuf_make_room(buf, extra) Reallocates if necessary to make room for @extra bytes (not including terminating null). - printbuf_str(buf) Returns a null terminated string equivalent to the contents of @buf. If @buf was never allocated (or allocation failed), returns a constant empty string. - printbuf_exit(buf) Releases memory allocated by a printbuf. Signed-off-by: Kent Overstreet --- include/linux/printbuf.h | 114 +++++++++++++++++++++++++++++++++------ lib/Makefile | 2 +- lib/printbuf.c | 70 ++++++++++++++++++++++++ 3 files changed, 170 insertions(+), 16 deletions(-) create mode 100644 lib/printbuf.c diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h index 8b3797dc4b..35236f774a 100644 --- a/include/linux/printbuf.h +++ b/include/linux/printbuf.h @@ -4,18 +4,68 @@ #ifndef _LINUX_PRINTBUF_H #define _LINUX_PRINTBUF_H =20 -#include - /* - * Printbufs: String buffer for outputting (printing) to, for vsnprintf + * Printbufs: Simple strings for printing to, with optional heap allocation + * + * This code has provisions for use in userspace, to aid in making other c= ode + * portable between kernelspace and userspace. + * + * Basic example: + * struct printbuf buf =3D PRINTBUF; + * + * prt_printf(&buf, "foo=3D"); + * foo_to_text(&buf, foo); + * printk("%s", buf.buf); + * printbuf_exit(&buf); + * + * Or + * struct printbuf buf =3D PRINTBUF_EXTERN(char_buf, char_buf_size) + * + * We can now write pretty printers instead of writing code that dumps + * everything to the kernel log buffer, and then those pretty-printers can= be + * used by other code that outputs to kernel log, sysfs, debugfs, etc. + * + * Memory allocation: Outputing to a printbuf may allocate memory. This + * allocation is done with GFP_KERNEL, by default: use the newer + * memalloc_*_(save|restore) functions as needed. + * + * Since no equivalent yet exists for GFP_ATOMIC/GFP_NOWAIT, memory alloca= tions + * will be done with GFP_NOWAIT if printbuf->atomic is nonzero. + * + * Memory allocation failures: We don't return errors directly, because on + * memory allocation failure we usually don't want to bail out and unwind = - we + * want to print what we've got, on a best-effort basis. But code that doe= s want + * to return -ENOMEM may check printbuf.allocation_failure. */ =20 +#include + struct printbuf { char *buf; unsigned size; unsigned pos; + /* + * If nonzero, allocations will be done with GFP_ATOMIC: + */ + u8 atomic; + bool allocation_failure:1; + bool heap_allocated:1; }; =20 +int printbuf_make_room(struct printbuf *, unsigned); +const char *printbuf_str(const struct printbuf *); +void printbuf_exit(struct printbuf *); + +/* Initializer for a heap allocated printbuf: */ +#define PRINTBUF ((struct printbuf) { .heap_allocated =3D true }) + +/* Initializer a printbuf that points to an external buffer: */ +#define PRINTBUF_EXTERN(_buf, _size) \ +((struct printbuf) { \ + .buf =3D _buf, \ + .size =3D _size, \ +}) + /* * Returns size remaining of output buffer: */ @@ -48,13 +98,15 @@ static inline bool printbuf_overflowed(struct printbuf = *out) =20 static inline void printbuf_nul_terminate(struct printbuf *out) { + printbuf_make_room(out, 1); + if (out->pos < out->size) out->buf[out->pos] =3D 0; else if (out->size) out->buf[out->size - 1] =3D 0; } =20 -static inline void __prt_chars(struct printbuf *out, char c, unsigned n) +static inline void __prt_chars_reserved(struct printbuf *out, char c, unsi= gned n) { memset(out->buf + out->pos, c, @@ -64,17 +116,26 @@ static inline void __prt_chars(struct printbuf *out, c= har c, unsigned n) =20 static inline void prt_chars(struct printbuf *out, char c, unsigned n) { - __prt_chars(out, c, n); + printbuf_make_room(out, n); + __prt_chars_reserved(out, c, n); printbuf_nul_terminate(out); } =20 -static inline void __prt_char(struct printbuf *out, char c) +/* Doesn't call printbuf_make_room(), doesn't nul terminate: */ +static inline void __prt_char_reserved(struct printbuf *out, char c) { if (printbuf_remaining(out)) out->buf[out->pos] =3D c; out->pos++; } =20 +/* Doesn't nul terminate: */ +static inline void __prt_char(struct printbuf *out, char c) +{ + printbuf_make_room(out, 1); + __prt_char_reserved(out, c); +} + static inline void prt_char(struct printbuf *out, char c) { __prt_char(out, c); @@ -83,6 +144,8 @@ static inline void prt_char(struct printbuf *out, char c) =20 static inline void prt_bytes(struct printbuf *out, const void *b, unsigned= n) { + printbuf_make_room(out, n); + memcpy(out->buf + out->pos, b, min(n, printbuf_remaining(out))); @@ -97,22 +160,43 @@ static inline void prt_str(struct printbuf *out, const= char *str) =20 static inline void prt_hex_byte(struct printbuf *out, u8 byte) { - __prt_char(out, hex_asc_hi(byte)); - __prt_char(out, hex_asc_lo(byte)); + printbuf_make_room(out, 2); + __prt_char_reserved(out, hex_asc_hi(byte)); + __prt_char_reserved(out, hex_asc_lo(byte)); printbuf_nul_terminate(out); } =20 static inline void prt_hex_byte_upper(struct printbuf *out, u8 byte) { - __prt_char(out, hex_asc_upper_hi(byte)); - __prt_char(out, hex_asc_upper_lo(byte)); + printbuf_make_room(out, 2); + __prt_char_reserved(out, hex_asc_upper_hi(byte)); + __prt_char_reserved(out, hex_asc_upper_lo(byte)); printbuf_nul_terminate(out); } =20 -#define PRINTBUF_EXTERN(_buf, _size) \ -((struct printbuf) { \ - .buf =3D _buf, \ - .size =3D _size, \ -}) +/** + * printbuf_reset - re-use a printbuf without freeing and re-initializing = it: + */ +static inline void printbuf_reset(struct printbuf *buf) +{ + buf->pos =3D 0; + buf->allocation_failure =3D 0; +} + +/** + * printbuf_atomic_inc - mark as entering an atomic section + */ +static inline void printbuf_atomic_inc(struct printbuf *buf) +{ + buf->atomic++; +} + +/** + * printbuf_atomic_inc - mark as leaving an atomic section + */ +static inline void printbuf_atomic_dec(struct printbuf *buf) +{ + buf->atomic--; +} =20 #endif /* _LINUX_PRINTBUF_H */ diff --git a/lib/Makefile b/lib/Makefile index 6b9ffc1bd1..b4609a4258 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -34,7 +34,7 @@ lib-y :=3D ctype.o string.o vsprintf.o cmdline.o \ is_single_threaded.o plist.o decompress.o kobject_uevent.o \ earlycpio.o seq_buf.o siphash.o dec_and_lock.o \ nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o \ - buildid.o + buildid.o printbuf.o =20 lib-$(CONFIG_PRINTK) +=3D dump_stack.o lib-$(CONFIG_SMP) +=3D cpumask.o diff --git a/lib/printbuf.c b/lib/printbuf.c new file mode 100644 index 0000000000..0093b34158 --- /dev/null +++ b/lib/printbuf.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: LGPL-2.1+ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifdef __KERNEL__ +#include +#include +#else +#define EXPORT_SYMBOL(x) +#endif + +#include +#include + +int printbuf_make_room(struct printbuf *out, unsigned extra) +{ + unsigned new_size; + char *buf; + + if (!out->heap_allocated) + return 0; + + /* Reserved space for terminating nul: */ + extra +=3D 1; + + if (out->pos + extra < out->size) + return 0; + + new_size =3D roundup_pow_of_two(out->size + extra); + buf =3D krealloc(out->buf, new_size, !out->atomic ? GFP_KERNEL : GFP_NOWA= IT); + + if (!buf) { + out->allocation_failure =3D true; + return -ENOMEM; + } + + out->buf =3D buf; + out->size =3D new_size; + return 0; +} +EXPORT_SYMBOL(printbuf_make_room); + +/** + * printbuf_str - returns printbuf's buf as a C string, guaranteed to be n= ull + * terminated + */ +const char *printbuf_str(const struct printbuf *buf) +{ + /* + * If we've written to a printbuf then it's guaranteed to be a null + * terminated string - but if we haven't, then we might not have + * allocated a buffer at all: + */ + return buf->pos + ? buf->buf + : ""; +} +EXPORT_SYMBOL(printbuf_str); + +/** + * printbuf_exit - exit a printbuf, freeing memory it owns and poisoning it + * against accidental use. + */ +void printbuf_exit(struct printbuf *buf) +{ + if (buf->heap_allocated) { + kfree(buf->buf); + buf->buf =3D ERR_PTR(-EINTR); /* poison value */ + } +} +EXPORT_SYMBOL(printbuf_exit); --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 00775C43334 for ; Sat, 4 Jun 2022 19:31:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240290AbiFDTba (ORCPT ); Sat, 4 Jun 2022 15:31:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47188 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240091AbiFDTbI (ORCPT ); Sat, 4 Jun 2022 15:31:08 -0400 Received: from mail-qt1-x834.google.com (mail-qt1-x834.google.com [IPv6:2607:f8b0:4864:20::834]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 84B4F4F9DD for ; Sat, 4 Jun 2022 12:31:03 -0700 (PDT) Received: by mail-qt1-x834.google.com with SMTP id j8so5184965qtn.13 for ; Sat, 04 Jun 2022 12:31:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=k/S9RyrnAxoxBJABrQh6w4keA3WMxhL6CB9ATTh+2iM=; b=kX5pVQfSHOnNdg7M682y9YLafSoDvPyLol0a+J1ubVd6S/w3RxV8ZLbMUiaKYIADtx 6N/IUYDkEigm2PS+DxW5vQTLVgkuN39sabY1YsKYYjea73WUgpl6eWngEpuIa2xofdH6 cTq/tfvO+3hDSFgclGTJ3wi1dDSIqoZZ1xnyrduucSaFT985PZAHnpUzyQLyEqc6XMwh 18L76hF4rQthxkC7KOkXsDJLlVttEyPIPIA6J5yjTibyxxq9yIIu009oNYu/l9w1Zppy 4MTEWb+nV0Gsqxia8SG4dwY2bCV7pPLpWHXapGQ8vOaGLeKCtBzbPV/OQGhw35g+EnmN 2xow== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=k/S9RyrnAxoxBJABrQh6w4keA3WMxhL6CB9ATTh+2iM=; b=W1Yt7GV30bvICpRkGkDtSBSoftGQN7K+wLzyCj2/2A7ntooeXkWc+XLCRB5LTCd3cA TzLGZemoD64Kikc7IlQbtqEW7V6zLIxKXhTk+etQ6C9xdoPnqyN4lCrz3bBO6Wnvpoxc zgG06qmh4b2xmFjVGG/PqRLK7LRVuuyMi91sP/oVPdaHiywlTe5G7MEcR/y0yBUvTxQm /T6mflTBTAGBcC32zbpl9Z8gmMlSOFeq07Bt8uqu+EIA/s9MB//ynCi5pmEKgKcvcjeV ngU2lHEfInJeuJeG8WMtgICbhJ8h92j7jcS5i2l6who+9RzIVLpdNeYuDuX+FNCJ3qdh AFHw== X-Gm-Message-State: AOAM531j/6wxbg3BrlonX0igOvWILL9RjdiNJRz5/Ls2p+k8isbt7FoC MDOwWU1a1JDHm4G+Nmo/dpnPM6O2N8NU X-Google-Smtp-Source: ABdhPJwaIXSDa0tsBhfJ3waTACNu9eec31qez1/QbublcTeTg39UNK7pcHeatPta8E5bSZ6wRNFSgQ== X-Received: by 2002:a05:622a:292:b0:304:3b6e:3f49 with SMTP id z18-20020a05622a029200b003043b6e3f49mr13106649qtw.613.1654371061997; Sat, 04 Jun 2022 12:31:01 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:01 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 08/33] lib/printbuf: Tabstops, indenting Date: Sat, 4 Jun 2022 15:30:17 -0400 Message-Id: <20220604193042.1674951-9-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch adds two new features to printbuf for structured formatting: - Indent level: the indent level, as a number of spaces, may be increased with pr_indent_add() and decreased with pr_indent_sub(). Subsequent lines, when started with pr_newline() (not "\n", although that may change) will then be intended according to the current indent level. This helps with pretty-printers that structure a large amonut of data across multiple lines and multiple functions. - Tabstops: Tabstops may be set by assigning to the printbuf->tabstops array. Then, pr_tab() may be used to advance to the next tabstop, printing as many spaces as required - leaving previous output left justified to the previous tabstop. pr_tab_rjust() advances to the next tabstop but inserts the spaces just after the previous tabstop - right justifying the previously-outputted text to the next tabstop. Signed-off-by: Kent Overstreet --- include/linux/printbuf.h | 28 +++++++++ lib/printbuf.c | 125 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h index 35236f774a..8fb074eb67 100644 --- a/include/linux/printbuf.h +++ b/include/linux/printbuf.h @@ -36,6 +36,23 @@ * memory allocation failure we usually don't want to bail out and unwind = - we * want to print what we've got, on a best-effort basis. But code that doe= s want * to return -ENOMEM may check printbuf.allocation_failure. + * + * Indenting, tabstops: + * + * To aid is writing multi-line pretty printers spread across multiple + * functions, printbufs track the current indent level. + * + * printbuf_indent_push() and printbuf_indent_pop() increase and decrease = the current indent + * level, respectively. + * + * To use tabstops, set printbuf->tabstops[]; they are in units of spaces,= from + * start of line. Once set, prt_tab() will output spaces up to the next ta= bstop. + * prt_tab_rjust() will also advance the current line of text up to the ne= xt + * tabstop, but it does so by shifting text since the previous tabstop up = to the + * next tabstop - right justifying it. + * + * Make sure you use prt_newline() instead of \n in the format string for = indent + * level and tabstops to work corretly. */ =20 #include @@ -44,18 +61,29 @@ struct printbuf { char *buf; unsigned size; unsigned pos; + unsigned last_newline; + unsigned last_field; + unsigned indent; /* * If nonzero, allocations will be done with GFP_ATOMIC: */ u8 atomic; bool allocation_failure:1; bool heap_allocated:1; + u8 tabstop; + u8 tabstops[4]; }; =20 int printbuf_make_room(struct printbuf *, unsigned); const char *printbuf_str(const struct printbuf *); void printbuf_exit(struct printbuf *); =20 +void prt_newline(struct printbuf *); +void printbuf_indent_add(struct printbuf *, unsigned); +void printbuf_indent_sub(struct printbuf *, unsigned); +void prt_tab(struct printbuf *); +void prt_tab_rjust(struct printbuf *); + /* Initializer for a heap allocated printbuf: */ #define PRINTBUF ((struct printbuf) { .heap_allocated =3D true }) =20 diff --git a/lib/printbuf.c b/lib/printbuf.c index 0093b34158..e11a504abf 100644 --- a/lib/printbuf.c +++ b/lib/printbuf.c @@ -11,6 +11,11 @@ #include #include =20 +static inline size_t printbuf_linelen(struct printbuf *buf) +{ + return buf->pos - buf->last_newline; +} + int printbuf_make_room(struct printbuf *out, unsigned extra) { unsigned new_size; @@ -68,3 +73,123 @@ void printbuf_exit(struct printbuf *buf) } } EXPORT_SYMBOL(printbuf_exit); + +void prt_newline(struct printbuf *buf) +{ + unsigned i; + + printbuf_make_room(buf, 1 + buf->indent); + + __prt_char(buf, '\n'); + + buf->last_newline =3D buf->pos; + + for (i =3D 0; i < buf->indent; i++) + __prt_char(buf, ' '); + + printbuf_nul_terminate(buf); + + buf->last_field =3D buf->pos; + buf->tabstop =3D 0; +} +EXPORT_SYMBOL(prt_newline); + +/** + * printbuf_indent_add - add to the current indent level + * + * @buf: printbuf to control + * @spaces: number of spaces to add to the current indent level + * + * Subsequent lines, and the current line if the output position is at the= start + * of the current line, will be indented by @spaces more spaces. + */ +void printbuf_indent_add(struct printbuf *buf, unsigned spaces) +{ + if (WARN_ON_ONCE(buf->indent + spaces < buf->indent)) + spaces =3D 0; + + buf->indent +=3D spaces; + while (spaces--) + prt_char(buf, ' '); +} +EXPORT_SYMBOL(printbuf_indent_add); + +/** + * printbuf_indent_sub - subtract from the current indent level + * + * @buf: printbuf to control + * @spaces: number of spaces to subtract from the current indent level + * + * Subsequent lines, and the current line if the output position is at the= start + * of the current line, will be indented by @spaces less spaces. + */ +void printbuf_indent_sub(struct printbuf *buf, unsigned spaces) +{ + if (WARN_ON_ONCE(spaces > buf->indent)) + spaces =3D buf->indent; + + if (buf->last_newline + buf->indent =3D=3D buf->pos) { + buf->pos -=3D spaces; + printbuf_nul_terminate(buf); + } + buf->indent -=3D spaces; +} +EXPORT_SYMBOL(printbuf_indent_sub); + +/** + * prt_tab - Advance printbuf to the next tabstop + * + * @buf: printbuf to control + * + * Advance output to the next tabstop by printing spaces. + */ +void prt_tab(struct printbuf *out) +{ + int spaces =3D max_t(int, 0, out->tabstops[out->tabstop] - printbuf_linel= en(out)); + + BUG_ON(out->tabstop > ARRAY_SIZE(out->tabstops)); + + prt_chars(out, ' ', spaces); + + out->last_field =3D out->pos; + out->tabstop++; +} +EXPORT_SYMBOL(prt_tab); + +/** + * prt_tab_rjust - Advance printbuf to the next tabstop, right justifying + * previous output + * + * @buf: printbuf to control + * + * Advance output to the next tabstop by inserting spaces immediately afte= r the + * previous tabstop, right justifying previously outputted text. + */ +void prt_tab_rjust(struct printbuf *buf) +{ + BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops)); + + if (printbuf_linelen(buf) < buf->tabstops[buf->tabstop]) { + unsigned move =3D buf->pos - buf->last_field; + unsigned shift =3D buf->tabstops[buf->tabstop] - + printbuf_linelen(buf); + + printbuf_make_room(buf, shift); + + if (buf->last_field + shift < buf->size) + memmove(buf->buf + buf->last_field + shift, + buf->buf + buf->last_field, + min(move, buf->size - 1 - buf->last_field - shift)); + + if (buf->last_field < buf->size) + memset(buf->buf + buf->last_field, ' ', + min(shift, buf->size - buf->last_field)); + + buf->pos +=3D shift; + printbuf_nul_terminate(buf); + } + + buf->last_field =3D buf->pos; + buf->tabstop++; +} +EXPORT_SYMBOL(prt_tab_rjust); --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99AFEC43334 for ; Sat, 4 Jun 2022 19:31:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240322AbiFDTbh (ORCPT ); Sat, 4 Jun 2022 15:31:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240093AbiFDTbI (ORCPT ); Sat, 4 Jun 2022 15:31:08 -0400 Received: from mail-qt1-x830.google.com (mail-qt1-x830.google.com [IPv6:2607:f8b0:4864:20::830]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D411D3388E for ; Sat, 4 Jun 2022 12:31:04 -0700 (PDT) Received: by mail-qt1-x830.google.com with SMTP id x16so4677545qtw.12 for ; Sat, 04 Jun 2022 12:31:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=sKb2EhCeklsdRsNI2YgRpJ34oLvZStS1bp2Vbt3uYtI=; b=c5Mv+jemCw0Zq3bfauzSeyeEO6D4d5jCRvMdGwhV3PqzD7pmreLQcvL9GujP2zip4/ PABVDtalGEr20tVUR/7VVLgh7TLH2VQ7a24DfvZV8ftkt2GiQkmdC0O6GI1nxt5YmInH a0kWKsGb4gnfzaR68WRErtBIZ4r1PMyeXkR8zTzhkZ3XUmR6/g/23sVrhxzpimqtIbQV HHo2FakfY2dCANg/NncP23lRjPjvepLgtQksqIsqWd/NNPM8GCLIzMCjFQEGOf6cZawd il8cRaj5y78QXRGLlV6aSA1QclGJMI9xJ2tTtgpL3rG6EdvQBcm2INoLSDTpMl4sEfzP RvLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sKb2EhCeklsdRsNI2YgRpJ34oLvZStS1bp2Vbt3uYtI=; b=n46Z6alNP8mDZaon22v4TshwWfYBVQi1ZPhE7th3sDor+O1s2/Gqqpw1GNauIbQcwu bxxZYZHWx+UfgeJKf+0kcqt99xGPFliSM5xrDGfx7vHpjhm8c8vwgXzfffovvFcwTXbH 5PSZl4EyfkBiKe7ndviL4ebyKm1cZkI/SznIFPpJ+kkmsrkZbJl1vFRB1EiS8rJ7A6ZW fTCUVBiW9kvCeNkkwEH/1m1L8WGaVX3XyEvhbmdJ2mvvAwFycv6TkKs5gadWkBO9HGu1 vVG2+CcVRN8cN3iD84nMMdb7fnNdXefsAw9gkJsVo+w37YfNePz2nlssOqlIwXd37ELK 70SQ== X-Gm-Message-State: AOAM5337pkNyAcCF65qF/AhJKbhAaWnbXU3K5ZKl6bDe0RRvG4JSNRKl 5dyZp5CI0+UpeAD82DHsJ9keNr6Xyw4U X-Google-Smtp-Source: ABdhPJzkXjLJzjLhssNceqtD/ETx33XcAOdJGR14+fjgysVdAF2hLM3bTZFtIExMUB4ErNWvgjEmFQ== X-Received: by 2002:ac8:7f92:0:b0:304:c4c0:f032 with SMTP id z18-20020ac87f92000000b00304c4c0f032mr12759448qtj.273.1654371063506; Sat, 04 Jun 2022 12:31:03 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:02 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 09/33] lib/printbuf: Unit specifiers Date: Sat, 4 Jun 2022 15:30:18 -0400 Message-Id: <20220604193042.1674951-10-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds options to printbuf for specifying whether units should be printed raw (default) or with human readable units, and for controlling whether human-readable units should be base 2 (default), or base 10. This also adds new helpers that obey these options: - pr_human_readable_u64 - pr_human_readable_s64 These obey printbuf->si_units - pr_units_u64 - pr_units_s64 These obey both printbuf-human_readable_units and printbuf->si_units Signed-off-by: Kent Overstreet --- include/linux/printbuf.h | 15 +++++++++++ lib/printbuf.c | 57 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h index 8fb074eb67..9d6c951626 100644 --- a/include/linux/printbuf.h +++ b/include/linux/printbuf.h @@ -53,10 +53,19 @@ * * Make sure you use prt_newline() instead of \n in the format string for = indent * level and tabstops to work corretly. + * + * Output units: printbuf->units exists to tell pretty-printers how to out= put + * numbers: a raw value (e.g. directly from a superblock field), as bytes,= or as + * human readable bytes. prt_units() obeys it. */ =20 #include =20 +enum printbuf_si { + PRINTBUF_UNITS_2, /* use binary powers of 2^10 */ + PRINTBUF_UNITS_10, /* use powers of 10^3 (standard SI) */ +}; + struct printbuf { char *buf; unsigned size; @@ -70,6 +79,8 @@ struct printbuf { u8 atomic; bool allocation_failure:1; bool heap_allocated:1; + enum printbuf_si si_units:1; + bool human_readable_units:1; u8 tabstop; u8 tabstops[4]; }; @@ -83,6 +94,10 @@ void printbuf_indent_add(struct printbuf *, unsigned); void printbuf_indent_sub(struct printbuf *, unsigned); void prt_tab(struct printbuf *); void prt_tab_rjust(struct printbuf *); +void prt_human_readable_u64(struct printbuf *, u64); +void prt_human_readable_s64(struct printbuf *, s64); +void prt_units_u64(struct printbuf *, u64); +void prt_units_s64(struct printbuf *, s64); =20 /* Initializer for a heap allocated printbuf: */ #define PRINTBUF ((struct printbuf) { .heap_allocated =3D true }) diff --git a/lib/printbuf.c b/lib/printbuf.c index e11a504abf..88f1f34fe6 100644 --- a/lib/printbuf.c +++ b/lib/printbuf.c @@ -9,6 +9,7 @@ #endif =20 #include +#include #include =20 static inline size_t printbuf_linelen(struct printbuf *buf) @@ -193,3 +194,59 @@ void prt_tab_rjust(struct printbuf *buf) buf->tabstop++; } EXPORT_SYMBOL(prt_tab_rjust); + +/** + * prt_human_readable_u64 - Print out a u64 in human readable units + * + * Units of 2^10 (default) or 10^3 are controlled via @buf->si_units + */ +void prt_human_readable_u64(struct printbuf *buf, u64 v) +{ + printbuf_make_room(buf, 10); + buf->pos +=3D string_get_size(v, 1, !buf->si_units, + buf->buf + buf->pos, + printbuf_remaining_size(buf)); +} +EXPORT_SYMBOL(prt_human_readable_u64); + +/** + * prt_human_readable_s64 - Print out a s64 in human readable units + * + * Units of 2^10 (default) or 10^3 are controlled via @buf->si_units + */ +void prt_human_readable_s64(struct printbuf *buf, s64 v) +{ + if (v < 0) + prt_char(buf, '-'); + prt_human_readable_u64(buf, abs(v)); +} +EXPORT_SYMBOL(prt_human_readable_s64); + +/** + * prt_units_u64 - Print out a u64 according to printbuf unit options + * + * Units are either raw (default), or human reabable units (controlled via + * @buf->human_readable_units) + */ +void prt_units_u64(struct printbuf *out, u64 v) +{ + if (out->human_readable_units) + prt_human_readable_u64(out, v); + else + prt_printf(out, "%llu", v); +} +EXPORT_SYMBOL(prt_units_u64); + +/** + * prt_units_s64 - Print out a s64 according to printbuf unit options + * + * Units are either raw (default), or human reabable units (controlled via + * @buf->human_readable_units) + */ +void prt_units_s64(struct printbuf *out, s64 v) +{ + if (v < 0) + prt_char(out, '-'); + prt_units_u64(out, abs(v)); +} +EXPORT_SYMBOL(prt_units_s64); --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 22E1AC433EF for ; Sat, 4 Jun 2022 19:31:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240428AbiFDTbl (ORCPT ); Sat, 4 Jun 2022 15:31:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47208 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240162AbiFDTbI (ORCPT ); Sat, 4 Jun 2022 15:31:08 -0400 Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4DA234F9EF for ; Sat, 4 Jun 2022 12:31:06 -0700 (PDT) Received: by mail-qk1-x72a.google.com with SMTP id k6so5324321qkf.4 for ; Sat, 04 Jun 2022 12:31:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Pog5jNfp5Dd2Cu5seYQ54yFgRVpvLlcCiIm5Dkf3KrE=; b=RCoLQOLwAttABgmnV+OZmfgfRp+eEI9LMGbFWz6kp/iyeIPrJrcsQdUb4SpRUX7J/g i3/BGpjrxunt+M+Xp/WwLcpPMx6GWO8VYWAMvdGsEzL0lbs5IVxfhfLVtPSe7x3lzbzj cGf5iWZRIHHyURMHuuQQ6ibZtbZCuhwFYUKMux9UdquFvfXHIMKoXswPrFJCzT7bOK5p eEjuAyFohBkwJ3Cp5SM/m09jwvMAnufCQa4B+I9kY4PcjgIcm77cOqx90Zn5BzkTyntN 4QGkgV/xvYj0ikwopzwMUdBgjnIbpoG5NqI9DtRpyMC/LOcV15ZdiKPI/79jF08i99cT NskA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Pog5jNfp5Dd2Cu5seYQ54yFgRVpvLlcCiIm5Dkf3KrE=; b=bfpnr975gNcPs9t3QfB0umUHkt7wMxD8Ro2wJRBURcUb8lS1ifIns8YIJYZQ2nfQ9w kDx1FXCXFMcKHpf7TvIfUSHL94fZOBsZvROlmO5KqL+3haXYfisUEjoxoMID6HUfyiQz lPhZLE2RGsFcncPvjxZkw8o8tj3ycdaLAsQGMstNjpGbZghVfjgNtrESzTadY9/2lfla YUSTxqJNLXII5Dd/uw1VT6pEy7mjl2yc9B3b8ODxx5AbbTV2+nj3SzAyMUWATTQUlwke 0oavr7T8GkScixe3R1BgbTp/ZXg13ixjh/p6Iha6Oonpxo9GlASe/k2f+aB+2ECzOh2A Y4ow== X-Gm-Message-State: AOAM531z5cXJuadqf7PIZI8Xmb7h/px+Oz6MhqXIyO8XpHgCK9/6ON7J 14Rw9+rZMPobersV8QQo93kVszfeOQ3z X-Google-Smtp-Source: ABdhPJwuKU6FVRDhJFPAnStYbOLMeIElK7agJEfmYqpVzfU8QFQNiKlTrNoyNQzBefLEJXjaKmHYjw== X-Received: by 2002:a37:a5d0:0:b0:6a6:7cbc:dc2a with SMTP id o199-20020a37a5d0000000b006a67cbcdc2amr9236853qke.496.1654371064885; Sat, 04 Jun 2022 12:31:04 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:04 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 10/33] lib/pretty-printers: prt_string_option(), prt_bitflags() Date: Sat, 4 Jun 2022 15:30:19 -0400 Message-Id: <20220604193042.1674951-11-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Signed-off-by: Kent Overstreet --- include/linux/pretty-printers.h | 10 ++++++ lib/Makefile | 2 +- lib/pretty-printers.c | 59 +++++++++++++++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 include/linux/pretty-printers.h create mode 100644 lib/pretty-printers.c diff --git a/include/linux/pretty-printers.h b/include/linux/pretty-printer= s.h new file mode 100644 index 0000000000..f39d8edfba --- /dev/null +++ b/include/linux/pretty-printers.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifndef _LINUX_PRETTY_PRINTERS_H +#define _LINUX_PRETTY_PRINTERS_H + +void prt_string_option(struct printbuf *, const char * const[], size_t); +void prt_bitflags(struct printbuf *, const char * const[], u64); + +#endif /* _LINUX_PRETTY_PRINTERS_H */ diff --git a/lib/Makefile b/lib/Makefile index b4609a4258..b520024852 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -34,7 +34,7 @@ lib-y :=3D ctype.o string.o vsprintf.o cmdline.o \ is_single_threaded.o plist.o decompress.o kobject_uevent.o \ earlycpio.o seq_buf.o siphash.o dec_and_lock.o \ nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o \ - buildid.o printbuf.o + buildid.o printbuf.o pretty-printers.o =20 lib-$(CONFIG_PRINTK) +=3D dump_stack.o lib-$(CONFIG_SMP) +=3D cpumask.o diff --git a/lib/pretty-printers.c b/lib/pretty-printers.c new file mode 100644 index 0000000000..8794eb3824 --- /dev/null +++ b/lib/pretty-printers.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: LGPL-2.1+ +/* Copyright (C) 2022 Kent Overstreet */ + +#include +#include +#include + +/** + * prt_string_option - Given a list of strings, print out the list and ind= icate + * which option is selected, with square brackets (sysfs style) + * + * @out: The printbuf to output to + * @list: List of strings to choose from + * @selected: The option to highlight, with square brackets + */ +void prt_string_option(struct printbuf *out, + const char * const list[], + size_t selected) +{ + size_t i; + + for (i =3D 0; list[i]; i++) { + if (i) + prt_char(out, ' '); + if (i =3D=3D selected) + prt_char(out, '['); + prt_str(out, list[i]); + if (i =3D=3D selected) + prt_char(out, ']'); + } +} +EXPORT_SYMBOL(prt_string_option); + +/** + * prt_bitflags: Given a bitmap and a list of names for each bit, print ou= t which + * bits are on, comma separated + * + * @out: The printbuf to output to + * @list: List of names for each bit + * @flags: Bits to print + */ +void prt_bitflags(struct printbuf *out, + const char * const list[], u64 flags) +{ + unsigned bit, nr =3D 0; + bool first =3D true; + + while (list[nr]) + nr++; + + while (flags && (bit =3D __ffs(flags)) < nr) { + if (!first) + prt_char(out, ','); + first =3D false; + prt_str(out, list[bit]); + flags ^=3D 1 << bit; + } +} +EXPORT_SYMBOL(prt_bitflags); --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D55DAC43334 for ; Sat, 4 Jun 2022 19:31:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240591AbiFDTbp (ORCPT ); Sat, 4 Jun 2022 15:31:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47060 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240206AbiFDTbI (ORCPT ); Sat, 4 Jun 2022 15:31:08 -0400 Received: from mail-qk1-x736.google.com (mail-qk1-x736.google.com [IPv6:2607:f8b0:4864:20::736]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A79C2251B for ; Sat, 4 Jun 2022 12:31:07 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id bi27so1809717qkb.10 for ; Sat, 04 Jun 2022 12:31:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=IjOFseB6wD6vM7xhBXj0Pmypn2c4Grf0JVhbVnX37js=; b=DXIamAJIMgDpqyhDaU2sRWfbikhQ84Arj9tDbxtpCA8oTG6UL0BnpIAMcFInJbW591 cFFlsukFXfgmpoxD/1fbvk/b7aDZPP4SU3y7iizkE0nzKbd/7O+1X4mhFdANtU8gFvyi uqjATvtehoqKwQ+HeUGzmnNxjx/df3XCBzEyQmCelm1uR+HB567XZ578TBaZDfpg5Bhl sW+oRCwaSOjuXWv0bU86XtdaHAR63/YzjzJ+hGWP8udpyBf9Fndc0Bq6xajDRfLoIVNt Ie7qddhqaNhgeXutZPmhQGL1kXNH/gpt3LGnQfus6ohjuKFWzMx4ehHlPPH+Z7d59dez p6fQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=IjOFseB6wD6vM7xhBXj0Pmypn2c4Grf0JVhbVnX37js=; b=SXXTk8unYwuM6NgQ1GqCv9wIpYznR5i9r14o2ZRLIU1G7JKSyHoLS7Fy0sRGoj/BPx PLdXw269WM2BiQ15L4AgpcUCf6PdgOTTN5CGSv8OZBhRoEcCgzOfPOgtqUjj+ZUarkXn /cunlOmTFWJXwmTk0yiMXiEYWkdsRXVuPnjILQEcoRq87Io3SE0b+pjwI7oxRA9ZcVHw dmj8fdgoDV9hqAPmM3gEPTTOXJ5ZX71pLss2Vgi4fo9WaYz4rPssemib9oHeOMBBa8Tg u/rO+tJ6Y778XGnUbZLuIt1/smWiPj59HJ1t2pRvfb0j8iBIJhcjotS3gIkv7h2ymTDK soMQ== X-Gm-Message-State: AOAM531WREUpwq4JrEGr0NdZoY5vwkD7CG4zV1D/lX1w1RRCgI99cFnQ ZKZ/3ICj2nhIGa5hBCtcX/B4b9z2DjXC X-Google-Smtp-Source: ABdhPJyyDLDNT2Eq92EPxIeXzkQF7IOVp3Joz59bjpeReg31EKn5ZozKfkcr0aLclx9Nelw3d05OXw== X-Received: by 2002:a05:620a:bcb:b0:6a6:5830:6138 with SMTP id s11-20020a05620a0bcb00b006a658306138mr10800536qki.647.1654371066278; Sat, 04 Jun 2022 12:31:06 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:05 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 11/33] vsprintf: Improve number() Date: Sat, 4 Jun 2022 15:30:20 -0400 Message-Id: <20220604193042.1674951-12-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch refactors number() to make it a bit clearer, and it also changes it to call printbuf_make_room() only once at the start, instead of in the printbuf output helpers. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 82 +++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 118d6f65c3..1c5ffc7f28 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -458,92 +458,92 @@ void number(struct printbuf *out, unsigned long long = num, { /* put_dec requires 2-byte alignment of the buffer. */ char tmp[3 * sizeof(num)] __aligned(2); - char sign; - char locase; + char sign =3D 0; + /* locase =3D 0 or 0x20. ORing digits or letters with 'locase' + * produces same digits or (maybe lowercased) letters */ + char locase =3D (spec.flags & SMALL); int need_pfx =3D ((spec.flags & SPECIAL) && spec.base !=3D 10); - int i; bool is_zero =3D num =3D=3D 0LL; int field_width =3D spec.field_width; int precision =3D spec.precision; + int nr_digits =3D 0; + int output_bytes =3D 0; =20 - /* locase =3D 0 or 0x20. ORing digits or letters with 'locase' - * produces same digits or (maybe lowercased) letters */ - locase =3D (spec.flags & SMALL); if (spec.flags & LEFT) spec.flags &=3D ~ZEROPAD; - sign =3D 0; if (spec.flags & SIGN) { if ((signed long long)num < 0) { sign =3D '-'; num =3D -(signed long long)num; - field_width--; + output_bytes++; } else if (spec.flags & PLUS) { sign =3D '+'; - field_width--; + output_bytes++; } else if (spec.flags & SPACE) { sign =3D ' '; - field_width--; + output_bytes++; } } if (need_pfx) { if (spec.base =3D=3D 16) - field_width -=3D 2; + output_bytes +=3D 2; else if (!is_zero) - field_width--; + output_bytes++; } =20 /* generate full string in tmp[], in reverse order */ - i =3D 0; - if (num < spec.base) - tmp[i++] =3D hex_asc_upper[num] | locase; - else if (spec.base !=3D 10) { /* 8 or 16 */ + if (spec.base =3D=3D 10) { + nr_digits =3D put_dec(tmp, num) - tmp; + } else { /* 8 or 16 */ int mask =3D spec.base - 1; - int shift =3D 3; + int shift =3D ilog2((unsigned) spec.base); =20 - if (spec.base =3D=3D 16) - shift =3D 4; do { - tmp[i++] =3D (hex_asc_upper[((unsigned char)num) & mask] | locase); + tmp[nr_digits++] =3D (hex_asc_upper[((unsigned char)num) & mask] | loca= se); num >>=3D shift; } while (num); - } else { /* base 10 */ - i =3D put_dec(tmp, num) - tmp; } =20 /* printing 100 using %2d gives "100", not "00" */ - if (i > precision) - precision =3D i; + precision =3D max(nr_digits, precision); + output_bytes +=3D precision; + field_width =3D max(0, field_width - output_bytes); + + printbuf_make_room(out, field_width + output_bytes); + /* leading space padding */ - field_width =3D max(0, field_width - precision); if (!(spec.flags & (ZEROPAD | LEFT))) { - __prt_chars(out, ' ', field_width); + __prt_chars_reserved(out, ' ', field_width); field_width =3D 0; } + /* sign */ if (sign) - __prt_char(out, sign); + __prt_char_reserved(out, sign); + /* "0x" / "0" prefix */ if (need_pfx) { if (spec.base =3D=3D 16 || !is_zero) - __prt_char(out, '0'); + __prt_char_reserved(out, '0'); if (spec.base =3D=3D 16) - __prt_char(out, 'X' | locase); + __prt_char_reserved(out, 'X' | locase); } - /* zero or space padding */ - if (!(spec.flags & LEFT)) { - char c =3D ' ' + (spec.flags & ZEROPAD); =20 - __prt_chars(out, c, field_width); - field_width =3D 0; - } - /* hmm even more zero padding? */ - if (precision > i) - __prt_chars(out, '0', precision - i); + /* zero padding */ + if (!(spec.flags & LEFT)) + __prt_chars_reserved(out, '0', field_width); + + /* zero padding from precision */ + if (precision > nr_digits) + __prt_chars_reserved(out, '0', precision - nr_digits); + /* actual digits of result */ - while (--i >=3D 0) - __prt_char(out, tmp[i]); + while (--nr_digits >=3D 0) + __prt_char_reserved(out, tmp[nr_digits]); + /* trailing space padding */ - __prt_chars(out, ' ', field_width); + if (spec.flags & LEFT) + __prt_chars_reserved(out, ' ', field_width); =20 printbuf_nul_terminate(out); } --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CA22EC433EF for ; Sat, 4 Jun 2022 19:32:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241107AbiFDTct (ORCPT ); Sat, 4 Jun 2022 15:32:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47488 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239999AbiFDTbQ (ORCPT ); Sat, 4 Jun 2022 15:31:16 -0400 Received: from mail-qt1-x831.google.com (mail-qt1-x831.google.com [IPv6:2607:f8b0:4864:20::831]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6FFB54F9CA for ; Sat, 4 Jun 2022 12:31:09 -0700 (PDT) Received: by mail-qt1-x831.google.com with SMTP id x18so5087404qtj.3 for ; Sat, 04 Jun 2022 12:31:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UKaXBn5egCcerocp5DjNOYjWsbUcD3ATqXK/SNAzNqI=; b=jYiKdFziiTb9X35fFfeHmFR0xAABNykPuIQamDtmiR4aAQ1VskyW18ppAUeCYWf7Zz 7Nll4jOA4jnmCDeQpGmUIjW1yCXER1xOHWQdjaI3HjyIfYU+OQaleXgee9nQLbUtzjqE teRoTFWr2Ewtl+VtaaFxGwFN69M9pOavqp53tyuPpRxua8wmCdWnJ5WBHnQGcCtn7jbT tL5C77Si7gAJRDgf0UyRaPDElzm7UR7DcA3n/84mvzGRsTGGctQsh+5+ntco3EX2pfRo NUNV5/+PNjviDjT5iqcbVZu5sSCqRjfSrAjsWm8702Kzf5P7UnNXoMRnpTsyYkroyxtO 2Bgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UKaXBn5egCcerocp5DjNOYjWsbUcD3ATqXK/SNAzNqI=; b=YYiFc8mxBh0wml4EmqcsLgMwIEnIJE88zz9Ui0DPChB687zi2TxTTtkc+nrEjOS45W VXTeIgfeFjvk8ofC05PRzK9KPkZ6quqtyHjGa93I7MZaROmPDW1O4C8nmZC/x7wsg1iN Ctd1f3nt376lyQJJE9MDszUxU+zU57okYa8PjyPHqF4CJZ7vdnGZsPMfNgKzSz+FWT58 S13zMtreN6IMi4aJHL/g3RZk903oXufB1htun8PXBg5aHxNBhGeuEuLKbNBwMnhhJ9hC T0D6pZRx+u4iJxPnIqWLVqSPXlLkeQmROshNoGWZp93ljhtIHE3IvP/R6UOb5VDs+IR2 1yQQ== X-Gm-Message-State: AOAM531Bvbmut64oklu91Lgqc1o1ZYsEEncx+eyUvehfw7yButVeZwS+ NH1Kofa802TIup6dBzdXR3kkgUbHlpfH X-Google-Smtp-Source: ABdhPJyLsl0QEwOIzxkUnepGxjpzz7ATMHPEl9hA0vD6OQEK7CI5ib96Ws44vmpaMuFwuB+nl5d7+g== X-Received: by 2002:a05:622a:1ba5:b0:304:e906:c4e6 with SMTP id bp37-20020a05622a1ba500b00304e906c4e6mr1332432qtb.117.1654371067828; Sat, 04 Jun 2022 12:31:07 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:07 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 12/33] vsprintf: prt_u64_minwidth(), prt_u64() Date: Sat, 4 Jun 2022 15:30:21 -0400 Message-Id: <20220604193042.1674951-13-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This adds two new-style printbuf helpers for printing simple u64s, and converts num_to_str() to be a simple wrapper around prt_u64_minwidth(). Signed-off-by: Kent Overstreet --- include/linux/kernel.h | 4 +- lib/vsprintf.c | 94 ++++++++++++++++++++---------------------- 2 files changed, 48 insertions(+), 50 deletions(-) diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 1906861ece..9ba5a53c6a 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -202,12 +202,14 @@ static inline void might_fault(void) { } =20 void do_exit(long error_code) __noreturn; =20 +struct printbuf; +extern void prt_u64_minwidth(struct printbuf *out, u64 num, unsigned width= ); +extern void prt_u64(struct printbuf *out, u64 num); extern int num_to_str(char *buf, int size, unsigned long long num, unsigned int width); =20 /* lib/printf utilities */ =20 -struct printbuf; extern __printf(2, 3) void prt_printf(struct printbuf *out, const char *fm= t, ...); extern __printf(2, 0) void prt_vprintf(struct printbuf *out, const char *f= mt, va_list); =20 diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 1c5ffc7f28..7b49a998d3 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -368,41 +368,51 @@ char *put_dec(char *buf, unsigned long long n) =20 #endif =20 -/* - * Convert passed number to decimal string. - * Returns the length of string. On buffer overflow, returns 0. - * - * If speed is not important, use snprintf(). It's easy to read the code. +/** + * prt_u64_minwidth - print a u64, in decimal, with zero padding + * @out: printbuf to output to + * @num: u64 to print + * @width: minimum width */ -int num_to_str(char *buf, int size, unsigned long long num, unsigned int w= idth) +void prt_u64_minwidth(struct printbuf *out, u64 num, unsigned width) { /* put_dec requires 2-byte alignment of the buffer. */ char tmp[sizeof(num) * 3] __aligned(2); - int idx, len; + unsigned len =3D put_dec(tmp, num) - tmp; =20 - /* put_dec() may work incorrectly for num =3D 0 (generate "", not "0") */ - if (num <=3D 9) { - tmp[0] =3D '0' + num; - len =3D 1; - } else { - len =3D put_dec(tmp, num) - tmp; - } + printbuf_make_room(out, max(len, width)); =20 - if (len > size || width > size) - return 0; + if (width > len) + __prt_chars_reserved(out, '0', width - len); =20 - if (width > len) { - width =3D width - len; - for (idx =3D 0; idx < width; idx++) - buf[idx] =3D ' '; - } else { - width =3D 0; - } + while (len) + __prt_char_reserved(out, tmp[--len]); + printbuf_nul_terminate(out); +} =20 - for (idx =3D 0; idx < len; ++idx) - buf[idx + width] =3D tmp[len - idx - 1]; +/** + * prt_u64 - print a simple u64, in decimal + * @out: printbuf to output to + * @num: u64 to print + */ +void prt_u64(struct printbuf *out, u64 num) +{ + prt_u64_minwidth(out, num, 0); +} =20 - return len + width; +/* + * Convert passed number to decimal string. + * Returns the length of string. On buffer overflow, returns 0. + * + * Consider switching to printbufs and using prt_u64() or prt_u64_minwith() + * instead. + */ +int num_to_str(char *buf, int size, unsigned long long num, unsigned int w= idth) +{ + struct printbuf out =3D PRINTBUF_EXTERN(buf, size); + + prt_u64_minwidth(&out, num, width); + return out.pos; } =20 #define SIGN 1 /* unsigned/signed, must be 1 */ @@ -1018,20 +1028,6 @@ static const struct printf_spec default_dec_spec =3D= { .precision =3D -1, }; =20 -static const struct printf_spec default_dec02_spec =3D { - .base =3D 10, - .field_width =3D 2, - .precision =3D -1, - .flags =3D ZEROPAD, -}; - -static const struct printf_spec default_dec04_spec =3D { - .base =3D 10, - .field_width =3D 4, - .precision =3D -1, - .flags =3D ZEROPAD, -}; - static noinline_for_stack void resource_string(struct printbuf *out, struct resource *res, struct printf_spec spec, const char *fmt) @@ -1231,12 +1227,12 @@ void bitmap_list_string(struct printbuf *out, unsig= ned long *bitmap, prt_char(out, ','); first =3D false; =20 - number(out, rbot, default_dec_spec); + prt_u64(out, rbot); if (rtop =3D=3D rbot + 1) continue; =20 prt_char(out, '-'); - number(out, rtop - 1, default_dec_spec); + prt_u64(out, rtop - 1); } } =20 @@ -1778,21 +1774,21 @@ void date_str(struct printbuf *out, int year =3D tm->tm_year + (r ? 0 : 1900); int mon =3D tm->tm_mon + (r ? 0 : 1); =20 - number(out, year, default_dec04_spec); + prt_u64_minwidth(out, year, 4); prt_char(out, '-'); - number(out, mon, default_dec02_spec); + prt_u64_minwidth(out, mon, 2); prt_char(out, '-'); - number(out, tm->tm_mday, default_dec02_spec); + prt_u64_minwidth(out, tm->tm_mday, 2); } =20 static noinline_for_stack void time_str(struct printbuf *out, const struct rtc_time *tm, bool r) { - number(out, tm->tm_hour, default_dec02_spec); + prt_u64_minwidth(out, tm->tm_hour, 2); prt_char(out, ':'); - number(out, tm->tm_min, default_dec02_spec); + prt_u64_minwidth(out, tm->tm_min, 2); prt_char(out, ':'); - number(out, tm->tm_sec, default_dec02_spec); + prt_u64_minwidth(out, tm->tm_sec, 2); } =20 static noinline_for_stack @@ -2070,7 +2066,7 @@ void device_node_string(struct printbuf *out, struct = device_node *dn, str_spec.precision =3D precision; break; case 'p': /* phandle */ - number(out, (unsigned int)dn->phandle, default_dec_spec); + prt_u64(out, (unsigned int)dn->phandle); break; case 'P': /* path-spec */ p =3D fwnode_get_name(of_fwnode_handle(dn)); --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 55A88C43334 for ; Sat, 4 Jun 2022 19:32:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240454AbiFDTb5 (ORCPT ); Sat, 4 Jun 2022 15:31:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48160 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240140AbiFDTbi (ORCPT ); Sat, 4 Jun 2022 15:31:38 -0400 Received: from mail-qt1-x831.google.com (mail-qt1-x831.google.com [IPv6:2607:f8b0:4864:20::831]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E79034F9D2 for ; Sat, 4 Jun 2022 12:31:10 -0700 (PDT) Received: by mail-qt1-x831.google.com with SMTP id t21so935157qtw.11 for ; Sat, 04 Jun 2022 12:31:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Shg77HnyMQRXbMxMOH7fDju/B6P367xm3FEJBtf2/5I=; b=ZHiSfBqPf0mmbm6Cwm8a5Stmx8hor2CW8L2no7YFJT+21lVu1KlVat/aaUe3DDYjH/ y4u/TFZndKUExogSMANFNdRkkv5S1EAcSEHdbgHQVDsQUT/Ei7aDabv4lcnV/1CUHJIl CbSGFxkKVgXnqltp5pM4Ld1WfhRNwHyDq0FVChR4oMeLklKEqtCf9rFv4ko3NNv+vF9E Pz5Ggg0J0GrzUmaZhWcITVVjxszp2JyiHvsNw5NXivNPNOAYYRu6FSxvytF3c/1enH02 akpVa+IoaPLG3KOtR63Vr9o0+hXnsRUh1/os5CusE6GXQrYUbv6SlnJIOEPh62PINNho yuhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Shg77HnyMQRXbMxMOH7fDju/B6P367xm3FEJBtf2/5I=; b=bleMMShbgtvPHrqnChmxlnJ+zG3yDrybCqvMOStmHq+gmyLdxDf3dbHz8VHXgWoFUZ hDtdicrW6qdppkgnfw17u/OXEhyygtjbb7Ywkr/LmpEUqb3aNrzjrUV2yS5bbYI3XiSc zd+Z2ZyPIvGmWnRNPtpV4DUste8djri9v4J8wxbLlpoRegd2wMynSuhPjmK8v9DW4lE6 djk6vQEfNgmVo7gtKMyvvoEEdw8R7bB0dKReilPUPRXuQZp4aYbYS+VwyHFEUnzv/hOj ibHUzisQXwkF/64iSftZLFnslffQCq61dAV7trtFr6/TobbskynEnDd+Q/ki7u//dBHr jTsA== X-Gm-Message-State: AOAM530/voVDP3LfGwJGrkoQ2e1FdTeoYECKBSBpQHkMyXGPKeMBu7sg W6Zz8F1tk4qiy6WpuBG+0FKX5+uM6dLA X-Google-Smtp-Source: ABdhPJyzxSOaiZXqgR7A3Pvq5x7fwHa5M9fdlhhr43aSTMgZOyRTaxT0Q4mwINIAHOZXvFKNHwLA8w== X-Received: by 2002:ac8:578f:0:b0:2f9:317a:bd25 with SMTP id v15-20020ac8578f000000b002f9317abd25mr12802150qta.456.1654371069357; Sat, 04 Jun 2022 12:31:09 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:08 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 13/33] test_printf: Drop requirement that sprintf not write past nul Date: Sat, 4 Jun 2022 15:30:22 -0400 Message-Id: <20220604193042.1674951-14-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The current test code checks that sprintf never writes past the terminating nul. This is a rather strange requirement, completely separate from writing past the end of the buffer, which of course we can't do: writing anywhere to the buffer passed to snprintf, within size of course, should be perfectly fine. Since this check has no documentation as to where it comes from or what depends on it, and it's getting in the way of further refactoring (printf_spec handling is right now scattered massively throughout the code, and we'd like to consolidate it) - delete it. Also, many current pretty-printers building up their output on the stack, and then copy it to the actual output buffer - by eliminating this requirement we can kill those extra buffers. Signed-off-by: Kent Overstreet --- lib/test_printf.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/test_printf.c b/lib/test_printf.c index ff833870f5..a702dd5dc0 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -78,12 +78,6 @@ do_test(int bufsize, const char *expect, int elen, return 1; } =20 - if (memchr_inv(test_buffer + written + 1, FILL_CHAR, BUF_SIZE + PAD_SIZE = - (written + 1))) { - pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote beyond the nul-terminator= \n", - bufsize, fmt); - return 1; - } - if (memcmp(test_buffer, expect, written)) { pr_warn("vsnprintf(buf, %d, \"%s\", ...) wrote '%s', expected '%.*s'\n", bufsize, fmt, test_buffer, written, expect); --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92430C433EF for ; Sat, 4 Jun 2022 19:32:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240806AbiFDTcK (ORCPT ); Sat, 4 Jun 2022 15:32:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48184 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240482AbiFDTbi (ORCPT ); Sat, 4 Jun 2022 15:31:38 -0400 Received: from mail-qt1-x835.google.com (mail-qt1-x835.google.com [IPv6:2607:f8b0:4864:20::835]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F0AD4F9EB for ; Sat, 4 Jun 2022 12:31:12 -0700 (PDT) Received: by mail-qt1-x835.google.com with SMTP id hh4so7943020qtb.10 for ; Sat, 04 Jun 2022 12:31:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Oaee6fU7FBLwhgu5DdJadkLE5G6WCsZxuaTAFXkUXZI=; b=ldYVpBXcFsh7cLhB7OmnC/+yw36roh8l6muIrrxyF+nORq7ggbBRiSYZOXlJmR8qzY MmNK2vdmdZaWiOH1+6g1UINWT7Q6rrwoEB8VHJs4r7rVwvVTy3ukdqwBCcGbxeDrIrEi pTWBDzZPpt6/CSvocm+uBXbwZcvMT1gS7nerlsKqStpeK4U+i4s+PaL6r+qKbBWOrxR+ bpww57Y1OMaSOo2hHfFjpQoJ3kGXSM8a+KycVx5a+WBE26j1vWsPu3opwxfjlJ0QTBJj uI1ZAEM6WfQHj8jQEExGF84ythD4GacqkzlCTdEHCThdfnFR7jJtrXChb+KT2ROd66tb 9vaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Oaee6fU7FBLwhgu5DdJadkLE5G6WCsZxuaTAFXkUXZI=; b=W5rK2sz/3Z8ro4D+6hoXt51KDX0Kt0/6IjkVPFk324XABcU2Rgdkhyti7jtXMbJ0pt 8mBDI9klKRUa4XdQITM6l6Hh2IdFg8V/w7oFxYxFDKqoSBUN+QIb9TNLZ+S3quv3MWkh cAEdr17b/XmwS4vQl/ef2EDFCvnrf/ru0ei3jILl3OEHPghTq8Q5ZVGntwTWc9P5wixq TJbFqRjaBD4wv0cI3j6zxRKoDx0wCvjiSkYBva72qT08Xv5VenLLIqKCq+kxTbsVGq5O fQ1o5GqrRKB4Ib1fC0nF1J85vIJVKqHsPqA4+4ufrACxfEeHTIBFKjxYPBFCmxLkOz03 HrEA== X-Gm-Message-State: AOAM531Rfs4eTBIV9Xhq79vMqN3nS+W6P4N8uZfatRl8RxhdpXfqNSaz X4H7Zbz5RvFhbt8X62iZWGk5meuLXpED X-Google-Smtp-Source: ABdhPJwPHepZk81dDDSxhA4FdxgP9+w2OaM0lH4d5XT8SOwNIWueCqz+T5/0KZ6r2nLyF+teXIMLvw== X-Received: by 2002:a05:622a:1705:b0:2ff:9bd1:f760 with SMTP id h5-20020a05622a170500b002ff9bd1f760mr12578426qtk.573.1654371070825; Sat, 04 Jun 2022 12:31:10 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:10 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 14/33] vsprintf: Start consolidating printf_spec handling Date: Sat, 4 Jun 2022 15:30:23 -0400 Message-Id: <20220604193042.1674951-15-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" printf_spec is right now something of a mess - it's a grab-bag of state that's interpreted inconsistently by different code, and it's scattered throughout vsprintf.c. We'd like to get it out of the pretty-printers, and have it be solely the responsibility of vsprintf()/vpr_buf(), the code that parses and handles format strings. Most of the code that uses printf_spec is only using it for a minimum & maximum field width - that can be done at the toplevel by checking how much we just printed, and padding or truncating it as necessary. This patch takes those "simple" uses of printf_spec and moves them as far up the call stack as possible. This patch also renames some helpers and creates new ones that don't take printf_spec: - do_width_precision: new helper that handles with/precision of printf_spec - error_string -> error_string_spec - check_pointer -> check_pointer_spec - string -> string_spec Next patches will be reducing/eliminating uses of the *_spec versions. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 245 ++++++++++++++++++++++++++++--------------------- 1 file changed, 138 insertions(+), 107 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 7b49a998d3..863040fdaa 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -617,6 +617,19 @@ void widen_string(struct printbuf *out, int n, prt_chars(out, ' ', spaces); } =20 +static void do_width_precision(struct printbuf *out, unsigned prev_pos, + struct printf_spec spec) +{ + unsigned n =3D out->pos - prev_pos; + + if (n > spec.precision) { + out->pos -=3D n - spec.precision; + n =3D spec.precision; + } + + widen_string(out, n, spec); +} + /* Handle string from a well known address. */ static void string_nocheck(struct printbuf *out, const char *s, @@ -649,7 +662,7 @@ static void err_ptr(struct printbuf *out, void *ptr, } =20 /* Be careful: error messages must fit into the given buffer. */ -static void error_string(struct printbuf *out, const char *s, +static void error_string_spec(struct printbuf *out, const char *s, struct printf_spec spec) { /* @@ -679,7 +692,7 @@ static const char *check_pointer_msg(const void *ptr) return NULL; } =20 -static int check_pointer(struct printbuf *out, +static int check_pointer_spec(struct printbuf *out, const void *ptr, struct printf_spec spec) { @@ -687,7 +700,7 @@ static int check_pointer(struct printbuf *out, =20 err_msg =3D check_pointer_msg(ptr); if (err_msg) { - error_string(out, err_msg, spec); + error_string_spec(out, err_msg, spec); return -EFAULT; } =20 @@ -695,16 +708,47 @@ static int check_pointer(struct printbuf *out, } =20 static noinline_for_stack -void string(struct printbuf *out, +void string_spec(struct printbuf *out, const char *s, struct printf_spec spec) { - if (check_pointer(out, s, spec)) + if (check_pointer_spec(out, s, spec)) return; =20 string_nocheck(out, s, spec); } =20 +static void error_string(struct printbuf *out, const char *s) +{ + /* + * Hard limit to avoid a completely insane messages. It actually + * works pretty well because most error messages are in + * the many pointer format modifiers. + */ + prt_bytes(out, s, min(strlen(s), 2 * sizeof(void *))); +} + +static int check_pointer(struct printbuf *out, const void *ptr) +{ + const char *err_msg; + + err_msg =3D check_pointer_msg(ptr); + if (err_msg) { + error_string(out, err_msg); + return -EFAULT; + } + + return 0; +} + +static void string(struct printbuf *out, const char *s) +{ + if (check_pointer(out, s)) + return; + + prt_str(out, s); +} + static void pointer_string(struct printbuf *out, const void *ptr, struct printf_spec spec) @@ -830,7 +874,7 @@ static void ptr_to_id(struct printbuf *out, if (ret) { spec.field_width =3D 2 * sizeof(ptr); /* string length must be less than default_width */ - return error_string(out, str, spec); + return error_string_spec(out, str, spec); } =20 pointer_string(out, (const void *)hashval, spec); @@ -871,7 +915,7 @@ void restricted_pointer(struct printbuf *out, if (in_irq() || in_serving_softirq() || in_nmi()) { if (spec.field_width =3D=3D -1) spec.field_width =3D 2 * sizeof(ptr); - return error_string(out, "pK-error", spec); + return error_string_spec(out, "pK-error", spec); } =20 /* @@ -901,14 +945,12 @@ void restricted_pointer(struct printbuf *out, } =20 static noinline_for_stack -void dentry_name(struct printbuf *out, - const struct dentry *d, struct printf_spec spec, +void dentry_name(struct printbuf *out, const struct dentry *d, const char *fmt) { - const char *array[4], *s; + const char *array[4]; const struct dentry *p; - int depth; - int i, n; + int i, depth; =20 switch (fmt[1]) { case '2': case '3': case '4': @@ -920,7 +962,7 @@ void dentry_name(struct printbuf *out, =20 rcu_read_lock(); for (i =3D 0; i < depth; i++, d =3D p) { - if (check_pointer(out, d, spec)) { + if (check_pointer(out, d)) { rcu_read_unlock(); return; } @@ -934,56 +976,46 @@ void dentry_name(struct printbuf *out, break; } } - s =3D array[--i]; - for (n =3D 0; n !=3D spec.precision; n++) { - char c =3D *s++; - if (!c) { - if (!i) - break; - c =3D '/'; - s =3D array[--i]; - } - prt_char(out, c); + while (1) { + prt_str(out, array[--i]); + if (!i) + break; + prt_char(out, '/'); } rcu_read_unlock(); - - widen_string(out, n, spec); } =20 static noinline_for_stack -void file_dentry_name(struct printbuf *out, - const struct file *f, - struct printf_spec spec, const char *fmt) +void file_dentry_name(struct printbuf *out, const struct file *f, + const char *fmt) { - if (check_pointer(out, f, spec)) + if (check_pointer(out, f)) return; =20 - return dentry_name(out, f->f_path.dentry, spec, fmt); + return dentry_name(out, f->f_path.dentry, fmt); } #ifdef CONFIG_BLOCK static noinline_for_stack -void bdev_name(struct printbuf *out, - struct block_device *bdev, - struct printf_spec spec, const char *fmt) +void bdev_name(struct printbuf *out, struct block_device *bdev) { struct gendisk *hd; =20 - if (check_pointer(out, bdev, spec)) + if (check_pointer(out, bdev)) return; =20 hd =3D bdev->bd_disk; - string(out, hd->disk_name, spec); + string(out, hd->disk_name); if (bdev->bd_partno) { if (isdigit(hd->disk_name[strlen(hd->disk_name)-1])) prt_char(out, 'p'); - number(out, bdev->bd_partno, spec); + prt_u64(out, bdev->bd_partno); } } #endif =20 static noinline_for_stack void symbol_string(struct printbuf *out, void *ptr, - struct printf_spec spec, const char *fmt) + const char *fmt) { unsigned long value; #ifdef CONFIG_KALLSYMS @@ -1006,17 +1038,12 @@ void symbol_string(struct printbuf *out, void *ptr, else sprint_symbol_no_offset(sym, value); =20 - string_nocheck(out, sym, spec); + prt_str(out, sym); #else special_hex_number(out, value, sizeof(void *)); #endif } =20 -static const struct printf_spec default_str_spec =3D { - .field_width =3D -1, - .precision =3D -1, -}; - static const struct printf_spec default_flag_spec =3D { .base =3D 16, .precision =3D -1, @@ -1075,7 +1102,7 @@ void resource_string(struct printbuf *out, struct res= ource *res, int decode =3D (fmt[0] =3D=3D 'R') ? 1 : 0; const struct printf_spec *specp; =20 - if (check_pointer(out, res, spec)) + if (check_pointer_spec(out, res, spec)) return; =20 prt_char(&sym, '['); @@ -1139,7 +1166,7 @@ void hex_string(struct printbuf *out, u8 *addr, /* nothing to print */ return; =20 - if (check_pointer(out, addr, spec)) + if (check_pointer_spec(out, addr, spec)) return; =20 switch (fmt[1]) { @@ -1180,7 +1207,7 @@ void bitmap_string(struct printbuf *out, unsigned lon= g *bitmap, int i, chunksz; bool first =3D true; =20 - if (check_pointer(out, bitmap, spec)) + if (check_pointer_spec(out, bitmap, spec)) return; =20 /* reused to print numbers */ @@ -1219,7 +1246,7 @@ void bitmap_list_string(struct printbuf *out, unsigne= d long *bitmap, bool first =3D true; int rbot, rtop; =20 - if (check_pointer(out, bitmap, spec)) + if (check_pointer_spec(out, bitmap, spec)) return ; =20 for_each_set_bitrange(rbot, rtop, bitmap, nr_bits) { @@ -1246,7 +1273,7 @@ void mac_address_string(struct printbuf *out, u8 *add= r, char separator; bool reversed =3D false; =20 - if (check_pointer(out, addr, spec)) + if (check_pointer_spec(out, addr, spec)) return; =20 switch (fmt[1]) { @@ -1547,7 +1574,7 @@ void ip_addr_string(struct printbuf *out, const void = *ptr, { char *err_fmt_msg; =20 - if (check_pointer(out, ptr, spec)) + if (check_pointer_spec(out, ptr, spec)) return; =20 switch (fmt[1]) { @@ -1568,12 +1595,12 @@ void ip_addr_string(struct printbuf *out, const voi= d *ptr, case AF_INET6: return ip6_addr_string_sa(out, &sa->v6, spec, fmt); default: - return error_string(out, "(einval)", spec); + return error_string_spec(out, "(einval)", spec); }} } =20 err_fmt_msg =3D fmt[0] =3D=3D 'i' ? "(%pi?)" : "(%pI?)"; - return error_string(out, err_fmt_msg, spec); + return error_string_spec(out, err_fmt_msg, spec); } =20 static noinline_for_stack @@ -1588,7 +1615,7 @@ void escaped_string(struct printbuf *out, u8 *addr, if (spec.field_width =3D=3D 0) return; /* nothing to print */ =20 - if (check_pointer(out, addr, spec)) + if (check_pointer_spec(out, addr, spec)) return; =20 do { @@ -1633,7 +1660,7 @@ static void va_format(struct printbuf *out, { va_list va; =20 - if (check_pointer(out, va_fmt, spec)) + if (check_pointer_spec(out, va_fmt, spec)) return; =20 va_copy(va, *va_fmt->va); @@ -1642,16 +1669,13 @@ static void va_format(struct printbuf *out, } =20 static noinline_for_stack -void uuid_string(struct printbuf *out, const u8 *addr, - struct printf_spec spec, const char *fmt) +void uuid_string(struct printbuf *out, const u8 *addr, const char *fmt) { - char uuid_buf[UUID_STRING_LEN + 1]; - struct printbuf uuid =3D PRINTBUF_EXTERN(uuid_buf, sizeof(uuid_buf)); int i; const u8 *index =3D uuid_index; bool uc =3D false; =20 - if (check_pointer(out, addr, spec)) + if (check_pointer(out, addr)) return; =20 switch (*(++fmt)) { @@ -1668,30 +1692,28 @@ void uuid_string(struct printbuf *out, const u8 *ad= dr, =20 for (i =3D 0; i < 16; i++) { if (uc) - prt_hex_byte_upper(&uuid, addr[index[i]]); + prt_hex_byte_upper(out, addr[index[i]]); else - prt_hex_byte(&uuid, addr[index[i]]); + prt_hex_byte(out, addr[index[i]]); switch (i) { case 3: case 5: case 7: case 9: - prt_char(&uuid, '-'); + prt_char(out, '-'); break; } } - - string_nocheck(out, uuid_buf, spec); } =20 static noinline_for_stack void netdev_bits(struct printbuf *out, const void *addr, - struct printf_spec spec, const char *fmt) + const char *fmt) { unsigned long long num; int size; =20 - if (check_pointer(out, addr, spec)) + if (check_pointer(out, addr)) return; =20 switch (fmt[1]) { @@ -1701,7 +1723,7 @@ void netdev_bits(struct printbuf *out, const void *ad= dr, special_hex_number(out, num, size); break; default: - error_string(out, "(%pN?)", spec); + error_string(out, "(%pN?)"); break; } } @@ -1716,9 +1738,9 @@ void fourcc_string(struct printbuf *out, const u32 *f= ourcc, u32 orig, val; =20 if (fmt[1] !=3D 'c' || fmt[2] !=3D 'c') - return error_string(out, "(%p4?)", spec); + return error_string_spec(out, "(%p4?)", spec); =20 - if (check_pointer(out, fourcc, spec)) + if (check_pointer_spec(out, fourcc, spec)) return; =20 orig =3D get_unaligned(fourcc); @@ -1739,17 +1761,17 @@ void fourcc_string(struct printbuf *out, const u32 = *fourcc, special_hex_number(&output, orig, sizeof(u32)); prt_char(&output, ')'); =20 - string(out, output_buf, spec); + string_spec(out, output_buf, spec); } =20 static noinline_for_stack void address_val(struct printbuf *out, const void *addr, - struct printf_spec spec, const char *fmt) + const char *fmt) { unsigned long long num; int size; =20 - if (check_pointer(out, addr, spec)) + if (check_pointer(out, addr)) return; =20 switch (fmt[1]) { @@ -1800,7 +1822,7 @@ void rtc_str(struct printbuf *out, const struct rtc_t= ime *tm, bool found =3D true; int count =3D 2; =20 - if (check_pointer(out, tm, spec)) + if (check_pointer_spec(out, tm, spec)) return; =20 switch (fmt[count]) { @@ -1870,7 +1892,7 @@ void time_and_date(struct printbuf *out, case 'T': return time64_str(out, *(const time64_t *)ptr, spec, fmt); default: - return error_string(out, "(%pt?)", spec); + return error_string_spec(out, "(%pt?)", spec); } } =20 @@ -1879,16 +1901,16 @@ void clock(struct printbuf *out, struct clk *clk, struct printf_spec spec, const char *fmt) { if (!IS_ENABLED(CONFIG_HAVE_CLK)) - return error_string(out, "(%pC?)", spec); + return error_string_spec(out, "(%pC?)", spec); =20 - if (check_pointer(out, clk, spec)) + if (check_pointer_spec(out, clk, spec)) return; =20 switch (fmt[1]) { case 'n': default: #ifdef CONFIG_COMMON_CLK - return string(out, __clk_get_name(clk), spec); + return string_spec(out, __clk_get_name(clk), spec); #else return ptr_to_id(out, clk, spec); #endif @@ -1906,7 +1928,7 @@ void format_flags(struct printbuf *out, unsigned long= flags, if ((flags & mask) !=3D mask) continue; =20 - string(out, names->name, default_str_spec); + string(out, names->name); =20 flags &=3D ~mask; if (flags) @@ -1964,7 +1986,7 @@ void format_page_flags(struct printbuf *out, unsigned= long flags) if (append) prt_char(out, '|'); =20 - string(out, pff[i].name, default_str_spec); + string(out, pff[i].name); prt_char(out, '=3D'); number(out, (flags >> pff[i].shift) & pff[i].mask, *pff[i].spec); =20 @@ -1980,7 +2002,7 @@ void flags_string(struct printbuf *out, void *flags_p= tr, unsigned long flags; const struct trace_print_flags *names; =20 - if (check_pointer(out, flags_ptr, spec)) + if (check_pointer_spec(out, flags_ptr, spec)) return; =20 switch (fmt[1]) { @@ -1995,7 +2017,7 @@ void flags_string(struct printbuf *out, void *flags_p= tr, names =3D gfpflag_names; break; default: - return error_string(out, "(%pG?)", spec); + return error_string_spec(out, "(%pG?)", spec); } =20 return format_flags(out, flags, names); @@ -2012,10 +2034,8 @@ void fwnode_full_name_string(struct printbuf *out, struct fwnode_handle *__fwnode =3D fwnode_get_nth_parent(fwnode, depth); =20 - string(out, fwnode_get_name_prefix(__fwnode), - default_str_spec); - string(out, fwnode_get_name(__fwnode), - default_str_spec); + string(out, fwnode_get_name_prefix(__fwnode)); + string(out, fwnode_get_name(__fwnode)); =20 fwnode_handle_put(__fwnode); } @@ -2036,12 +2056,12 @@ void device_node_string(struct printbuf *out, struc= t device_node *dn, str_spec.field_width =3D -1; =20 if (fmt[0] !=3D 'F') - return error_string(out, "(%pO?)", spec); + return error_string_spec(out, "(%pO?)", spec); =20 if (!IS_ENABLED(CONFIG_OF)) - return error_string(out, "(%pOF?)", spec); + return error_string_spec(out, "(%pOF?)", spec); =20 - if (check_pointer(out, dn, spec)) + if (check_pointer_spec(out, dn, spec)) return; =20 /* simple case without anything any more format specifiers */ @@ -2062,7 +2082,7 @@ void device_node_string(struct printbuf *out, struct = device_node *dn, p =3D fwnode_get_name(of_fwnode_handle(dn)); precision =3D str_spec.precision; str_spec.precision =3D strchrnul(p, '@') - p; - string(out, p, str_spec); + string_spec(out, p, str_spec); str_spec.precision =3D precision; break; case 'p': /* phandle */ @@ -2072,7 +2092,7 @@ void device_node_string(struct printbuf *out, struct = device_node *dn, p =3D fwnode_get_name(of_fwnode_handle(dn)); if (!p[1]) p =3D "/"; - string(out, p, str_spec); + string_spec(out, p, str_spec); break; case 'F': /* flags */ tbuf[0] =3D of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-'; @@ -2082,18 +2102,18 @@ void device_node_string(struct printbuf *out, struc= t device_node *dn, tbuf[4] =3D 0; string_nocheck(out, tbuf, str_spec); break; - case 'c': /* major compatible string */ + case 'c': /* major compatible string_spec */ ret =3D of_property_read_string(dn, "compatible", &p); if (!ret) - string(out, p, str_spec); + string_spec(out, p, str_spec); break; - case 'C': /* full compatible string */ + case 'C': /* full compatible string_spec */ has_mult =3D false; of_property_for_each_string(dn, "compatible", prop, p) { if (has_mult) string_nocheck(out, ",", str_spec); string_nocheck(out, "\"", str_spec); - string(out, p, str_spec); + string_spec(out, p, str_spec); string_nocheck(out, "\"", str_spec); =20 has_mult =3D true; @@ -2118,16 +2138,16 @@ void fwnode_string(struct printbuf *out, str_spec.field_width =3D -1; =20 if (*fmt !=3D 'w') - return error_string(out, "(%pf?)", spec); + return error_string_spec(out, "(%pf?)", spec); =20 - if (check_pointer(out, fwnode, spec)) + if (check_pointer_spec(out, fwnode, spec)) return; =20 fmt++; =20 switch (*fmt) { case 'P': /* name */ - string(out, fwnode_get_name(fwnode), str_spec); + string_spec(out, fwnode_get_name(fwnode), str_spec); break; case 'f': /* full_name */ default: @@ -2294,13 +2314,16 @@ static noinline_for_stack void pointer(struct printbuf *out, const char *fmt, void *ptr, struct printf_spec spec) { + unsigned prev_pos =3D out->pos; + switch (*fmt) { case 'S': case 's': ptr =3D dereference_symbol_descriptor(ptr); fallthrough; case 'B': - return symbol_string(out, ptr, spec, fmt); + symbol_string(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'R': case 'r': return resource_string(out, ptr, spec, fmt); @@ -2331,28 +2354,34 @@ void pointer(struct printbuf *out, const char *fmt, case 'E': return escaped_string(out, ptr, spec, fmt); case 'U': - return uuid_string(out, ptr, spec, fmt); + uuid_string(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'V': return va_format(out, ptr, spec, fmt); case 'K': return restricted_pointer(out, ptr, spec); case 'N': - return netdev_bits(out, ptr, spec, fmt); + netdev_bits(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case '4': return fourcc_string(out, ptr, spec, fmt); case 'a': - return address_val(out, ptr, spec, fmt); + address_val(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'd': - return dentry_name(out, ptr, spec, fmt); + dentry_name(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 't': return time_and_date(out, ptr, spec, fmt); case 'C': return clock(out, ptr, spec, fmt); case 'D': - return file_dentry_name(out, ptr, spec, fmt); + file_dentry_name(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); #ifdef CONFIG_BLOCK case 'g': - return bdev_name(out, ptr, spec, fmt); + bdev_name(out, ptr); + return do_width_precision(out, prev_pos, spec); #endif =20 case 'G': @@ -2372,9 +2401,9 @@ void pointer(struct printbuf *out, const char *fmt, case 'k': switch (fmt[1]) { case 's': - return string(out, ptr, spec); + return string_spec(out, ptr, spec); default: - return error_string(out, "(einval)", spec); + return error_string_spec(out, "(einval)", spec); } default: return default_pointer(out, ptr, spec); @@ -2675,6 +2704,7 @@ void prt_vprintf(struct printbuf *out, const char *fm= t, va_list args) =20 while (*fmt) { const char *old_fmt =3D fmt; + unsigned prev_pos =3D out->pos; int read =3D format_decode(fmt, &spec); =20 fmt +=3D read; @@ -2704,7 +2734,8 @@ void prt_vprintf(struct printbuf *out, const char *fm= t, va_list args) break; =20 case FORMAT_TYPE_STR: - string(out, va_arg(args, char *), spec); + string(out, va_arg(args, char *)); + do_width_precision(out, prev_pos, spec); break; =20 case FORMAT_TYPE_PTR: @@ -3197,7 +3228,7 @@ void prt_bstrprintf(struct printbuf *out, const char = *fmt, const u32 *bin_buf) case FORMAT_TYPE_STR: { const char *str_arg =3D args; args +=3D strlen(str_arg) + 1; - string(out, (char *)str_arg, spec); + string_spec(out, (char *)str_arg, spec); break; } =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C12ACC43334 for ; Sat, 4 Jun 2022 19:32:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240497AbiFDTcE (ORCPT ); Sat, 4 Jun 2022 15:32:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48136 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240463AbiFDTbi (ORCPT ); Sat, 4 Jun 2022 15:31:38 -0400 Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2C52E4F9FB for ; Sat, 4 Jun 2022 12:31:13 -0700 (PDT) Received: by mail-qk1-x72a.google.com with SMTP id k6so5324321qkf.4 for ; Sat, 04 Jun 2022 12:31:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8ZR3vpiR15jc25rT55XN+a9EgF+ZdSJRDIqigHrDnho=; b=Ax0TRUqWFqBQoDAa5BEt61bnAuF6Ed67k7TQfNLCysxCWPwEUuHJADW/dZVquOmELO M0YWX8DDPs0OMKpku7Ur655CIHt81ED3P1UOOGRUeTe1I02cB+hYv4EwRQrUsai49zUO Pmj9febU5I2VYRsTtF6sleaJaYntU1fK5Lpjk1bSdDuqvfbn3O3RQoP3JjX2RqbIJGwh Tlu3KnWVUpkMz/5qkQ7Nv2LdOTyT72jeWRQLQuI6uydqjz9UQZoV1w/I+JSPDKkkCRDx 7Fao6awNZECbqzJNaP/U9f3eECWtgypdnQ2ICozXAsWCr3Q52drhMkO6olzQlXcCu+Xq cZaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8ZR3vpiR15jc25rT55XN+a9EgF+ZdSJRDIqigHrDnho=; b=f3QIFx55Bpkm9ySzd22EPM4GgOYFizFutZC8sGIuQM2dD6+IWlqd8CxA3FHrFrF1Gp WwgAk1pfBo2YdS7REbySa2KqazFn9m1ihnDZ9kCwdj2mgfY/J2E4LqQn7+2sNE6teybb enXMtf5Ey0EqTWw2Zcnc118UM82B3FBrRw4T+G/nWXZySN/MKq4UmyrvVZHHAOvBrYF0 zmqY5pF24xybiDpyjpcssDKGb3B6J5xmIlvHgHGz2yv/g3JGl0eEPjMbqOxE5Bsg62pP Z36WhYPoo9bAChVzxpd8gB1ZSfc0PlZIZEPzV71H2ZUGtjqZYixElB37jmyBXY/xoER1 PShw== X-Gm-Message-State: AOAM530B64D5A/0CaG8UIOajyJHYZCNxAZSe/hLovlzfcxYm9GefmKWV cpVkkkVu38vF7dgsu4DFfeqEkwHTtEYu X-Google-Smtp-Source: ABdhPJyQPhTMjSqi97ahdwhDFjNJRE/3k8WyZKzM35WBcYJXHsCoozDbFPH5AQ99VPWww1VIWCG6Vw== X-Received: by 2002:a05:620a:b42:b0:6a6:ab7a:8d0d with SMTP id x2-20020a05620a0b4200b006a6ab7a8d0dmr3335289qkg.515.1654371072323; Sat, 04 Jun 2022 12:31:12 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:11 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 15/33] vsprintf: Refactor resource_string() Date: Sat, 4 Jun 2022 15:30:24 -0400 Message-Id: <20220604193042.1674951-16-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Two changes: - We're attempting to consolidate printf_spec and format string handling in the top level vpr_buf(), this changes resource_string to not take printf_spec - With the new printbuf helpers there's no need to use a separate stack allocated buffer, so this patch deletes it. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 51 ++++++++++++++++++++++++-------------------------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 863040fdaa..4256b1d3a5 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1057,7 +1057,7 @@ static const struct printf_spec default_dec_spec =3D { =20 static noinline_for_stack void resource_string(struct printbuf *out, struct resource *res, - struct printf_spec spec, const char *fmt) + int decode) { #ifndef IO_RSRC_PRINTK_SIZE #define IO_RSRC_PRINTK_SIZE 6 @@ -1096,62 +1096,58 @@ void resource_string(struct printbuf *out, struct r= esource *res, #define FLAG_BUF_SIZE (2 * sizeof(res->flags)) #define DECODED_BUF_SIZE sizeof("[mem - 64bit pref window disabled]") #define RAW_BUF_SIZE sizeof("[mem - flags 0x]") - char sym_buf[max(2*RSRC_BUF_SIZE + DECODED_BUF_SIZE, - 2*RSRC_BUF_SIZE + FLAG_BUF_SIZE + RAW_BUF_SIZE)]; - struct printbuf sym =3D PRINTBUF_EXTERN(sym_buf, sizeof(sym_buf)); - int decode =3D (fmt[0] =3D=3D 'R') ? 1 : 0; const struct printf_spec *specp; =20 - if (check_pointer_spec(out, res, spec)) + if (check_pointer(out, res)) return; =20 - prt_char(&sym, '['); + prt_char(out, '['); if (res->flags & IORESOURCE_IO) { - string_nocheck(&sym, "io ", str_spec); + string_nocheck(out, "io ", str_spec); specp =3D &io_spec; } else if (res->flags & IORESOURCE_MEM) { - string_nocheck(&sym, "mem ", str_spec); + string_nocheck(out, "mem ", str_spec); specp =3D &mem_spec; } else if (res->flags & IORESOURCE_IRQ) { - string_nocheck(&sym, "irq ", str_spec); + string_nocheck(out, "irq ", str_spec); specp =3D &default_dec_spec; } else if (res->flags & IORESOURCE_DMA) { - string_nocheck(&sym, "dma ", str_spec); + string_nocheck(out, "dma ", str_spec); specp =3D &default_dec_spec; } else if (res->flags & IORESOURCE_BUS) { - string_nocheck(&sym, "bus ", str_spec); + string_nocheck(out, "bus ", str_spec); specp =3D &bus_spec; } else { - string_nocheck(&sym, "??? ", str_spec); + string_nocheck(out, "??? ", str_spec); specp =3D &mem_spec; decode =3D 0; } if (decode && res->flags & IORESOURCE_UNSET) { - string_nocheck(&sym, "size ", str_spec); - number(&sym, resource_size(res), *specp); + string_nocheck(out, "size ", str_spec); + number(out, resource_size(res), *specp); } else { - number(&sym, res->start, *specp); + number(out, res->start, *specp); if (res->start !=3D res->end) { - prt_char(&sym, '-'); - number(&sym, res->end, *specp); + prt_char(out, '-'); + number(out, res->end, *specp); } } if (decode) { if (res->flags & IORESOURCE_MEM_64) - string_nocheck(&sym, " 64bit", str_spec); + string_nocheck(out, " 64bit", str_spec); if (res->flags & IORESOURCE_PREFETCH) - string_nocheck(&sym, " pref", str_spec); + string_nocheck(out, " pref", str_spec); if (res->flags & IORESOURCE_WINDOW) - string_nocheck(&sym, " window", str_spec); + string_nocheck(out, " window", str_spec); if (res->flags & IORESOURCE_DISABLED) - string_nocheck(&sym, " disabled", str_spec); + string_nocheck(out, " disabled", str_spec); } else { - string_nocheck(&sym, " flags ", str_spec); - number(&sym, res->flags, default_flag_spec); + string_nocheck(out, " flags ", str_spec); + number(out, res->flags, default_flag_spec); } - prt_char(&sym, ']'); + prt_char(out, ']'); =20 - string_nocheck(out, sym_buf, spec); + printbuf_nul_terminate(out); } =20 static noinline_for_stack @@ -2326,7 +2322,8 @@ void pointer(struct printbuf *out, const char *fmt, return do_width_precision(out, prev_pos, spec); case 'R': case 'r': - return resource_string(out, ptr, spec, fmt); + resource_string(out, ptr, fmt[0] =3D=3D 'R'); + return do_width_precision(out, prev_pos, spec); case 'h': return hex_string(out, ptr, spec, fmt); case 'b': --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ADEA3C433EF for ; Sat, 4 Jun 2022 19:32:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240782AbiFDTcm (ORCPT ); Sat, 4 Jun 2022 15:32:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240233AbiFDTbi (ORCPT ); Sat, 4 Jun 2022 15:31:38 -0400 Received: from mail-qt1-x833.google.com (mail-qt1-x833.google.com [IPv6:2607:f8b0:4864:20::833]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8CA994FC58 for ; Sat, 4 Jun 2022 12:31:15 -0700 (PDT) Received: by mail-qt1-x833.google.com with SMTP id hf10so7949567qtb.7 for ; Sat, 04 Jun 2022 12:31:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=wLK6+egkCovHKJVGrXsuX+1zu1r3Q9U94qYohBZ6ysU=; b=lR2Ebc++yXYk7EIAmHmJt5oC4YtNu+3h345iAEZWGUlsZFxZRZoDsC5rIPph3bs2+o ixOSAL+g8KhfZO90C8/7ng9xIALijDoK9MHNodU9XMK3/ktmBuGiStG0p3O82u4tfV3E 72AP2xSAmTmYzX8eQ98wiFS1gR7hatJfEINh/LLG8cFywqfEwi18J0eNvCOUlivM+/aY rxePgeON72yT7caAuubDqu5LZM5f/cug0MvvAJViTHPCjQngeh+DAVbS0wyrtLO9zKqF OPyfy1Gn9CbpDEmG6T1HXmFvuKiK/52x/T5gONrChfRXs+U5Aq6HLbXJFz6nMtV8Rue8 DO2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wLK6+egkCovHKJVGrXsuX+1zu1r3Q9U94qYohBZ6ysU=; b=T5HFdrGIUXsO5qd6dRCypBFnljHFY7U6qTu/Ui6n77IcjzIJWhfp7g8gTGHKCPWnau rG5sMQW7NgQ++rZHHWcyAsnLOYIj8M4lJISpHWFHp7l08OHe8AwUzVtCXS0Iw++Ckb// PxBONrX44sC+46TwYwqAMLTAaiAsBE2LvvoFplfFuN+UHTwRUf4bXfj2jFKVzMSqj2st ljBMQZ3Uy4le5uV5MSz3auCoaUo95iGv1w3+6MMhdFdvRA3GblgHWi++/5hKBttRyNQe QtmLVHiHydwwFOAFAc9JCqjkTL0yfgr3se+25cuPlOY7CXDrLUxT29iSWFNgNUM9voub bkWQ== X-Gm-Message-State: AOAM533A+qs2aMgU0Off6x/eojs10Q5Id427P263yzXaGcKktgBTEElv Gzbw57g+f9EEKlEFRQ8G7xf3C1Zs8R7S X-Google-Smtp-Source: ABdhPJwXUtbJlxmaOaBtF/AQ5yLrI1MHSSqCox5sjK8rNC+25X0is+ap4JMCAAqqXSlWabJ858cxaA== X-Received: by 2002:ac8:5c8e:0:b0:303:1a91:e435 with SMTP id r14-20020ac85c8e000000b003031a91e435mr12749544qta.15.1654371073712; Sat, 04 Jun 2022 12:31:13 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:13 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 16/33] vsprintf: Refactor fourcc_string() Date: Sat, 4 Jun 2022 15:30:25 -0400 Message-Id: <20220604193042.1674951-17-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" - We're attempting to consolidate printf_spec and format string handling in the top level vpr_buf(), this changes fourcc_string() to not take printf_spec - With the new printbuf helpers there's no need to use a separate stack allocated buffer, so this patch deletes it. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 4256b1d3a5..49565e0dc4 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1726,17 +1726,15 @@ void netdev_bits(struct printbuf *out, const void *= addr, =20 static noinline_for_stack void fourcc_string(struct printbuf *out, const u32 *fourcc, - struct printf_spec spec, const char *fmt) + const char *fmt) { - char output_buf[sizeof("0123 little-endian (0x01234567)")]; - struct printbuf output =3D PRINTBUF_EXTERN(output_buf, sizeof(output_buf)= ); unsigned int i; u32 orig, val; =20 if (fmt[1] !=3D 'c' || fmt[2] !=3D 'c') - return error_string_spec(out, "(%p4?)", spec); + return error_string(out, "(%p4?)"); =20 - if (check_pointer_spec(out, fourcc, spec)) + if (check_pointer(out, fourcc)) return; =20 orig =3D get_unaligned(fourcc); @@ -1746,18 +1744,16 @@ void fourcc_string(struct printbuf *out, const u32 = *fourcc, unsigned char c =3D val >> (i * 8); =20 /* Print non-control ASCII characters as-is, dot otherwise */ - prt_char(&output, isascii(c) && isprint(c) ? c : '.'); + prt_char(out, isascii(c) && isprint(c) ? c : '.'); } =20 - prt_char(&output, ' '); - prt_str(&output, orig & BIT(31) ? "big-endian" : "little-endian"); - - prt_char(&output, ' '); - prt_char(&output, '('); - special_hex_number(&output, orig, sizeof(u32)); - prt_char(&output, ')'); + prt_char(out, ' '); + prt_str(out, orig & BIT(31) ? "big-endian" : "little-endian"); =20 - string_spec(out, output_buf, spec); + prt_char(out, ' '); + prt_char(out, '('); + special_hex_number(out, orig, sizeof(u32)); + prt_char(out, ')'); } =20 static noinline_for_stack @@ -2361,7 +2357,8 @@ void pointer(struct printbuf *out, const char *fmt, netdev_bits(out, ptr, fmt); return do_width_precision(out, prev_pos, spec); case '4': - return fourcc_string(out, ptr, spec, fmt); + fourcc_string(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'a': address_val(out, ptr, fmt); return do_width_precision(out, prev_pos, spec); --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9E20C433EF for ; Sat, 4 Jun 2022 19:32:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240562AbiFDTcP (ORCPT ); Sat, 4 Jun 2022 15:32:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48216 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240536AbiFDTbj (ORCPT ); Sat, 4 Jun 2022 15:31:39 -0400 Received: from mail-qk1-x72e.google.com (mail-qk1-x72e.google.com [IPv6:2607:f8b0:4864:20::72e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4B5484F9DF for ; Sat, 4 Jun 2022 12:31:16 -0700 (PDT) Received: by mail-qk1-x72e.google.com with SMTP id c144so5882473qkg.11 for ; Sat, 04 Jun 2022 12:31:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Pf/FzfiFeov0TvwCq8OTCWTHUawuSdyfQ/gNqM6PjUQ=; b=Tp1wo/ZA2SnFuK5A4UnbUfj64gtGhb0gbb64GWpIAcagfJfF5IH0+tH1uilDeoXUfX PzZqlrtQRWDZ30E8MYMBkG+sLxciu/HfrwelqrPWS76y29Bi4lH6VcIY4c29OaeWRmXp e2EeoJNgLP9blMhLQdwaFpXku1pYbg4d6uTE2LaS4ncXrOpRCFhzpaEMW4PpnwWjyJmo wuwD+CuD+LusMeO+24rydrDhoG9tD9ae8sk/PhsvOwGXN4OBWZh9RwHUTNuhzD1J0u28 gdiZJsq+d2eztF/eVUENzF6wa8d2aK+kKes0cnqmWjJCCJgJLCd8WhUkGC5sed8Ci5Oe qsJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Pf/FzfiFeov0TvwCq8OTCWTHUawuSdyfQ/gNqM6PjUQ=; b=2FoleXmjJIkhchAZCMUmM0ieo3/+JT/nl6Q4vPSVLaCM/Gzf44XssaWty4JZyx2f0h CHTM3JOW23+c7yWg8iANaMHlphQxTFJfX0a1oJ2ylfnF6d0TuGAP9g7JLosp2Th4wn9s SIhR7UxUFC4jpxU9oSXrfzxr7Q4JZF5sHr0zr0i7DH5v/slce8MDrhuqv6VOHuCq/onA WC2GwR9k7ntRlTJzksHTNtXgyBxF2wCkm2Jhy28BsZHKoeVEa84j9Q99AP3roLmFWli5 aU8hCJmYapW9AVBcs6ReQr1jByJsMRymCNpkMg9eP2jpn7dkEXEuEecp97rNAxZSoTe9 TtTg== X-Gm-Message-State: AOAM530xIAj+vm3oYxmEbgr6dYxVMmPzeqzrJNiLbtWCmN9AU478ja5U VWdv5B68qXq0BDZ+o5uptiEbim45KcCx X-Google-Smtp-Source: ABdhPJzs8MC4G60VN3BYLJKVipa/+cKuKEJ8EV/K4ImNKi99R+/OG5w2PvvftTUqbF8oaoMR8/CfrA== X-Received: by 2002:a37:e304:0:b0:6a6:a784:6276 with SMTP id y4-20020a37e304000000b006a6a7846276mr5009907qki.778.1654371075318; Sat, 04 Jun 2022 12:31:15 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:14 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 17/33] vsprintf: Refactor ip_addr_string() Date: Sat, 4 Jun 2022 15:30:26 -0400 Message-Id: <20220604193042.1674951-18-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" - We're attempting to consolidate printf_spec and format string handling in the top level vpr_buf(), this changes ip_addr_string() to not take printf_spec - With the new printbuf helpers there's no need to use a separate stack allocated buffer, so this patch deletes it. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 114 ++++++++++++++++--------------------------------- 1 file changed, 37 insertions(+), 77 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 49565e0dc4..964e00b6a2 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1301,13 +1301,13 @@ void mac_address_string(struct printbuf *out, u8 *a= ddr, } =20 static noinline_for_stack -void ip4_string(struct printbuf *out, - const u8 *addr, const char *fmt) +void ip4_string(struct printbuf *out, const u8 *addr, const char *fmt) { - int i; - bool leading_zeros =3D (fmt[0] =3D=3D 'i'); - int index; - int step; + struct printf_spec spec =3D default_dec_spec; + int i, index, step; + + if (fmt[0] =3D=3D 'i') + spec.precision =3D 3; =20 switch (fmt[2]) { case 'h': @@ -1331,19 +1331,9 @@ void ip4_string(struct printbuf *out, break; } for (i =3D 0; i < 4; i++) { - char temp[4] __aligned(2); /* hold each IP quad in reverse order */ - int digits =3D put_dec_trunc8(temp, addr[index]) - temp; - if (leading_zeros) { - if (digits < 3) - prt_char(out, '0'); - if (digits < 2) - prt_char(out, '0'); - } - /* reverse the digits in the quad */ - while (digits--) - prt_char(out, temp[digits]); - if (i < 3) + if (i) prt_char(out, '.'); + number(out, addr[index], spec); index +=3D step; } } @@ -1426,8 +1416,6 @@ void ip6_compressed_string(struct printbuf *out, cons= t char *addr) __prt_char(out, ':'); ip4_string(out, &in6.s6_addr[12], "I4"); } - - printbuf_nul_terminate(out); } =20 static noinline_for_stack @@ -1445,41 +1433,20 @@ void ip6_string(struct printbuf *out, const char *a= ddr, const char *fmt) =20 static noinline_for_stack void ip6_addr_string(struct printbuf *out, const u8 *addr, - struct printf_spec spec, const char *fmt) + const char *fmt) { - char ip6_addr_buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")= ]; - struct printbuf ip6_addr =3D PRINTBUF_EXTERN(ip6_addr_buf, sizeof(ip6_add= r_buf)); - if (fmt[0] =3D=3D 'I' && fmt[2] =3D=3D 'c') - ip6_compressed_string(&ip6_addr, addr); + ip6_compressed_string(out, addr); else - ip6_string(&ip6_addr, addr, fmt); - - string_nocheck(out, ip6_addr_buf, spec); -} - -static noinline_for_stack -void ip4_addr_string(struct printbuf *out, const u8 *addr, - struct printf_spec spec, const char *fmt) -{ - char ip4_addr_buf[sizeof("255.255.255.255")]; - struct printbuf ip4_addr =3D PRINTBUF_EXTERN(ip4_addr_buf, sizeof(ip4_add= r_buf)); - - ip4_string(&ip4_addr, addr, fmt); - - string_nocheck(out, ip4_addr_buf, spec); + ip6_string(out, addr, fmt); } =20 static noinline_for_stack void ip6_addr_string_sa(struct printbuf *out, const struct sockaddr_in6 *sa, - struct printf_spec spec, const char *fmt) + const char *fmt) { bool have_p =3D false, have_s =3D false, have_f =3D false, have_c =3D fal= se; - char ip6_addr_buf[sizeof("[xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255]= ") + - sizeof(":12345") + sizeof("/123456789") + - sizeof("%1234567890")]; - struct printbuf ip6_addr =3D PRINTBUF_EXTERN(ip6_addr_buf, sizeof(ip6_add= r_buf)); const u8 *addr =3D (const u8 *) &sa->sin6_addr; char fmt6[2] =3D { fmt[0], '6' }; =20 @@ -1502,41 +1469,35 @@ void ip6_addr_string_sa(struct printbuf *out, } =20 if (have_p || have_s || have_f) - prt_char(&ip6_addr, '['); + prt_char(out, '['); =20 if (fmt6[0] =3D=3D 'I' && have_c) - ip6_compressed_string(&ip6_addr, addr); + ip6_compressed_string(out, addr); else - ip6_string(&ip6_addr, addr, fmt6); + ip6_string(out, addr, fmt6); =20 if (have_p || have_s || have_f) - prt_char(&ip6_addr, ']'); + prt_char(out, ']'); =20 if (have_p) { - prt_char(&ip6_addr, ':'); - number(&ip6_addr, ntohs(sa->sin6_port), spec); + prt_char(out, ':'); + prt_u64(out, ntohs(sa->sin6_port)); } if (have_f) { - prt_char(&ip6_addr, '/'); - number(&ip6_addr, ntohl(sa->sin6_flowinfo & - IPV6_FLOWINFO_MASK), spec); + prt_char(out, '/'); + prt_u64(out, ntohl(sa->sin6_flowinfo & IPV6_FLOWINFO_MASK)); } if (have_s) { - prt_char(&ip6_addr, '%'); - number(&ip6_addr, sa->sin6_scope_id, spec); + prt_char(out, '%'); + prt_u64(out, sa->sin6_scope_id); } - - string_nocheck(out, ip6_addr_buf, spec); } =20 static noinline_for_stack -void ip4_addr_string_sa(struct printbuf *out, - const struct sockaddr_in *sa, - struct printf_spec spec, const char *fmt) +void ip4_addr_string_sa(struct printbuf *out, const struct sockaddr_in *sa, + const char *fmt) { bool have_p =3D false; - char ip4_addr_buf[sizeof("255.255.255.255") + sizeof(":12345")]; - struct printbuf ip4_addr =3D PRINTBUF_EXTERN(ip4_addr_buf, sizeof(ip4_add= r_buf)); const u8 *addr =3D (const u8 *) &sa->sin_addr.s_addr; char fmt4[3] =3D { fmt[0], '4', 0 }; =20 @@ -1555,29 +1516,27 @@ void ip4_addr_string_sa(struct printbuf *out, } } =20 - ip4_string(&ip4_addr, addr, fmt4); + ip4_string(out, addr, fmt4); if (have_p) { - prt_char(&ip4_addr, ':'); - number(&ip4_addr, ntohs(sa->sin_port), spec); + prt_char(out, ':'); + prt_u64(out, ntohs(sa->sin_port)); } - - string_nocheck(out, ip4_addr_buf, spec); } =20 static noinline_for_stack void ip_addr_string(struct printbuf *out, const void *ptr, - struct printf_spec spec, const char *fmt) + const char *fmt) { char *err_fmt_msg; =20 - if (check_pointer_spec(out, ptr, spec)) + if (check_pointer(out, ptr)) return; =20 switch (fmt[1]) { case '6': - return ip6_addr_string(out, ptr, spec, fmt); + return ip6_addr_string(out, ptr, fmt); case '4': - return ip4_addr_string(out, ptr, spec, fmt); + return ip4_string(out, ptr, fmt); case 'S': { const union { struct sockaddr raw; @@ -1587,16 +1546,16 @@ void ip_addr_string(struct printbuf *out, const voi= d *ptr, =20 switch (sa->raw.sa_family) { case AF_INET: - return ip4_addr_string_sa(out, &sa->v4, spec, fmt); + return ip4_addr_string_sa(out, &sa->v4, fmt); case AF_INET6: - return ip6_addr_string_sa(out, &sa->v6, spec, fmt); + return ip6_addr_string_sa(out, &sa->v6, fmt); default: - return error_string_spec(out, "(einval)", spec); + return error_string(out, "(einval)"); }} } =20 err_fmt_msg =3D fmt[0] =3D=3D 'i' ? "(%pi?)" : "(%pI?)"; - return error_string_spec(out, err_fmt_msg, spec); + error_string(out, err_fmt_msg); } =20 static noinline_for_stack @@ -2343,7 +2302,8 @@ void pointer(struct printbuf *out, const char *fmt, * 4: 001.002.003.004 * 6: 000102...0f */ - return ip_addr_string(out, ptr, spec, fmt); + ip_addr_string(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'E': return escaped_string(out, ptr, spec, fmt); case 'U': --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E5F8AC43334 for ; Sat, 4 Jun 2022 19:32:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240922AbiFDTcU (ORCPT ); Sat, 4 Jun 2022 15:32:20 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48182 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240618AbiFDTbk (ORCPT ); Sat, 4 Jun 2022 15:31:40 -0400 Received: from mail-qk1-x736.google.com (mail-qk1-x736.google.com [IPv6:2607:f8b0:4864:20::736]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B55BA4FC76 for ; Sat, 4 Jun 2022 12:31:17 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id bi27so1809717qkb.10 for ; Sat, 04 Jun 2022 12:31:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=J+OO0U/O9fCdUkK5Q7sI7mM5Cd+STQfapJZCjl15B/w=; b=qP08oHvi8nY3OUezgt2nZswPfX/oSDDYzDCqAxorOV06IrbszeIsXCBHQYsQrd9gJb 5jjU6gs/2cuWjG1jZp0jQrauPRAkSpy0cXGHsYQULiYDl6jJ7xh/e811mp7p2A93Ymnq /liRAJ/Su6PV8EHJI+ehuyf8jdIJ8KcdjssPNMF3rwjPINrhMSbdDjYaylJiAAnNB8rZ cjtEmsVyOphGap4yrt+vivGXoMGa/ifW6eldZWyZi4YuKy0V4a7w3BRcN6UiRNvMHuYu nmwa8Har8dNEuUwrmJEZmhbXBC/NOA43ysFqxZsAkIJYTYcoEX1l2FHGpBanuul5zhzd M4Dw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=J+OO0U/O9fCdUkK5Q7sI7mM5Cd+STQfapJZCjl15B/w=; b=xeu5YYBaTBHRh42FXEDNMHokHRXZtaKogqHh4J24E4e4IChItlGKIi4ew+ot2Ip+E/ uLZfUvgvgAQx9JlccJgmJmX6yZc+AFVDI/kvzpsxZShj4Dj3jeN8naNk93Ppd7iu15BG UBHS25x/l5qOZuOpp7/2zhAiawl6Ip9eqhRW1RdfgYui2rhF0iy7tBcTLM9xVM3UWQ+5 RaIz64Eiv0omYNg7ARSjMnShzUUaIk9thzAcNl4jLJXzKZQ4c0BO/GcV0DAzg9MA/nHx 8HpUBUqhV653oAzl8VruqH+/YCc1cp3F5ahyZftx30+1hAaj3NJGosZagiWDblOMTOdx Fnyg== X-Gm-Message-State: AOAM531AJOze7TAxT4LrLqBO4AnEEptodALVHEbdX2nuNDfgl0CVcl3d Giu/vyg1OYT4C91o7FjB5cfEqmmFRlcn X-Google-Smtp-Source: ABdhPJzWGfZd5UH/WSl1tsC8XiPB079oUZ1fpabgZPLuWwqzaQ9DEsHbsdCKV/pCtuAm2TkpAys2Fw== X-Received: by 2002:a37:9d45:0:b0:6a6:8b04:e7fd with SMTP id g66-20020a379d45000000b006a68b04e7fdmr8821614qke.37.1654371076801; Sat, 04 Jun 2022 12:31:16 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:16 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 18/33] vsprintf: Refactor mac_address_string() Date: Sat, 4 Jun 2022 15:30:27 -0400 Message-Id: <20220604193042.1674951-19-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" - We're attempting to consolidate printf_spec and format string handling in the top level ptr_vprintf(), this changes mac_address_string() to not take printf_spec - With the new printbuf helpers there's no need to use a separate stack allocated buffer, so this patch deletes it. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 964e00b6a2..6020f55fc0 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1261,15 +1261,13 @@ void bitmap_list_string(struct printbuf *out, unsig= ned long *bitmap, =20 static noinline_for_stack void mac_address_string(struct printbuf *out, u8 *addr, - struct printf_spec spec, const char *fmt) + const char *fmt) { - char mac_addr[sizeof("xx:xx:xx:xx:xx:xx")]; - char *p =3D mac_addr; int i; char separator; bool reversed =3D false; =20 - if (check_pointer_spec(out, addr, spec)) + if (check_pointer(out, addr)) return; =20 switch (fmt[1]) { @@ -1288,16 +1286,13 @@ void mac_address_string(struct printbuf *out, u8 *a= ddr, =20 for (i =3D 0; i < 6; i++) { if (reversed) - p =3D hex_byte_pack(p, addr[5 - i]); + prt_hex_byte(out, addr[5 - i]); else - p =3D hex_byte_pack(p, addr[i]); + prt_hex_byte(out, addr[i]); =20 if (fmt[0] =3D=3D 'M' && i !=3D 5) - *p++ =3D separator; + prt_char(out, separator); } - *p =3D '\0'; - - string_nocheck(out, mac_addr, spec); } =20 static noinline_for_stack @@ -2292,7 +2287,8 @@ void pointer(struct printbuf *out, const char *fmt, case 'm': /* Contiguous: 000102030405 */ /* [mM]F (FDDI) */ /* [mM]R (Reverse order; Bluetooth) */ - return mac_address_string(out, ptr, spec, fmt); + mac_address_string(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'I': /* Formatted IP supported * 4: 1.2.3.4 * 6: 0001:0203:...:0708 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0E8B6C43334 for ; Sat, 4 Jun 2022 19:32:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236992AbiFDTc1 (ORCPT ); Sat, 4 Jun 2022 15:32:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240649AbiFDTbk (ORCPT ); Sat, 4 Jun 2022 15:31:40 -0400 Received: from mail-qk1-x730.google.com (mail-qk1-x730.google.com [IPv6:2607:f8b0:4864:20::730]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D20950001 for ; Sat, 4 Jun 2022 12:31:19 -0700 (PDT) Received: by mail-qk1-x730.google.com with SMTP id a184so4813982qkg.5 for ; Sat, 04 Jun 2022 12:31:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=5EcspCOdO3ERymWEcbTM1mUbo49A548NGXqTZCRd2s8=; b=l02443OrBLuUyG71ej4YvSDyXjAtkdq3Mh1aRuz1IYeuK8rqF0Rpq/jPGeF/j1v6hN iXCIvCwEAoKluUuX8Ywo4ZyjynDP/OhfS39bwixWuRs11xDjGdbNOyRLq4akrOO3nDl6 bs+wvnZtqY0jOPZOXFWqmGLOyXksQ2rNU3hNkoBG4uabJrua+71Dey7PWfhbEjdHL29Z 8ukiSB4vvtGGJ0/rrlTsB8dHt+qTVLnb6aUCe7j3vGxwAeEgrSS8OtQWPFR19zRqdV7z EQIotE6+2/GQVMQ8Yl+VGimeHkgzgF4PziiPrM7bohQSg/oyBCOfulZc8XHX5DJHRFxs gHtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5EcspCOdO3ERymWEcbTM1mUbo49A548NGXqTZCRd2s8=; b=hYaVnMOVeutTlEAzhJHY0WtIF6KyosrwVcnKRlRHWrn4HYjX/osTlBg4BfAMthbPKD BRrALeTpkCQaa7AgK/0GKXtUVTrzpDRdRmlEwfSAM/hhIEusEukNVsQUTuU64RMwfpbu DUsQ+3BZ9HKDccpqyo2LMWE+H+/bljPzvVwndZbLCnvRHT6gUBNbnYY9LQvfyxtIWaN2 ZyUXUFefJ23gJl+GSvilWvez+iyFanaMtytkuNJ8HENvrA/0n17KD6+V3rqfh8K31LGf DKSeHSD4hb4XfsqnpKoU+2Li1inkBPZOCIRkhnMwWXjSQF77XApog+b7n+zQE1pN9JQ7 gnEQ== X-Gm-Message-State: AOAM533YTG30przspcdbUzRSxT+BV72WsL3iAs1T6pmKU/cNz+qDTwrH +mL/ZFY+T9drKSNStVgFdko4rr9qL0Wj X-Google-Smtp-Source: ABdhPJzBuY7gv/t5buyAi6q/RUYs/Yy+fsSFyvu5ITPo1CN3yUF3PanibFLO8vDMEg6wfBHBBrJoQg== X-Received: by 2002:ae9:e401:0:b0:6a3:5985:8f41 with SMTP id q1-20020ae9e401000000b006a359858f41mr11169541qkc.58.1654371078561; Sat, 04 Jun 2022 12:31:18 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:17 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 19/33] vsprintf: time_and_date() no longer takes printf_spec Date: Sat, 4 Jun 2022 15:30:28 -0400 Message-Id: <20220604193042.1674951-20-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" We're attempting to consolidate printf_spec and format string handling in the top level vpr_buf(), this changes time_and_date() to not take printf_spec. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 6020f55fc0..5de25723a3 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1761,14 +1761,14 @@ void time_str(struct printbuf *out, const struct rt= c_time *tm, bool r) =20 static noinline_for_stack void rtc_str(struct printbuf *out, const struct rtc_time *tm, - struct printf_spec spec, const char *fmt) + const char *fmt) { bool have_t =3D true, have_d =3D true; bool raw =3D false, iso8601_separator =3D true; bool found =3D true; int count =3D 2; =20 - if (check_pointer_spec(out, tm, spec)) + if (check_pointer(out, tm)) return; =20 switch (fmt[count]) { @@ -1806,7 +1806,7 @@ void rtc_str(struct printbuf *out, const struct rtc_t= ime *tm, =20 static noinline_for_stack void time64_str(struct printbuf *out, const time64_t time, - struct printf_spec spec, const char *fmt) + const char *fmt) { struct rtc_time rtc_time; struct tm tm; @@ -1824,21 +1824,20 @@ void time64_str(struct printbuf *out, const time64_= t time, =20 rtc_time.tm_isdst =3D 0; =20 - rtc_str(out, &rtc_time, spec, fmt); + rtc_str(out, &rtc_time, fmt); } =20 static noinline_for_stack -void time_and_date(struct printbuf *out, - void *ptr, struct printf_spec spec, +void time_and_date(struct printbuf *out, void *ptr, const char *fmt) { switch (fmt[1]) { case 'R': - return rtc_str(out, (const struct rtc_time *)ptr, spec, fmt); + return rtc_str(out, (const struct rtc_time *)ptr, fmt); case 'T': - return time64_str(out, *(const time64_t *)ptr, spec, fmt); + return time64_str(out, *(const time64_t *)ptr, fmt); default: - return error_string_spec(out, "(%pt?)", spec); + return error_string(out, "(%pt?)"); } } =20 @@ -2322,7 +2321,8 @@ void pointer(struct printbuf *out, const char *fmt, dentry_name(out, ptr, fmt); return do_width_precision(out, prev_pos, spec); case 't': - return time_and_date(out, ptr, spec, fmt); + time_and_date(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'C': return clock(out, ptr, spec, fmt); case 'D': --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60D25C43334 for ; Sat, 4 Jun 2022 19:32:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240359AbiFDTcc (ORCPT ); Sat, 4 Jun 2022 15:32:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47522 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240665AbiFDTbk (ORCPT ); Sat, 4 Jun 2022 15:31:40 -0400 Received: from mail-qt1-x832.google.com (mail-qt1-x832.google.com [IPv6:2607:f8b0:4864:20::832]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7E02B50017 for ; Sat, 4 Jun 2022 12:31:21 -0700 (PDT) Received: by mail-qt1-x832.google.com with SMTP id c8so7974406qtj.1 for ; Sat, 04 Jun 2022 12:31:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=3Kz0pz7Mia/gmCNDAqKt9rpofsruelzWNSzQfxnNHsE=; b=Yk9lCBml1xUExBB5xXCaE6uEJorrNxMZIJaf6Ac+vckzLUw2vXxnWgP/R5Z06V1W2m HCmlEOHThU6UsI7c1aYjZ/PV5nVou+3TJOpL1+8xJWmqtQRlIm6FOhYGzr8nYYWgYPHM Ofo8xS2GBBVX3b7q8epm+vTtSx/pJoPVajwkPBgaSd0eJ8X6dunRl6BY2IlgA/l/50dL NwCipFS0qJ5unGzOPey6Ay45+OVkLuJpVlPHdi+/osxop4f6hOXN74t5XVi95AtDhBmV qhcgbFoW+mJ0fI1x/T/yEdM9/9oNPDSV3DsojUqFEg6HGGcQXvI/PZcLsaC39Q5B8E5J v75Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=3Kz0pz7Mia/gmCNDAqKt9rpofsruelzWNSzQfxnNHsE=; b=ukH2PQg9X1IsZLGabB8iX497FN1Ajc+u+peGeuXQGTT4IO5gHs8Vu7p43TWYJQy6qh /i9sj+xcFvT9tneiDPfN3kn3dfVTXmrmMWvoPu8pEDhQfJpx8a3ZujIyqy7nrsA2JK3f llFkKBNFlTzH6JpvRGdjVrPmss9ioSXyLDwDewymWnyBNMK+PlZoQwCGqqgXioFq6aBg Na3gzK5u8aDFwWNAsC8qex31iRLdgfdQtY0+9Y0FRkqcGjjpFdww9K2nRyLXGKn1V7fG wdOYC6It4sP08Oit3fzwW2aDLRCzQtlb/TR6/GTxD016rvYV6luINOcmfNvjO3wsffvF 0VsA== X-Gm-Message-State: AOAM530sR4jimShmH6R5rR5nIOTINjeAK6+GyzJl6UfP3Xrzo9ZY+E/m 2x4vNIBEyPobctu877JRF1wUYWUJqgRB X-Google-Smtp-Source: ABdhPJzIHTtna/1os7r4Gh4AU9wLMHUo8ofSn1AcfAhxWyFKssjKHFrHde23TLJfuYShzMR9eaeDvg== X-Received: by 2002:ac8:5e13:0:b0:304:b452:9ec8 with SMTP id h19-20020ac85e13000000b00304b4529ec8mr13038713qtx.356.1654371080158; Sat, 04 Jun 2022 12:31:20 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:19 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 20/33] vsprintf: flags_string() no longer takes printf_spec Date: Sat, 4 Jun 2022 15:30:29 -0400 Message-Id: <20220604193042.1674951-21-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" We're attempting to consolidate printf_spec and format string handling in the top level vpr_buf(), this changes time_and_date() to not take printf_spec. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 5de25723a3..1cd08d0d5b 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1942,12 +1942,12 @@ void format_page_flags(struct printbuf *out, unsign= ed long flags) =20 static noinline_for_stack void flags_string(struct printbuf *out, void *flags_ptr, - struct printf_spec spec, const char *fmt) + const char *fmt) { unsigned long flags; const struct trace_print_flags *names; =20 - if (check_pointer_spec(out, flags_ptr, spec)) + if (check_pointer(out, flags_ptr)) return; =20 switch (fmt[1]) { @@ -1962,7 +1962,7 @@ void flags_string(struct printbuf *out, void *flags_p= tr, names =3D gfpflag_names; break; default: - return error_string_spec(out, "(%pG?)", spec); + return error_string(out, "(%pG?)"); } =20 return format_flags(out, flags, names); @@ -2335,7 +2335,8 @@ void pointer(struct printbuf *out, const char *fmt, #endif =20 case 'G': - return flags_string(out, ptr, spec, fmt); + flags_string(out, ptr, fmt); + return do_width_precision(out, prev_pos, spec); case 'O': return device_node_string(out, ptr, spec, fmt + 1); case 'f': --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BFC7FC433EF for ; Sat, 4 Jun 2022 19:32:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240358AbiFDTch (ORCPT ); Sat, 4 Jun 2022 15:32:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48218 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240741AbiFDTbl (ORCPT ); Sat, 4 Jun 2022 15:31:41 -0400 Received: from mail-qk1-x730.google.com (mail-qk1-x730.google.com [IPv6:2607:f8b0:4864:20::730]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3C40350030 for ; Sat, 4 Jun 2022 12:31:23 -0700 (PDT) Received: by mail-qk1-x730.google.com with SMTP id 15so3180689qki.6 for ; Sat, 04 Jun 2022 12:31:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tBLUoPSxSGKqcejJuuf09USNiWA4deHhuF7lsarfJlk=; b=b8ibYrANVzYijUODa3pl10vPBNYWfl7jr/XJ0dU3DOVCP57IAou/cLUfCpFakBCDY3 K575QZbv3eNn7iKbYcpqiuW9KTxgO/xwOjxQU0srH9MLM8L2AGsLK7FKCRhrKXy9aqfm /cpXC3HqPAkEk2S3gRtHNOTWZqzLBcOnFKxG9hYKi7Kx6kywT9LorSWdxoD8aA72zoAG 8eACTq4BGw9zdjFvUK2FAee3elqFwkqMDglw3/YWtIQisnu5rw/9UCO4bnIQnt72EtlD TCaFjJfgQApWcuht3Y/itnuqRXuzCJVjwjJFqliuc8zFuN5MVGVyfhiZI8tkzejw/gvo aX9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tBLUoPSxSGKqcejJuuf09USNiWA4deHhuF7lsarfJlk=; b=OA8NJhhJtYQ6deDCKHdeU4Gg0lH75YzGS6FmNqJNp1zLCeB/4YEVst/Y9gPQTW73t5 ggKiOxv5I00WY5IjQdzffuy9YX9kJAbrrpAbRUDkeGicC2tLXSe0WycxqFwzT6N6+mZ5 SRlhlczbLsAAvvcGgtcIftsNAPQq/nBpY3q65CVaQ5RhUlCHZmik8rO1nVTHaN4Q4nuX C0YpxfTqqG793x3HcBS932D0LCqKAH9THSEFwzf1QNm5iztkdgsN8gAg5soB8qo21fB0 6KqskzYUtbMJ/ypSiPV97mISprj//6RoyPL68MW20vZU+NcPF0Hur9avT9TB3GZd5VRl bH8w== X-Gm-Message-State: AOAM531U+0+VXEtNNlbh/HYfsAKaTYhsK5VPgA1ju9Mp9AzbhmDWA8qp LR13hfp2CaNjpwttYpbVqQcODoedfqMJ X-Google-Smtp-Source: ABdhPJxV991bBD3QwqWsTw3IDLsLBmeZHoyyMOxLxoxh00qU774JUl1cV2K9WSceT4W7bgiusGKMgw== X-Received: by 2002:ae9:eb94:0:b0:6a6:a208:e420 with SMTP id b142-20020ae9eb94000000b006a6a208e420mr5815509qkg.684.1654371081736; Sat, 04 Jun 2022 12:31:21 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:20 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 21/33] vsprintf: Refactor device_node_string, fwnode_string Date: Sat, 4 Jun 2022 15:30:30 -0400 Message-Id: <20220604193042.1674951-22-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" - eliminate on-stack buffer in device_node_string - eliminate unnecessary uses of printf_spec, lift format string precision/field width to pointer() Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 73 ++++++++++++++++++++------------------------------ 1 file changed, 29 insertions(+), 44 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 1cd08d0d5b..a0a17a2aac 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -1988,25 +1988,20 @@ void fwnode_full_name_string(struct printbuf *out, =20 static noinline_for_stack void device_node_string(struct printbuf *out, struct device_node *dn, - struct printf_spec spec, const char *fmt) + const char *fmt) { - char tbuf[sizeof("xxxx") + 1]; const char *p; int ret; - unsigned start =3D out->pos; struct property *prop; bool has_mult, pass; =20 - struct printf_spec str_spec =3D spec; - str_spec.field_width =3D -1; - if (fmt[0] !=3D 'F') - return error_string_spec(out, "(%pO?)", spec); + return error_string(out, "(%pO?)"); =20 if (!IS_ENABLED(CONFIG_OF)) - return error_string_spec(out, "(%pOF?)", spec); + return error_string(out, "(%pOF?)"); =20 - if (check_pointer_spec(out, dn, spec)) + if (check_pointer(out, dn)) return; =20 /* simple case without anything any more format specifiers */ @@ -2015,7 +2010,6 @@ void device_node_string(struct printbuf *out, struct = device_node *dn, fmt =3D "f"; =20 for (pass =3D false; strspn(fmt,"fnpPFcC"); fmt++, pass =3D true) { - int precision; if (pass) prt_char(out, ':'); =20 @@ -2023,43 +2017,41 @@ void device_node_string(struct printbuf *out, struc= t device_node *dn, case 'f': /* full_name */ fwnode_full_name_string(out, of_fwnode_handle(dn)); break; - case 'n': /* name */ - p =3D fwnode_get_name(of_fwnode_handle(dn)); - precision =3D str_spec.precision; - str_spec.precision =3D strchrnul(p, '@') - p; - string_spec(out, p, str_spec); - str_spec.precision =3D precision; + case 'n': { /* name */ + const char *name =3D fwnode_get_name(of_fwnode_handle(dn)); + unsigned len =3D strchrnul(name, '@') - name; + + prt_bytes(out, name, len); break; + } case 'p': /* phandle */ - prt_u64(out, (unsigned int)dn->phandle); + prt_u64(out, dn->phandle); break; case 'P': /* path-spec */ p =3D fwnode_get_name(of_fwnode_handle(dn)); if (!p[1]) p =3D "/"; - string_spec(out, p, str_spec); + string(out, p); break; case 'F': /* flags */ - tbuf[0] =3D of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-'; - tbuf[1] =3D of_node_check_flag(dn, OF_DETACHED) ? 'd' : '-'; - tbuf[2] =3D of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-'; - tbuf[3] =3D of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-'; - tbuf[4] =3D 0; - string_nocheck(out, tbuf, str_spec); + prt_char(out, of_node_check_flag(dn, OF_DYNAMIC) ? 'D' : '-'); + prt_char(out, of_node_check_flag(dn, OF_DETACHED) ? 'd' : '-'); + prt_char(out, of_node_check_flag(dn, OF_POPULATED) ? 'P' : '-'); + prt_char(out, of_node_check_flag(dn, OF_POPULATED_BUS) ? 'B' : '-'); break; case 'c': /* major compatible string_spec */ ret =3D of_property_read_string(dn, "compatible", &p); if (!ret) - string_spec(out, p, str_spec); + string(out, p); break; case 'C': /* full compatible string_spec */ has_mult =3D false; of_property_for_each_string(dn, "compatible", prop, p) { if (has_mult) - string_nocheck(out, ",", str_spec); - string_nocheck(out, "\"", str_spec); - string_spec(out, p, str_spec); - string_nocheck(out, "\"", str_spec); + prt_char(out, ','); + prt_char(out, '\"'); + string(out, p); + prt_char(out, '\"'); =20 has_mult =3D true; } @@ -2068,39 +2060,30 @@ void device_node_string(struct printbuf *out, struc= t device_node *dn, break; } } - - widen_string(out, out->pos - start, spec); } =20 static noinline_for_stack void fwnode_string(struct printbuf *out, struct fwnode_handle *fwnode, - struct printf_spec spec, const char *fmt) + const char *fmt) { - struct printf_spec str_spec =3D spec; - unsigned start =3D out->pos; - - str_spec.field_width =3D -1; - if (*fmt !=3D 'w') - return error_string_spec(out, "(%pf?)", spec); + return error_string(out, "(%pf?)"); =20 - if (check_pointer_spec(out, fwnode, spec)) + if (check_pointer(out, fwnode)) return; =20 fmt++; =20 switch (*fmt) { case 'P': /* name */ - string_spec(out, fwnode_get_name(fwnode), str_spec); + string(out, fwnode_get_name(fwnode)); break; case 'f': /* full_name */ default: fwnode_full_name_string(out, fwnode); break; } - - widen_string(out, out->pos - start, spec); } =20 int __init no_hash_pointers_enable(char *str) @@ -2338,9 +2321,11 @@ void pointer(struct printbuf *out, const char *fmt, flags_string(out, ptr, fmt); return do_width_precision(out, prev_pos, spec); case 'O': - return device_node_string(out, ptr, spec, fmt + 1); + device_node_string(out, ptr, fmt + 1); + return do_width_precision(out, prev_pos, spec); case 'f': - return fwnode_string(out, ptr, spec, fmt + 1); + fwnode_string(out, ptr, fmt + 1); + return do_width_precision(out, prev_pos, spec); case 'x': return pointer_string(out, ptr, spec); case 'e': --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45E65C433EF for ; Sat, 4 Jun 2022 19:32:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240980AbiFDTcz (ORCPT ); Sat, 4 Jun 2022 15:32:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48340 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240791AbiFDTbn (ORCPT ); Sat, 4 Jun 2022 15:31:43 -0400 Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 573AA50040 for ; Sat, 4 Jun 2022 12:31:24 -0700 (PDT) Received: by mail-qk1-x72a.google.com with SMTP id k6so5324321qkf.4 for ; Sat, 04 Jun 2022 12:31:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=n7xTWujhYMsquXrLDM3KnLZABLDfbSvZSUE+dtyzLjg=; b=j+dS3Sm7mCs9vz5MLK96Drd23NgqBEeJRajz2q6+z/CmZfZP79QLhdRJTt6Z4z3fav aqsEZHJPeZ7fMSSNqgiq0u/Rn60jK20Hnhi729Zq0LSNC75S+TMMa0hzraMd6P3p4QT7 uPi+RBOEv0jSJ+r9jRg9zCMBdokH5ek9rJpQz2qtjoZE7Mw65/5PrBFMs3U5OsvdUDpi zcJnPVsfOK5pX0ZfFawZ+Bxvuqz+bjQanSuzSlt5vmZqvcb/bF6ps2beSZLVpZG/4L+P rVLLV42Yyzc769T0Rh4oNgxp57dIB8e+vGOcdKvMd4dapUQ97A0DpHOsMjKExnNyRjFK 4rdw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=n7xTWujhYMsquXrLDM3KnLZABLDfbSvZSUE+dtyzLjg=; b=q/B84ni27Uu4xQ8KVk8Az7SFYUlzFkDa0kYlELW2K/cwqRlJ85ixNyBn3ZV4YrCtkb z3xLmwNLIYGsumtl2ZMvRDowRvKtI6B9SiD150rByDNqs4iv4UtITdKSpVeLf0y7pWgj VJplyQFlp5/vmE/G5tk1BTKiULjYUYOdumKWEPca2n0FJd8PlejfzN5eoNuHHFj5yns8 aLTtKMJVgvOejpHyPoEdFUi55cs7WRIMlUqspQ3A3j2SnGWdSKdkeTLn5TS+oaXl6WEJ /5ZpdDDWML59I5anQpSQcB/HMauo6jJs3DVmmK1xKiMVI55sYMORdBoUidj//SCUpo9R kovw== X-Gm-Message-State: AOAM533iFuWjRTc3Iku5TSxWTzxjafI2KM6VU9d7S4pNBeosM40T+SPC pmv6yJfu4Zn8NtmjPMgq1YIURuLKI2+h X-Google-Smtp-Source: ABdhPJyppCrJhWA8B0jX1JiXHPJUTI3RdVRs5XLjOnpRkODmDCM9/4o0ImXLaDwEXp4jw/rJ2oOeDA== X-Received: by 2002:a37:614a:0:b0:6a6:af3b:e9cb with SMTP id v71-20020a37614a000000b006a6af3be9cbmr2123015qkb.744.1654371083363; Sat, 04 Jun 2022 12:31:23 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:22 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 22/33] vsprintf: Refactor hex_string, bitmap_string_list, bitmap_string Date: Sat, 4 Jun 2022 15:30:31 -0400 Message-Id: <20220604193042.1674951-23-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This patch cleans up printf_spec handling: these functions only use spec.field_width and they do not interpret it in the normal way - instead it's a number of bits/bytes passed in to print, so these functions are changed to take that parameter directly. Signed-off-by: Kent Overstreet --- lib/vsprintf.c | 60 +++++++++++++++++++++++--------------------------- 1 file changed, 28 insertions(+), 32 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index a0a17a2aac..f5c93c36fa 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -53,6 +53,7 @@ #include =20 #include +#include #include "kstrtox.h" =20 /* Disable pointer hashing if requested */ @@ -1151,18 +1152,23 @@ void resource_string(struct printbuf *out, struct r= esource *res, } =20 static noinline_for_stack -void hex_string(struct printbuf *out, u8 *addr, - struct printf_spec spec, const char *fmt) +void hex_string(struct printbuf *out, const u8 *addr, + int len, const char *fmt) { - int i, len =3D 1; /* if we pass '%ph[CDN]', field width remains - negative value, fallback to the default */ char separator; =20 - if (spec.field_width =3D=3D 0) - /* nothing to print */ + /* nothing to print */ + if (len =3D=3D 0) return; =20 - if (check_pointer_spec(out, addr, spec)) + /* if we pass '%ph[CDN]', field width remains + negative value, fallback to the default */ + if (len < 0) + len =3D 1; + + len =3D min(len, 64); + + if (check_pointer(out, addr)) return; =20 switch (fmt[1]) { @@ -1180,34 +1186,21 @@ void hex_string(struct printbuf *out, u8 *addr, break; } =20 - if (spec.field_width > 0) - len =3D min_t(int, spec.field_width, 64); - - for (i =3D 0; i < len; ++i) { - __prt_char(out, hex_asc_hi(addr[i])); - __prt_char(out, hex_asc_lo(addr[i])); - - if (separator && i !=3D len - 1) - __prt_char(out, separator); - } - - printbuf_nul_terminate(out); + prt_hex_bytes(out, addr, len, 1, separator); } =20 static noinline_for_stack -void bitmap_string(struct printbuf *out, unsigned long *bitmap, - struct printf_spec spec, const char *fmt) +void bitmap_string(struct printbuf *out, unsigned long *bitmap, int nr_bit= s) { + struct printf_spec spec =3D { .flags =3D SMALL | ZEROPAD, .base =3D 16 }; const int CHUNKSZ =3D 32; - int nr_bits =3D max_t(int, spec.field_width, 0); int i, chunksz; bool first =3D true; =20 - if (check_pointer_spec(out, bitmap, spec)) - return; + nr_bits =3D max(nr_bits, 0); =20 - /* reused to print numbers */ - spec =3D (struct printf_spec){ .flags =3D SMALL | ZEROPAD, .base =3D 16 }; + if (check_pointer(out, bitmap)) + return; =20 chunksz =3D nr_bits & (CHUNKSZ - 1); if (chunksz =3D=3D 0) @@ -1236,13 +1229,14 @@ void bitmap_string(struct printbuf *out, unsigned l= ong *bitmap, =20 static noinline_for_stack void bitmap_list_string(struct printbuf *out, unsigned long *bitmap, - struct printf_spec spec, const char *fmt) + int nr_bits) { - int nr_bits =3D max_t(int, spec.field_width, 0); bool first =3D true; int rbot, rtop; =20 - if (check_pointer_spec(out, bitmap, spec)) + nr_bits =3D max(nr_bits, 0); + + if (check_pointer(out, bitmap)) return ; =20 for_each_set_bitrange(rbot, rtop, bitmap, nr_bits) { @@ -2257,13 +2251,15 @@ void pointer(struct printbuf *out, const char *fmt, resource_string(out, ptr, fmt[0] =3D=3D 'R'); return do_width_precision(out, prev_pos, spec); case 'h': - return hex_string(out, ptr, spec, fmt); + /* Uses field_width but _not_ as field size */ + return hex_string(out, ptr, spec.field_width, fmt); case 'b': + /* Uses field_width but _not_ as field size */ switch (fmt[1]) { case 'l': - return bitmap_list_string(out, ptr, spec, fmt); + return bitmap_list_string(out, ptr, spec.field_width); default: - return bitmap_string(out, ptr, spec, fmt); + return bitmap_string(out, ptr, spec.field_width); } case 'M': /* Colon separated: 00:01:02:03:04:05 */ case 'm': /* Contiguous: 000102030405 */ --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D1AE3C43334 for ; Sat, 4 Jun 2022 19:33:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241146AbiFDTc7 (ORCPT ); Sat, 4 Jun 2022 15:32:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47498 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240824AbiFDTbn (ORCPT ); Sat, 4 Jun 2022 15:31:43 -0400 Received: from mail-qv1-xf32.google.com (mail-qv1-xf32.google.com [IPv6:2607:f8b0:4864:20::f32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4509550054 for ; Sat, 4 Jun 2022 12:31:26 -0700 (PDT) Received: by mail-qv1-xf32.google.com with SMTP id u8so7808560qvj.2 for ; Sat, 04 Jun 2022 12:31:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=twQ/l/SSVqpaC5DgYCH7VSwC9ALcVhz/FUNTup042zw=; b=Pq1aVOpBoqOFqZVHk+9X2Ha0pzyJLlZ0SJ56FoTjDlD//Vt+ICDz0Pc7OfLeYV9d+i WNDXN+/eGNFSnDey1xe/IV5JnlIlEFAUfbhMSDLdUvYio64ZtgOUEaTdejLNYwbGlJIc ihy3R5Kh9Mpb1lpdZfoP069T8mfl7/0p8LlZNmRhDzJQy7VeKb5cHt3VegvSfxfI68cF 124mPZILgRqzpA4EqRg9yeAdAoxAqZ1K50Oqkdhx5oIvgqDgjd38t7US4e87rTDbkHRJ obX1iOirBb0tph2oARKt3XDDZIdJBpXVT2XN7aNVAavRGAnKi5VVxOlv2PhP1mDeEsat f29w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=twQ/l/SSVqpaC5DgYCH7VSwC9ALcVhz/FUNTup042zw=; b=HyBValA0IF8kdwVR3rV5e7Gr0cwzBhGG1ZffdKaG1dJUL8e3+ane1Oemf9N3tf4mQ4 QY4kW6YSlu265AHY+QF0uj4J2whCSo82UR60kNTqGEhMqpwHhTc4pGU4a6pzd6i7CL2U wspk9GpeLWGq3qulwEkDs8iVg9XzF8ZUDr1zyj6cdj1P4vonLXJpo89QwIsBbOt+GZIU wmdoPk4DRHaVL2EJ04N6tPKeL1V6JUhgeP+52Q0o2JC8v+4V0yZImaNvyBLNGYzuAo1X lRkBcSpHsSH+f5Vj8Xl/t+ycuX4ADU0EL1ME9cTU5QdciMDKsrHnACdXcsDFgswC1Y8X 7ZxQ== X-Gm-Message-State: AOAM5331K0OU+BzbDhyXcH9+WVfgaQMCyFoz7mHkB7FT678mNm+QIAvs jqE8KZR4472zZUQKMy3/0wuQzKFtxomv X-Google-Smtp-Source: ABdhPJzfXdmtWyzWeixbaNma8wEgUblOis9qeSNZ6Bqys/lu8X8bd4LkFPW8KHMjxZT5Jv3UwOCTcQ== X-Received: by 2002:a0c:e790:0:b0:46a:916:32c5 with SMTP id x16-20020a0ce790000000b0046a091632c5mr5533882qvn.129.1654371084778; Sat, 04 Jun 2022 12:31:24 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:24 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 23/33] Input/joystick/analog: Convert from seq_buf -> printbuf Date: Sat, 4 Jun 2022 15:30:32 -0400 Message-Id: <20220604193042.1674951-24-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" seq_buf is being deprecated, this converts to printbuf. Signed-off-by: Kent Overstreet --- drivers/input/joystick/analog.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analo= g.c index 3088c5b829..a8c5f90e82 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include =20 @@ -339,24 +339,21 @@ static void analog_calibrate_timer(struct analog_port= *port) =20 static void analog_name(struct analog *analog) { - struct seq_buf s; + struct printbuf buf =3D PRINTBUF_EXTERN(analog->name, sizeof(analog->name= )); =20 - seq_buf_init(&s, analog->name, sizeof(analog->name)); - seq_buf_printf(&s, "Analog %d-axis %d-button", - hweight8(analog->mask & ANALOG_AXES_STD), - hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTN= S_CHF) * 2 + - hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALO= G_HBTN_CHF) * 4); + prt_printf(&buf, "Analog %d-axis %d-button", + hweight8(analog->mask & ANALOG_AXES_STD), + hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALO= G_BTNS_CHF) * 2 + + hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & = ANALOG_HBTN_CHF) * 4); =20 if (analog->mask & ANALOG_HATS_ALL) - seq_buf_printf(&s, " %d-hat", - hweight16(analog->mask & ANALOG_HATS_ALL)); - + prt_printf(&buf, " %d-hat", hweight16(analog->mask & ANALOG_HATS_ALL)); if (analog->mask & ANALOG_HAT_FCS) - seq_buf_printf(&s, " FCS"); + prt_printf(&buf, " FCS"); if (analog->mask & ANALOG_ANY_CHF) - seq_buf_printf(&s, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); + prt_printf(&buf, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); =20 - seq_buf_printf(&s, (analog->mask & ANALOG_GAMEPAD) ? " gamepad" : " joyst= ick"); + prt_printf(&buf, (analog->mask & ANALOG_GAMEPAD) ? " gamepad" : " joystic= k"); } =20 /* --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 719C5C43334 for ; Sat, 4 Jun 2022 19:33:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241207AbiFDTdF (ORCPT ); Sat, 4 Jun 2022 15:33:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48202 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240532AbiFDTbo (ORCPT ); Sat, 4 Jun 2022 15:31:44 -0400 Received: from mail-qv1-xf2e.google.com (mail-qv1-xf2e.google.com [IPv6:2607:f8b0:4864:20::f2e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F20A95005F for ; Sat, 4 Jun 2022 12:31:28 -0700 (PDT) Received: by mail-qv1-xf2e.google.com with SMTP id l1so7812454qvh.1 for ; Sat, 04 Jun 2022 12:31:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uTBJQxxOq1+B+oEKPtyj8xG9RwTxPKpWggt48cPFUTs=; b=qF8hvl7FRdivZqjRtJV3KC4IjPjSaOkQ//qhUAMMund+hkAvcmgC8hOVy9dqOmOhHE SnAvDDqrFCTK2834+EwTE5QW2BvZ1djniF6FLRndwBhml8CZKkNNipJHa2t/3sKTg9Z/ CArej/tQ/ZK2Mni6YKXY6SwGB0SzCRgPID+7Oqd010mBCTipJZ3nG02+u3nulBzqjDEo hm2Vw4CVdR40mQG4ycSi5J3BVJN0GfEInoz2uFU7nYhs9BpqvVy0k6nPucgq51DTa+rk XrNeRFuHL15ytdaiRkSvvNKggJ+CA86Z605rPC3azKAb5pyMWZgBX8/WudQ5B78kNqXX 2h1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uTBJQxxOq1+B+oEKPtyj8xG9RwTxPKpWggt48cPFUTs=; b=LGP7lbwoaQjOTtBPbe0wCr8sIrBCSBrCwabcb0Cov7PMlFWaI6OnP+dMGRES82Gjuy 9TXJ9E3V+4R4l9KcH8LwiRy7BWz7coVmZUDFWfdN+0HmWjLbCCIpZnrRWl+bUbK4ed5T uoG0UFadIvVdpkw3FHf1843DlffhXyR1f79v5xXHDhuCkpTyChC2iWVu1MPNS+iEPA3c lp4Np/amABKupa94BUJRtQu1VGdrVYH2UIS4JB6rZXAtRhLnIzp5LY3Pr5Rsc+IDKZwJ opFzGDDE4iD/cpP5N9nzvRhPAbh+CtKDazVaceahNPmmGMUneI+4MIVNM6OAs7hHuivn BqFA== X-Gm-Message-State: AOAM530fDyk9H9YaIB/iwksZDOh0ftsrSVJDfxcOoISazld2CMnzzalH WOgZlyxVTcd+uRcVDR5rA1joJioFeHoe X-Google-Smtp-Source: ABdhPJyup4DVXawsaJXGhDU1HMeqJkb2a5r+HIeWjsqJ7vBBtcWqrYj0+HHTr/GSS/jvqIzsiZu2jQ== X-Received: by 2002:a05:6214:5097:b0:466:c160:e585 with SMTP id kk23-20020a056214509700b00466c160e585mr12929848qvb.54.1654371086393; Sat, 04 Jun 2022 12:31:26 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:25 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 24/33] mm/memcontrol.c: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:33 -0400 Message-Id: <20220604193042.1674951-25-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts memory_stat_format() from seq_buf to printbuf. Printbuf is simalar to seq_buf except that it heap allocates the string buffer: here, we were already heap allocating the buffer with kmalloc() so the conversion is trivial. Signed-off-by: Kent Overstreet --- mm/memcontrol.c | 68 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 598fece89e..57861dc9fe 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -62,7 +62,7 @@ #include #include #include -#include +#include #include "internal.h" #include #include @@ -1461,13 +1461,9 @@ static inline unsigned long memcg_page_state_output(= struct mem_cgroup *memcg, =20 static char *memory_stat_format(struct mem_cgroup *memcg) { - struct seq_buf s; + struct printbuf buf =3D PRINTBUF; int i; =20 - seq_buf_init(&s, kmalloc(PAGE_SIZE, GFP_KERNEL), PAGE_SIZE); - if (!s.buffer) - return NULL; - /* * Provide statistics on the state of the memory subsystem as * well as cumulative event counters that show past behavior. @@ -1484,49 +1480,51 @@ static char *memory_stat_format(struct mem_cgroup *= memcg) u64 size; =20 size =3D memcg_page_state_output(memcg, memory_stats[i].idx); - seq_buf_printf(&s, "%s %llu\n", memory_stats[i].name, size); + prt_printf(&buf, "%s %llu\n", memory_stats[i].name, size); =20 if (unlikely(memory_stats[i].idx =3D=3D NR_SLAB_UNRECLAIMABLE_B)) { size +=3D memcg_page_state_output(memcg, NR_SLAB_RECLAIMABLE_B); - seq_buf_printf(&s, "slab %llu\n", size); + prt_printf(&buf, "slab %llu\n", size); } } =20 /* Accumulated memory events */ =20 - seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGFAULT), - memcg_events(memcg, PGFAULT)); - seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGMAJFAULT), - memcg_events(memcg, PGMAJFAULT)); - seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGREFILL), - memcg_events(memcg, PGREFILL)); - seq_buf_printf(&s, "pgscan %lu\n", - memcg_events(memcg, PGSCAN_KSWAPD) + - memcg_events(memcg, PGSCAN_DIRECT)); - seq_buf_printf(&s, "pgsteal %lu\n", - memcg_events(memcg, PGSTEAL_KSWAPD) + - memcg_events(memcg, PGSTEAL_DIRECT)); - seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGACTIVATE), - memcg_events(memcg, PGACTIVATE)); - seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGDEACTIVATE), - memcg_events(memcg, PGDEACTIVATE)); - seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGLAZYFREE), - memcg_events(memcg, PGLAZYFREE)); - seq_buf_printf(&s, "%s %lu\n", vm_event_name(PGLAZYFREED), - memcg_events(memcg, PGLAZYFREED)); + prt_printf(&buf, "%s %lu\n", vm_event_name(PGFAULT), + memcg_events(memcg, PGFAULT)); + prt_printf(&buf, "%s %lu\n", vm_event_name(PGMAJFAULT), + memcg_events(memcg, PGMAJFAULT)); + prt_printf(&buf, "%s %lu\n", vm_event_name(PGREFILL), + memcg_events(memcg, PGREFILL)); + prt_printf(&buf, "pgscan %lu\n", + memcg_events(memcg, PGSCAN_KSWAPD) + + memcg_events(memcg, PGSCAN_DIRECT)); + prt_printf(&buf, "pgsteal %lu\n", + memcg_events(memcg, PGSTEAL_KSWAPD) + + memcg_events(memcg, PGSTEAL_DIRECT)); + prt_printf(&buf, "%s %lu\n", vm_event_name(PGACTIVATE), + memcg_events(memcg, PGACTIVATE)); + prt_printf(&buf, "%s %lu\n", vm_event_name(PGDEACTIVATE), + memcg_events(memcg, PGDEACTIVATE)); + prt_printf(&buf, "%s %lu\n", vm_event_name(PGLAZYFREE), + memcg_events(memcg, PGLAZYFREE)); + prt_printf(&buf, "%s %lu\n", vm_event_name(PGLAZYFREED), + memcg_events(memcg, PGLAZYFREED)); =20 #ifdef CONFIG_TRANSPARENT_HUGEPAGE - seq_buf_printf(&s, "%s %lu\n", vm_event_name(THP_FAULT_ALLOC), - memcg_events(memcg, THP_FAULT_ALLOC)); - seq_buf_printf(&s, "%s %lu\n", vm_event_name(THP_COLLAPSE_ALLOC), - memcg_events(memcg, THP_COLLAPSE_ALLOC)); + prt_printf(&buf, "%s %lu\n", vm_event_name(THP_FAULT_ALLOC), + memcg_events(memcg, THP_FAULT_ALLOC)); + prt_printf(&buf, "%s %lu\n", vm_event_name(THP_COLLAPSE_ALLOC), + memcg_events(memcg, THP_COLLAPSE_ALLOC)); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ =20 - /* The above should easily fit into one page */ - WARN_ON_ONCE(seq_buf_has_overflowed(&s)); + if (buf.allocation_failure) { + printbuf_exit(&buf); + return NULL; + } =20 - return s.buffer; + return buf.buf; } =20 #define K(x) ((x) << (PAGE_SHIFT-10)) --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DD811C433EF for ; Sat, 4 Jun 2022 19:33:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240437AbiFDTdK (ORCPT ); Sat, 4 Jun 2022 15:33:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47510 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240589AbiFDTbp (ORCPT ); Sat, 4 Jun 2022 15:31:45 -0400 Received: from mail-qk1-x730.google.com (mail-qk1-x730.google.com [IPv6:2607:f8b0:4864:20::730]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F8A95006A for ; Sat, 4 Jun 2022 12:31:31 -0700 (PDT) Received: by mail-qk1-x730.google.com with SMTP id x75so4967012qkb.12 for ; Sat, 04 Jun 2022 12:31:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=VJKGBDexodWWi3v7d8CIP7nDbDAKpXAShXjsyM+XqYo=; b=L2aTCNAmvIeV+mmoBcGrwRVseEMQ39fJ5n8rwtdgsPesbbN4QJaLLyAyaaJEAZ1eGr bZcRZK/rri1uLE2KV3EOsQ9SizakITASmJSCRTRrcj9zKU+zJwrnveRiUR8fRe6NUBeG HawmFj4dJB6TflzYC+208jPJ1c0mI/IN/IE3KQYwS/dP8czbRj5pRCUTdzIA3hLmTRa7 SED/W4SYB8WGPmR6HUBBcWQPJuXh/GyI5VcFnRJhcgMbHlhrkZuL/3A1rr9hs9D2fPof Y2l4JGEeDSPIvCMuQpCV5xMGBF29JV8mozNwUHvqE2wKYS3ofK0WrWyL9sPxwiuVQLFq Y5xw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=VJKGBDexodWWi3v7d8CIP7nDbDAKpXAShXjsyM+XqYo=; b=v/heGYP763+BzTcYkfwD5aNu9uO6CuscPz+J8oay1uRKS+H3WqohXOzK9XHgIM79aV hZV3HOcsjkty20WzlJ8oWor+kFZ9JevVPotYsB78g9ytX/1pBvSNBY1Dgr5QMQnhLL3J /wiZXfPN9f+69Ky3DX7cPWJ2MIRVAXmYVJTvarzLQdnrY06O/oZk5CiS+uOYtR94ZV4x W8Y+Mq3RX8k7tfbZAgS1aoyT01/JLU3gittyNufJz4nsU+3J1q7D7v6q7lpdBrk7Lp4u /5MEfEWu/nR8z/3zzMnS1JOdA70T7/Sd1np6PktMPSqipTE1zwGoX15nEkZweUDFdpIY ptWA== X-Gm-Message-State: AOAM531LiZa2nfhzU/2b2cBImu7y0yMSQlkTNCtOWZ5kXoddfDKtHJx3 hYS8cm0G+RQlWgFWQiK7i55KyO3aTBKd X-Google-Smtp-Source: ABdhPJwOcaHElFrLXXJvVqSZ3B+X4j3Ba3ekudjRftXMdJ/1Ph/Sgr2Q2VR4uSJIqWu5zLwMHUPHsg== X-Received: by 2002:a37:a683:0:b0:6a6:ae13:7df8 with SMTP id p125-20020a37a683000000b006a6ae137df8mr2473713qke.385.1654371088085; Sat, 04 Jun 2022 12:31:28 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:27 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 25/33] clk: tegra: bpmp: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:34 -0400 Message-Id: <20220604193042.1674951-26-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts from seq_buf to printbuf, which is similar but heap allocates the string buffer. Previously in this code the string buffer was allocated on the stack; this means we've added a new potential memory allocation failure. This is fine though since it's only for a dev_printk() message. Memory allocation context: printbuf doesn't take gfp flags, instead we prefer the new memalloc_no*_(save|restore) interfaces to be used. Here the surrounding code is already allocating with GFP_KERNEL, so everything is fine. Signed-off-by: Kent Overstreet --- drivers/clk/tegra/clk-bpmp.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/drivers/clk/tegra/clk-bpmp.c b/drivers/clk/tegra/clk-bpmp.c index 6ecf18f71c..301551174c 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -5,7 +5,7 @@ =20 #include #include -#include +#include #include =20 #include @@ -360,39 +360,38 @@ static void tegra_bpmp_clk_info_dump(struct tegra_bpm= p *bpmp, const struct tegra_bpmp_clk_info *info) { const char *prefix =3D ""; - struct seq_buf buf; + struct printbuf buf =3D PRINTBUF; unsigned int i; - char flags[64]; - - seq_buf_init(&buf, flags, sizeof(flags)); =20 if (info->flags) - seq_buf_printf(&buf, "("); + prt_printf(&buf, "("); =20 if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { - seq_buf_printf(&buf, "%smux", prefix); + prt_printf(&buf, "%smux", prefix); prefix =3D ", "; } =20 if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) =3D=3D 0) { - seq_buf_printf(&buf, "%sfixed", prefix); + prt_printf(&buf, "%sfixed", prefix); prefix =3D ", "; } =20 if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) { - seq_buf_printf(&buf, "%sroot", prefix); + prt_printf(&buf, "%sroot", prefix); prefix =3D ", "; } =20 if (info->flags) - seq_buf_printf(&buf, ")"); + prt_printf(&buf, ")"); =20 dev_printk(level, bpmp->dev, "%03u: %s\n", info->id, info->name); - dev_printk(level, bpmp->dev, " flags: %lx %s\n", info->flags, flags); + dev_printk(level, bpmp->dev, " flags: %lx %s\n", info->flags, printbuf_s= tr(&buf)); dev_printk(level, bpmp->dev, " parents: %u\n", info->num_parents); =20 for (i =3D 0; i < info->num_parents; i++) dev_printk(level, bpmp->dev, " %03u\n", info->parents[i]); + + printbuf_exit(&buf); } =20 static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp, --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 54F93C433EF for ; Sat, 4 Jun 2022 19:33:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241061AbiFDTdZ (ORCPT ); Sat, 4 Jun 2022 15:33:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48570 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240865AbiFDTbt (ORCPT ); Sat, 4 Jun 2022 15:31:49 -0400 Received: from mail-qk1-x729.google.com (mail-qk1-x729.google.com [IPv6:2607:f8b0:4864:20::729]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 27FDD50448 for ; Sat, 4 Jun 2022 12:31:36 -0700 (PDT) Received: by mail-qk1-x729.google.com with SMTP id az35so1177947qkb.3 for ; Sat, 04 Jun 2022 12:31:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HmYk1E0nlrVwRWwFSUC/a4yoPMG0X4XicsKq1hOz6KU=; b=PJoje00985N6oGb/Y7bGsu79gRdWGwWmNVnvrX06a4qBWEHiGWQMqbbjrBD0FWF2C9 hSxat3cFEp6yEukLVpR44SfZoxpFuoy8AW0TgKufz1DdZL5g4kNAzKJx0SPBApiG7uu9 5iJ5dC8D+KXHkXvGpc8je01NDyf1w/bitToUoQPbJleWS5Aihp4Z6oeD3doWmT251/Cp rh9gw83EVSkHrRClNO/OBunWbwOxu/mC3V+aooYZnVFQS+qMckTUvctDbOhw6s9TmWyO II1dLerx3Cqsh6cZ78WG0pNY2U19ON3i0qzCmNq4qNtFUNIlU8RatEylhTfDZWObcyZz JZvg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HmYk1E0nlrVwRWwFSUC/a4yoPMG0X4XicsKq1hOz6KU=; b=drX+fwuhq8RLSL9bGneFPl/2UIBFihyc3nyoUgNs8Ikx5jIX1NbuLM2jjBBra3T6px Mn7vKP73GXhiH4ur9bDpmZShgpi7uc9Wrr7AioIgGfKoAptPuf8zM/CNpKQe2pQoTttJ ftyK2ZsoPDLPZ8Qn4YzisPA83XRL4buLuq+6YUKuVbllHp2k1Txcff+XO6isoT/mgWYV b3ybm5OWPiK/fXInAxUdyM/T5lXXZZEgeULQHDWx/gWwENnMKMrbTccR/1iiohjsk/iz ldRnYo1WVfY4s8IYSgEf8nOwDi6v6sIBzEUXDGfhszWEyHkRE6YKKqSzAoAxggRE+DZ4 UXSg== X-Gm-Message-State: AOAM533GsLZs8SP8iIfMOEoZecQsLUuZcWpYXfFxav1hASG+DBVCBxAZ CFtwlxN/1VeHpwia+YqJn6/mHzn9rf1j X-Google-Smtp-Source: ABdhPJx+3SHYROOTVTOhx/1YUWQwQKfJsM6CjtyyJSI2BNjTj2VGslnIUXruGHfNZ1OR/0E4gZ8QFQ== X-Received: by 2002:a05:620a:2586:b0:680:f846:4708 with SMTP id x6-20020a05620a258600b00680f8464708mr10998237qko.654.1654371089527; Sat, 04 Jun 2022 12:31:29 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:28 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org, Dan Williams , Dave Hansen , nvdimm@lists.linux.dev Subject: [PATCH v3 26/33] tools/testing/nvdimm: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:35 -0400 Message-Id: <20220604193042.1674951-27-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts from seq_buf to printbuf. Here we're using printbuf with an external buffer, meaning it's a direct conversion. Signed-off-by: Kent Overstreet Cc: Dan Williams Cc: Dave Hansen Cc: nvdimm@lists.linux.dev --- tools/testing/nvdimm/test/ndtest.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/tools/testing/nvdimm/test/ndtest.c b/tools/testing/nvdimm/test= /ndtest.c index 4d1a947367..a2097955da 100644 --- a/tools/testing/nvdimm/test/ndtest.c +++ b/tools/testing/nvdimm/test/ndtest.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include =20 #include "../watermark.h" #include "nfit_test.h" @@ -740,32 +740,30 @@ static ssize_t flags_show(struct device *dev, { struct nvdimm *nvdimm =3D to_nvdimm(dev); struct ndtest_dimm *dimm =3D nvdimm_provider_data(nvdimm); - struct seq_buf s; + struct printbuf s =3D PRINTBUF_EXTERN(buf, PAGE_SIZE); u64 flags; =20 flags =3D dimm->flags; =20 - seq_buf_init(&s, buf, PAGE_SIZE); if (flags & PAPR_PMEM_UNARMED_MASK) - seq_buf_printf(&s, "not_armed "); + prt_printf(&s, "not_armed "); =20 if (flags & PAPR_PMEM_BAD_SHUTDOWN_MASK) - seq_buf_printf(&s, "flush_fail "); + prt_printf(&s, "flush_fail "); =20 if (flags & PAPR_PMEM_BAD_RESTORE_MASK) - seq_buf_printf(&s, "restore_fail "); + prt_printf(&s, "restore_fail "); =20 if (flags & PAPR_PMEM_SAVE_MASK) - seq_buf_printf(&s, "save_fail "); + prt_printf(&s, "save_fail "); =20 if (flags & PAPR_PMEM_SMART_EVENT_MASK) - seq_buf_printf(&s, "smart_notify "); + prt_printf(&s, "smart_notify "); =20 + if (printbuf_written(&s)) + prt_printf(&s, "\n"); =20 - if (seq_buf_used(&s)) - seq_buf_printf(&s, "\n"); - - return seq_buf_used(&s); + return printbuf_written(&s); } static DEVICE_ATTR_RO(flags); =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A4BA5C43334 for ; Sat, 4 Jun 2022 19:33:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241034AbiFDTdf (ORCPT ); Sat, 4 Jun 2022 15:33:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240786AbiFDTcH (ORCPT ); Sat, 4 Jun 2022 15:32:07 -0400 Received: from mail-qk1-x736.google.com (mail-qk1-x736.google.com [IPv6:2607:f8b0:4864:20::736]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4CD4B4F9E0 for ; Sat, 4 Jun 2022 12:31:45 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id n197so1310476qke.1 for ; Sat, 04 Jun 2022 12:31:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NlNl9OvEp4IMCqcRwg89/P60FLQNHXpSzQS3N1mbD9I=; b=PPCbCe1Cn5gxAVLp4/Tq89fTjn8y2mOUnl72vTehGJMskf+QM8QpgwisaBl2Q2Xu0L pcxb6StUmBT+NNKdGZ5Xtxds8951aeo7IWGcXVWYG54c4AnIkcrcXd+x/vxeG+lGqSts whMfrQQRkM7J7Q/HvLxmXgt1KpVkYaBWbq7Wz+QDmkF96YDxViWGXgMm+JdGvvOufjTv PODs0z/cH21o09MpkkWPj+1bL5uwG24sb4I5HW9Xx6mE6W7S2HwkP104pyS1a/pbWECy 5j/vOr1LKSNkyOpkxSwZziKo9ljKu6nIu7YJMEK2c4q8vEb7IoclRdSArDqNWUAQ1quX K24Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NlNl9OvEp4IMCqcRwg89/P60FLQNHXpSzQS3N1mbD9I=; b=xXJUNhKqX38fQrs2yIu4kixwetrT6AUA1go1Zc/ln25Zc/UKkmPM9/OWonBRtlolTi EYKHL07x36tR7ND/gm/2Qb91dXrUAcGVUK9Q63qjF8m8iIlHSCzv+smVP2210/bjnRFZ mIT33jihJ5RrLl8PCxFZDTL7gwAN4mgjcuQKbEzbXUVUqdqk4BqH6AkB1PHTa2vjvEy/ LU8QR+HGzTxU2Z1kxPIMx0q6WEHMBEgDTBH8/elpvIn4t8KSgzoY4EQgbynSLw+reF/k j21UlijRBDnnTKc7jLOl7Xurx9pZjql16S1KLgV2as+q8QysGKYEoogDvMFkt6rhtQzM ojGQ== X-Gm-Message-State: AOAM533NA/844rVtvWtrq32Ggbv4CmJnVTv4E4hFBk+chAKc5RKmDUky dOZrUXLVlClwNit/FSsfHb7GOP0y65R0 X-Google-Smtp-Source: ABdhPJzBRRjsEOdO/xHzCjiPIQRTFX3synBXQ85mW+EUDqbdptxp9HspSHmKHy7HY89aSSnWUYLjfQ== X-Received: by 2002:a05:620a:2943:b0:6a3:ac4d:5a4f with SMTP id n3-20020a05620a294300b006a3ac4d5a4fmr10776147qkp.159.1654371091071; Sat, 04 Jun 2022 12:31:31 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:30 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v3 27/33] powerpc: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:36 -0400 Message-Id: <20220604193042.1674951-28-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts from seq_buf to printbuf. We're using printbuf in external buffer mode, so it's a direct conversion, aside from some trivial refactoring in cpu_show_meltdown() to make the code more consistent. Signed-off-by: Kent Overstreet Cc: linuxppc-dev@lists.ozlabs.org --- arch/powerpc/kernel/process.c | 16 +++-- arch/powerpc/kernel/security.c | 75 ++++++++++------------- arch/powerpc/platforms/pseries/papr_scm.c | 34 +++++----- 3 files changed, 57 insertions(+), 68 deletions(-) diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 984813a4d5..fb8ba50223 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -39,7 +39,7 @@ #include #include #include -#include +#include =20 #include #include @@ -1399,32 +1399,30 @@ void show_user_instructions(struct pt_regs *regs) { unsigned long pc; int n =3D NR_INSN_TO_PRINT; - struct seq_buf s; char buf[96]; /* enough for 8 times 9 + 2 chars */ + struct printbuf s =3D PRINTBUF_EXTERN(buf, sizeof(buf)); =20 pc =3D regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int)); =20 - seq_buf_init(&s, buf, sizeof(buf)); - while (n) { int i; =20 - seq_buf_clear(&s); + printbuf_reset(&s); =20 for (i =3D 0; i < 8 && n; i++, n--, pc +=3D sizeof(int)) { int instr; =20 if (copy_from_user_nofault(&instr, (void __user *)pc, sizeof(instr))) { - seq_buf_printf(&s, "XXXXXXXX "); + prt_printf(&s, "XXXXXXXX "); continue; } - seq_buf_printf(&s, regs->nip =3D=3D pc ? "<%08x> " : "%08x ", instr); + prt_printf(&s, regs->nip =3D=3D pc ? "<%08x> " : "%08x ", instr); } =20 - if (!seq_buf_has_overflowed(&s)) + if (printbuf_remaining(&s)) pr_info("%s[%d]: code: %s\n", current->comm, - current->pid, s.buffer); + current->pid, s.buf); } } =20 diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c index d96fd14bd7..b34de62e65 100644 --- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include #include =20 #include @@ -144,31 +144,28 @@ void __init setup_spectre_v2(void) #ifdef CONFIG_PPC_BOOK3S_64 ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *att= r, char *buf) { + struct printbuf s =3D PRINTBUF_EXTERN(buf, PAGE_SIZE); bool thread_priv; =20 thread_priv =3D security_ftr_enabled(SEC_FTR_L1D_THREAD_PRIV); =20 if (rfi_flush) { - struct seq_buf s; - seq_buf_init(&s, buf, PAGE_SIZE - 1); =20 - seq_buf_printf(&s, "Mitigation: RFI Flush"); + prt_printf(&s, "Mitigation: RFI Flush"); if (thread_priv) - seq_buf_printf(&s, ", L1D private per thread"); - - seq_buf_printf(&s, "\n"); - - return s.len; + prt_printf(&s, ", L1D private per thread"); + + prt_printf(&s, "\n"); + } else if (thread_priv) { + prt_printf(&s, "Vulnerable: L1D private per thread\n"); + } else if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && + !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)) { + prt_printf(&s, "Not affected\n"); + } else { + prt_printf(&s, "Vulnerable\n"); } =20 - if (thread_priv) - return sprintf(buf, "Vulnerable: L1D private per thread\n"); - - if (!security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV) && - !security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR)) - return sprintf(buf, "Not affected\n"); - - return sprintf(buf, "Vulnerable\n"); + return printbuf_written(&s); } =20 ssize_t cpu_show_l1tf(struct device *dev, struct device_attribute *attr, c= har *buf) @@ -179,70 +176,66 @@ ssize_t cpu_show_l1tf(struct device *dev, struct devi= ce_attribute *attr, char *b =20 ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *a= ttr, char *buf) { - struct seq_buf s; - - seq_buf_init(&s, buf, PAGE_SIZE - 1); + struct printbuf s =3D PRINTBUF_EXTERN(buf, PAGE_SIZE); =20 if (security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR)) { if (barrier_nospec_enabled) - seq_buf_printf(&s, "Mitigation: __user pointer sanitization"); + prt_printf(&s, "Mitigation: __user pointer sanitization"); else - seq_buf_printf(&s, "Vulnerable"); + prt_printf(&s, "Vulnerable"); =20 if (security_ftr_enabled(SEC_FTR_SPEC_BAR_ORI31)) - seq_buf_printf(&s, ", ori31 speculation barrier enabled"); + prt_printf(&s, ", ori31 speculation barrier enabled"); =20 - seq_buf_printf(&s, "\n"); + prt_printf(&s, "\n"); } else - seq_buf_printf(&s, "Not affected\n"); + prt_printf(&s, "Not affected\n"); =20 - return s.len; + return printbuf_written(&s); } =20 ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *a= ttr, char *buf) { - struct seq_buf s; + struct printbuf s =3D PRINTBUF_EXTERN(buf, PAGE_SIZE); bool bcs, ccd; =20 - seq_buf_init(&s, buf, PAGE_SIZE - 1); - bcs =3D security_ftr_enabled(SEC_FTR_BCCTRL_SERIALISED); ccd =3D security_ftr_enabled(SEC_FTR_COUNT_CACHE_DISABLED); =20 if (bcs || ccd) { - seq_buf_printf(&s, "Mitigation: "); + prt_printf(&s, "Mitigation: "); =20 if (bcs) - seq_buf_printf(&s, "Indirect branch serialisation (kernel only)"); + prt_printf(&s, "Indirect branch serialisation (kernel only)"); =20 if (bcs && ccd) - seq_buf_printf(&s, ", "); + prt_printf(&s, ", "); =20 if (ccd) - seq_buf_printf(&s, "Indirect branch cache disabled"); + prt_printf(&s, "Indirect branch cache disabled"); =20 } else if (count_cache_flush_type !=3D BRANCH_CACHE_FLUSH_NONE) { - seq_buf_printf(&s, "Mitigation: Software count cache flush"); + prt_printf(&s, "Mitigation: Software count cache flush"); =20 if (count_cache_flush_type =3D=3D BRANCH_CACHE_FLUSH_HW) - seq_buf_printf(&s, " (hardware accelerated)"); + prt_printf(&s, " (hardware accelerated)"); =20 } else if (btb_flush_enabled) { - seq_buf_printf(&s, "Mitigation: Branch predictor state flush"); + prt_printf(&s, "Mitigation: Branch predictor state flush"); } else { - seq_buf_printf(&s, "Vulnerable"); + prt_printf(&s, "Vulnerable"); } =20 if (bcs || ccd || count_cache_flush_type !=3D BRANCH_CACHE_FLUSH_NONE) { if (link_stack_flush_type !=3D BRANCH_CACHE_FLUSH_NONE) - seq_buf_printf(&s, ", Software link stack flush"); + prt_printf(&s, ", Software link stack flush"); if (link_stack_flush_type =3D=3D BRANCH_CACHE_FLUSH_HW) - seq_buf_printf(&s, " (hardware accelerated)"); + prt_printf(&s, " (hardware accelerated)"); } =20 - seq_buf_printf(&s, "\n"); + prt_printf(&s, "\n"); =20 - return s.len; + return printbuf_written(&s); } =20 #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platf= orms/pseries/papr_scm.c index 39962c9055..317d4513db 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include =20 #include @@ -1145,7 +1145,7 @@ static ssize_t perf_stats_show(struct device *dev, { int index; ssize_t rc; - struct seq_buf s; + struct printbuf s =3D PRINTBUF_EXTERN(buf, PAGE_SIZE); struct papr_scm_perf_stat *stat; struct papr_scm_perf_stats *stats; struct nvdimm *dimm =3D to_nvdimm(dev); @@ -1168,18 +1168,17 @@ static ssize_t perf_stats_show(struct device *dev, * values. Since stat_id is essentially a char string of * 8 bytes, simply use the string format specifier to print it. */ - seq_buf_init(&s, buf, PAGE_SIZE); for (index =3D 0, stat =3D stats->scm_statistic; index < be32_to_cpu(stats->num_statistics); ++index, ++stat) { - seq_buf_printf(&s, "%.8s =3D 0x%016llX\n", - stat->stat_id, - be64_to_cpu(stat->stat_val)); + prt_printf(&s, "%.8s =3D 0x%016llX\n", + stat->stat_id, + be64_to_cpu(stat->stat_val)); } =20 free_stats: kfree(stats); - return rc ? rc : (ssize_t)seq_buf_used(&s); + return rc ?: printbuf_written(&s); } static DEVICE_ATTR_ADMIN_RO(perf_stats); =20 @@ -1188,7 +1187,7 @@ static ssize_t flags_show(struct device *dev, { struct nvdimm *dimm =3D to_nvdimm(dev); struct papr_scm_priv *p =3D nvdimm_provider_data(dimm); - struct seq_buf s; + struct printbuf s =3D PRINTBUF_EXTERN(buf, PAGE_SIZE); u64 health; int rc; =20 @@ -1199,29 +1198,28 @@ static ssize_t flags_show(struct device *dev, /* Copy health_bitmap locally, check masks & update out buffer */ health =3D READ_ONCE(p->health_bitmap); =20 - seq_buf_init(&s, buf, PAGE_SIZE); if (health & PAPR_PMEM_UNARMED_MASK) - seq_buf_printf(&s, "not_armed "); + prt_printf(&s, "not_armed "); =20 if (health & PAPR_PMEM_BAD_SHUTDOWN_MASK) - seq_buf_printf(&s, "flush_fail "); + prt_printf(&s, "flush_fail "); =20 if (health & PAPR_PMEM_BAD_RESTORE_MASK) - seq_buf_printf(&s, "restore_fail "); + prt_printf(&s, "restore_fail "); =20 if (health & PAPR_PMEM_ENCRYPTED) - seq_buf_printf(&s, "encrypted "); + prt_printf(&s, "encrypted "); =20 if (health & PAPR_PMEM_SMART_EVENT_MASK) - seq_buf_printf(&s, "smart_notify "); + prt_printf(&s, "smart_notify "); =20 if (health & PAPR_PMEM_SCRUBBED_AND_LOCKED) - seq_buf_printf(&s, "scrubbed locked "); + prt_printf(&s, "scrubbed locked "); =20 - if (seq_buf_used(&s)) - seq_buf_printf(&s, "\n"); + if (printbuf_written(&s)) + prt_printf(&s, "\n"); =20 - return seq_buf_used(&s); + return printbuf_written(&s); } DEVICE_ATTR_RO(flags); =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 948E8C43334 for ; Sat, 4 Jun 2022 19:33:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240844AbiFDTda (ORCPT ); Sat, 4 Jun 2022 15:33:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240732AbiFDTcG (ORCPT ); Sat, 4 Jun 2022 15:32:06 -0400 Received: from mail-qt1-x836.google.com (mail-qt1-x836.google.com [IPv6:2607:f8b0:4864:20::836]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D54ED4F9E6 for ; Sat, 4 Jun 2022 12:31:45 -0700 (PDT) Received: by mail-qt1-x836.google.com with SMTP id x7so7964192qta.6 for ; Sat, 04 Jun 2022 12:31:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=1KhCKnVaLX/kVfWuiSwPJQ3smEaMf/clD1IjnRzWHRY=; b=gMBTMfBQ8/cbt+ZlKXMwQ9hAKNl1Pbu4zN3nJBZqB4T+bsbNZCQpS1AOuL/2nTdvGy vW4m91ZR2m7ulMRaQsaT/opV3auOjxmygX0MJzr3eTrK+ZNTXqs4LMFCHGV6JevBBCc+ d973RH1IDE0vXB9dyCQCaTzT8i/2zX9WKEFVZAOXNKhrwbzyeRbbWDC2qcpoR00N6reG bmACbuX6ZNEScb7rMHqnHhykRe5VioXaE+DOIW80UWS8acmFQwju17ryghcThZEkY1m7 aY7XfpjEIje0B3IXlJwM4CWhrARsjra7au+adJK+6Unem6bJwPDeo6FTgLT5YOQY2Pxw Rgfg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1KhCKnVaLX/kVfWuiSwPJQ3smEaMf/clD1IjnRzWHRY=; b=WwNCNRpUb21WwzIja5wQCg5LJBrlZmvOWyPWdRhRsD/HZf2OS8ev0gxw/g82XLe+O6 2E3grIbI+C/7qa6bwV3itYn3JBM8nVWGr+NvmiqOicon6pNDfYHjmlIjV1lOueI7ab7Z LcoKhDyK0xoIwvdH1SIfV5WwnXdkoM0F5PJ4bB3M1wCrOCjb6NdnriyHDQlODQyLq/j2 gUwnl6Mi8hotezJHHeEIBeAVvYkeGTahbHyfyX09v4UN6REbzhjpcOaJl6VHvSmUtuYO iD5qw5qlkzb0RyguQAalxo2BL9ZkQN3uePNj91DvVrk9DtTn2dN+JLaXD9wbnyQYLTai VmUg== X-Gm-Message-State: AOAM533hjnlNt8IRf+IYl7k8w/ulUIlOi+Oe9tOMG49+VY1AnIIRi/SB ObrrDcurJL7HL26dpUT+gZX49G4Xyygs X-Google-Smtp-Source: ABdhPJxZ34TJtN2Hlrhiy+Lza2bHPLROoEr/P4uJ4PkL4qttBONUCc0sNV919ANU3/TyhcUjA7+E+g== X-Received: by 2002:a05:622a:58f:b0:2f9:16f3:95b0 with SMTP id c15-20020a05622a058f00b002f916f395b0mr12960409qtb.493.1654371092562; Sat, 04 Jun 2022 12:31:32 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:31 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org, x86@kernel.org Subject: [PATCH v3 28/33] x86/resctrl: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:37 -0400 Message-Id: <20220604193042.1674951-29-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts from seq_buf to printbuf. We're using printbuf in external buffer mode, so it's a direct conversion, aside from some trivial refactoring in cpu_show_meltdown() to make the code more consistent. Signed-off-by: Kent Overstreet Cc: x86@kernel.org --- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/r= esctrl/rdtgroup.c index 83f901e2c2..5b6720b6a4 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include #include @@ -51,7 +51,7 @@ static struct kernfs_node *kn_mongrp; /* Kernel fs node for "mon_data" directory under root */ static struct kernfs_node *kn_mondata; =20 -static struct seq_buf last_cmd_status; +static struct printbuf last_cmd_status; static char last_cmd_status_buf[512]; =20 struct dentry *debugfs_resctrl; @@ -59,13 +59,13 @@ struct dentry *debugfs_resctrl; void rdt_last_cmd_clear(void) { lockdep_assert_held(&rdtgroup_mutex); - seq_buf_clear(&last_cmd_status); + printbuf_reset(&last_cmd_status); } =20 void rdt_last_cmd_puts(const char *s) { lockdep_assert_held(&rdtgroup_mutex); - seq_buf_puts(&last_cmd_status, s); + prt_str(&last_cmd_status, s); } =20 void rdt_last_cmd_printf(const char *fmt, ...) @@ -74,7 +74,7 @@ void rdt_last_cmd_printf(const char *fmt, ...) =20 va_start(ap, fmt); lockdep_assert_held(&rdtgroup_mutex); - seq_buf_vprintf(&last_cmd_status, fmt, ap); + prt_vprintf(&last_cmd_status, fmt, ap); va_end(ap); } =20 @@ -833,7 +833,7 @@ static int rdt_last_cmd_status_show(struct kernfs_open_= file *of, int len; =20 mutex_lock(&rdtgroup_mutex); - len =3D seq_buf_used(&last_cmd_status); + len =3D printbuf_written(&last_cmd_status); if (len) seq_printf(seq, "%.*s", len, last_cmd_status_buf); else @@ -3248,8 +3248,8 @@ int __init rdtgroup_init(void) { int ret =3D 0; =20 - seq_buf_init(&last_cmd_status, last_cmd_status_buf, - sizeof(last_cmd_status_buf)); + last_cmd_status =3D PRINTBUF_EXTERN(last_cmd_status_buf, + sizeof(last_cmd_status_buf)); =20 ret =3D rdtgroup_setup_root(); if (ret) --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 51AF0C43334 for ; Sat, 4 Jun 2022 19:33:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240440AbiFDTdu (ORCPT ); Sat, 4 Jun 2022 15:33:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48262 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240820AbiFDTcK (ORCPT ); Sat, 4 Jun 2022 15:32:10 -0400 Received: from mail-qt1-x82c.google.com (mail-qt1-x82c.google.com [IPv6:2607:f8b0:4864:20::82c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA6054F9F4; Sat, 4 Jun 2022 12:31:47 -0700 (PDT) Received: by mail-qt1-x82c.google.com with SMTP id ew15so7962016qtb.2; Sat, 04 Jun 2022 12:31:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ODz0xlzoLBs6dcrjiKhQxftor+2WPn3OJscfp/YQp7I=; b=Y1gh/CBM8MBqiAEP68Q5r9yD6zqL6tJYGIr5D9uF5dstEz3rT9cWB5jTPy2ceJ+/yE /Wse3w0exUsBYU/sErKIIiBTJngsnyLQ7Rby9npQ/75Y4tCO61GWPW/n9m6RPbsQ+FDe FJD81AC79cosf/Nes1YaBEJpuh1KNqVFmf09JCLGL2ij6/oTGGWQrjkrQUPT8iDz5jMq r9GsVNdxI3/L1+mwv/v4mzz1R0LWeHP6ucLYnhEgUkKWJLEfCiU57L04JLfiTT2e6RcM YLETwXcEmVAFroE9C8EDq6oPMPxMX3g6WLN8sKSB1KgtJEydz2uZQfcW0t7BHEgSOm/2 aBAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ODz0xlzoLBs6dcrjiKhQxftor+2WPn3OJscfp/YQp7I=; b=6/nM3IvYZQoto7GFV84g+zkWxEbu+CCWWGN55PvIyA+OQ3V8tdGAwj+UwWZCtEDPpl Z4BfI/cPgTvnxYD2wzdl0m2pvO8gg8yuRuYOwr7izwyus+DHmE0VtjtgzthQGRXLY+Gu aC6PlVU9uQ2GyWvb9wWht8nxH78Dp/ArfnAEhKDSI4KEYVJsb9qJQeXtxeulYtMdxsyY NsZPHtIfqRUu6KE8y611mFCmLk0qM/Ocfw8ASKrSorgY8feBPh4S3PhBGD+tPYp1BCv7 c589J+6o8VZS+ML8rQZ90U/TOr1CzHpNfyNc4f4K8iDryCXGhsivq6xIZIx2yBZHoiHI aI/A== X-Gm-Message-State: AOAM533tdlQQaCclilnq4p7Lsmd1h4x9CPrZi0IMJaAe18s8aFISWBEG +acMyM8i6kpcPl1GCVbfWSDf2HesIUDS X-Google-Smtp-Source: ABdhPJyFb0Cvw3XxP8j+iWRgmOmbVwwa/PfAwP6p+g+HAZV+hvBphkJ+ocbbc+Khip88ap0Tf5af4g== X-Received: by 2002:ac8:570a:0:b0:304:e615:275f with SMTP id 10-20020ac8570a000000b00304e615275fmr3099117qtw.139.1654371094268; Sat, 04 Jun 2022 12:31:34 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:33 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org, linux-pci@vger.kernel.org Subject: [PATCH v3 29/33] PCI/P2PDMA: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:38 -0400 Message-Id: <20220604193042.1674951-30-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts from seq_buf to printbuf. We're using printbuf in external buffer mode, so it's a direct conversion, aside from some trivial refactoring in cpu_show_meltdown() to make the code more consistent. Signed-off-by: Kent Overstreet Cc: linux-pci@vger.kernel.org --- drivers/pci/p2pdma.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index 30b1df3c9d..c40d91912a 100644 --- a/drivers/pci/p2pdma.c +++ b/drivers/pci/p2pdma.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include =20 enum pci_p2pdma_map_type { @@ -281,12 +281,9 @@ static int pci_bridge_has_acs_redir(struct pci_dev *pd= ev) return 0; } =20 -static void seq_buf_print_bus_devfn(struct seq_buf *buf, struct pci_dev *p= dev) +static void prt_bus_devfn(struct printbuf *buf, struct pci_dev *pdev) { - if (!buf) - return; - - seq_buf_printf(buf, "%s;", pci_name(pdev)); + prt_printf(buf, "%s;", pci_name(pdev)); } =20 static bool cpu_supports_p2pdma(void) @@ -455,13 +452,11 @@ calc_map_type_and_dist(struct pci_dev *provider, stru= ct pci_dev *client, struct pci_dev *a =3D provider, *b =3D client, *bb; bool acs_redirects =3D false; struct pci_p2pdma *p2pdma; - struct seq_buf acs_list; int acs_cnt =3D 0; int dist_a =3D 0; int dist_b =3D 0; char buf[128]; - - seq_buf_init(&acs_list, buf, sizeof(buf)); + struct printbuf acs_list =3D PRINTBUF_EXTERN(buf, sizeof(buf)); =20 /* * Note, we don't need to take references to devices returned by @@ -472,7 +467,7 @@ calc_map_type_and_dist(struct pci_dev *provider, struct= pci_dev *client, dist_b =3D 0; =20 if (pci_bridge_has_acs_redir(a)) { - seq_buf_print_bus_devfn(&acs_list, a); + prt_bus_devfn(&acs_list, a); acs_cnt++; } =20 @@ -501,7 +496,7 @@ calc_map_type_and_dist(struct pci_dev *provider, struct= pci_dev *client, break; =20 if (pci_bridge_has_acs_redir(bb)) { - seq_buf_print_bus_devfn(&acs_list, bb); + prt_bus_devfn(&acs_list, bb); acs_cnt++; } =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2CB93C43334 for ; Sat, 4 Jun 2022 19:33:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240745AbiFDTdR (ORCPT ); Sat, 4 Jun 2022 15:33:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240377AbiFDTbu (ORCPT ); Sat, 4 Jun 2022 15:31:50 -0400 Received: from mail-qk1-x730.google.com (mail-qk1-x730.google.com [IPv6:2607:f8b0:4864:20::730]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 965755000D for ; Sat, 4 Jun 2022 12:31:36 -0700 (PDT) Received: by mail-qk1-x730.google.com with SMTP id 15so3180689qki.6 for ; Sat, 04 Jun 2022 12:31:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=fodx0Hm16VmVFm0PyMZVCAbEC8HUDt/O+iPo+rO/H6Q=; b=AwntglKrCvTp5pRtKOik5bb3woM0Nk0MJ0Kjn5Vp7MCHg/IlIypJb0KjiMOmwSIHqG qhxqF5CKLCvgHcNbUu/S8lpjo2Qs66Y3WAKi1JmkzdtdMjcao08GtJlExfYcDU6M1pm3 /Ft3mJREzkRm7RK6SgHx5P8SVOEA6rUieXDjBmnSK737USig/wBMc9pRUjcJtr0Y3eFs RD4IVuvPhoZyUkK1Lg+bxy+VNEFXYNNyh+BA5BpUPkOslmFxLEtc28HHoLpFlv2BK5B/ q6Ah6U/A/61zmvte8acSgboXWphCi8t9Q2PHM2gp15Nu89xXCTWH2/76nU2PP5MmYbBh bTLg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fodx0Hm16VmVFm0PyMZVCAbEC8HUDt/O+iPo+rO/H6Q=; b=G0KEJka5K6pqRLbo0zaGn8qIyP8DvKsrTb8mHa50OhmaJ/5DU1WLz7LxYM8bpV/6RQ TvpLoNYeo2Jc5pOiM2H6laU+l2fVJIXPkDCjxTy6z6PFE157E467zZ6asG+yCMNq0bJz sXw1UYg2kkLNezez2JOTDG5vHvD3pM5/qzdDu+AEHng7y2QZ2h0y8qZaqKoAiINbeA5F /ASZHEiFyiIkjE0x4THAva9xe1lXgPzRo1c/AqYkRunPu6KwdEG4ItGf6yQMoJUJOq/l gQtv6wauZkg+gqQ/HH7uEBnGrs3hOW5hFx1bsotPY5+Oo5AcpY6lK5uZh3eDdF4ZqFjs SjLA== X-Gm-Message-State: AOAM530cUDRMK31Ugd6sk0P7rYJyIJGKA6o8ighqANGQhaJee2DgEj8p Kf9NmIr2IDEBmOkD9VkRRkxLZoDC3X4y X-Google-Smtp-Source: ABdhPJwcXnrXZ4c9txaRW21Tgmh57lB+ZAiPrKlf5hfjnlkde0VEiG4ln96Zywr61OEI9ZXhs05i5A== X-Received: by 2002:a05:620a:28c6:b0:6a5:7f03:4377 with SMTP id l6-20020a05620a28c600b006a57f034377mr11298646qkp.118.1654371095865; Sat, 04 Jun 2022 12:31:35 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:34 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org, Ingo Molnar Subject: [PATCH v3 30/33] tracing: trace_events_synth: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:39 -0400 Message-Id: <20220604193042.1674951-31-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts from seq_buf to printbuf Signed-off-by: Kent Overstreet Cc: Steven Rostedt Cc: Ingo Molnar --- kernel/trace/trace_events_synth.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_= synth.c index 5e8c07aef0..627e0e45f0 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -5,13 +5,14 @@ * Copyright (C) 2015, 2020 Tom Zanussi */ =20 -#include #include -#include +#include #include +#include +#include +#include #include #include -#include #include =20 /* for gfp flag names */ @@ -611,7 +612,7 @@ static struct synth_field *parse_synth_field(int argc, = char **argv, const char *prefix =3D NULL, *field_type =3D argv[0], *field_name, *array; struct synth_field *field; int len, ret =3D -ENOMEM; - struct seq_buf s; + struct printbuf s; ssize_t size; =20 if (!strcmp(field_type, "unsigned")) { @@ -666,17 +667,15 @@ static struct synth_field *parse_synth_field(int argc= , char **argv, if (!field->type) goto free; =20 - seq_buf_init(&s, field->type, len); + s =3D PRINTBUF_EXTERN(field->type, len); if (prefix) - seq_buf_puts(&s, prefix); - seq_buf_puts(&s, field_type); + prt_str(&s, prefix); + prt_str(&s, field_type); if (array) - seq_buf_puts(&s, array); - if (WARN_ON_ONCE(!seq_buf_buffer_left(&s))) + prt_str(&s, array); + if (WARN_ON_ONCE(!printbuf_remaining(&s))) goto free; =20 - s.buffer[s.len] =3D '\0'; - size =3D synth_field_size(field->type); if (size < 0) { if (array) @@ -694,13 +693,12 @@ static struct synth_field *parse_synth_field(int argc= , char **argv, if (!type) goto free; =20 - seq_buf_init(&s, type, len); - seq_buf_puts(&s, "__data_loc "); - seq_buf_puts(&s, field->type); + s =3D PRINTBUF_EXTERN(type, len); + prt_str(&s, "__data_loc "); + prt_str(&s, field->type); =20 - if (WARN_ON_ONCE(!seq_buf_buffer_left(&s))) + if (WARN_ON_ONCE(!printbuf_remaining(&s))) goto free; - s.buffer[s.len] =3D '\0'; =20 kfree(field->type); field->type =3D type; --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE254C433EF for ; Sat, 4 Jun 2022 19:33:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241236AbiFDTdy (ORCPT ); Sat, 4 Jun 2022 15:33:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48194 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240534AbiFDTcN (ORCPT ); Sat, 4 Jun 2022 15:32:13 -0400 Received: from mail-qk1-x732.google.com (mail-qk1-x732.google.com [IPv6:2607:f8b0:4864:20::732]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C87854FC4B for ; Sat, 4 Jun 2022 12:31:48 -0700 (PDT) Received: by mail-qk1-x732.google.com with SMTP id x65so8383015qke.2 for ; Sat, 04 Jun 2022 12:31:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=6ifovngagXEclMNUOGWmhploQA6POSVt6ng3YeKVo7U=; b=PRjSJrgW3U/L87AYtaENt1TjxKHHUSfXQuEFlqHACigby6EqGnHAmSr2cqz2vdcD0s elc1r0BadJJj96s8r5YoNLdtKDs/W/C5p0crvIj++uEUPSJ+BLfNG0NDg5cfTNOkAq5X xA+iOOGuj+EX6MPqBifK56VWk9GOD2G4Jwl3mqIsg8xA8BbhHvdvTlvqciBDrqajSqMq iboHZoya/EDGPEXXrHOYduFRKyBklICt5cKY3RwEMiaodgi7LDuwwUawswjcQ+oG7fpD lfv+JmQbbwnQie+T/CucuRu22JqRzTo9zJjG9bG++/JB662llwNat+0YHZyHh1blPPGG 0oAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=6ifovngagXEclMNUOGWmhploQA6POSVt6ng3YeKVo7U=; b=5PBGIri/Ew+fCIkOoAiA+A5p4P5e4bMF66t8lw9hiSUUoXvjIgOkajisKf31tAPMEC zAN90MeSzDBlSy9ELd18OerC587NcSbXAp5U2oQGWJzrLbO6wn6iUU1oqfOWMxJ5ptKJ cSwKlTNZyTsg4EM18jhdIojHz+fcgteaQMsI+5X5puO8oU5TXRpTrl1qj08xjbwxY96c dvRzrB/YdumSvdFJfOIINl0J1wiIRJTUrvFuuHJEkZHdjk1U1D6grSCsbJ/mdwyLG5pz Uha8OUBi9UKhXil0M1yJformXxLchISK4sR05qGsTXS0kLREhHt+cX8lzPpOXZYZgvaf FHfw== X-Gm-Message-State: AOAM532ApEFDZ9gTswoJRcKDXjd4tZhVYNxVYzmG4W37PhTVbc6NgGMR MlRCmJBx2lZ5Fy6eLiCQBYMXFOzDpemE X-Google-Smtp-Source: ABdhPJwM2iDqN9G3t6ZQgs7+9spOd6m3aHpCPX0WrWpeQ6Smg+iy7nqX6/Y5/Mrw6WR5mTMXGI+Ecw== X-Received: by 2002:a05:620a:9:b0:6a6:b064:882e with SMTP id j9-20020a05620a000900b006a6b064882emr1726068qki.445.1654371097463; Sat, 04 Jun 2022 12:31:37 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:36 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 31/33] d_path: prt_path() Date: Sat, 4 Jun 2022 15:30:40 -0400 Message-Id: <20220604193042.1674951-32-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This implements a new printbuf version of d_path()/mangle_path(), which will replace the seq_buf version. Signed-off-by: Kent Overstreet --- fs/d_path.c | 34 ++++++++++++++++++++++++++++++++++ include/linux/dcache.h | 1 + 2 files changed, 35 insertions(+) diff --git a/fs/d_path.c b/fs/d_path.c index e4e0ebad1f..2aa8dfc1a7 100644 --- a/fs/d_path.c +++ b/fs/d_path.c @@ -294,6 +294,40 @@ char *d_path(const struct path *path, char *buf, int b= uflen) } EXPORT_SYMBOL(d_path); =20 +/** + * prt_path - format a path for output + * @out: printbuf to output to + * @path: path to write into the sequence buffer. + * @esc: set of characters to escape in the output + * + * Write a path name into the sequence buffer. + * + * Returns 0 on success, or error code from d_path + */ +int prt_path(struct printbuf *out, const struct path *path, const char *es= c) +{ + char *p, *buf; + size_t size; +again: + buf =3D out->buf + out->pos; + size =3D printbuf_remaining_size(out); + + p =3D d_path(path, buf, size); + if (IS_ERR(p)) { + printbuf_make_room(out, max(64, size * 2)); + if (printbuf_remaining_size(out) > size) + goto again; + + return PTR_ERR(p); + } + + p =3D mangle_path(buf, p, esc); + if (p) + out->pos +=3D p - buf; + return 0; +} +EXPORT_SYMBOL(prt_path); + /* * Helper function for dentry_operations.d_dname() members */ diff --git a/include/linux/dcache.h b/include/linux/dcache.h index f5bba51480..2181144f9f 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -293,6 +293,7 @@ extern char *d_absolute_path(const struct path *, char = *, int); extern char *d_path(const struct path *, char *, int); extern char *dentry_path_raw(const struct dentry *, char *, int); extern char *dentry_path(const struct dentry *, char *, int); +extern int prt_path(struct printbuf *, const struct path *, const char *); =20 /* Allocation counts.. */ =20 --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BCE1C433EF for ; Sat, 4 Jun 2022 19:33:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240649AbiFDTdn (ORCPT ); Sat, 4 Jun 2022 15:33:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240417AbiFDTb4 (ORCPT ); Sat, 4 Jun 2022 15:31:56 -0400 Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 889314EA35 for ; Sat, 4 Jun 2022 12:31:40 -0700 (PDT) Received: by mail-qk1-x72a.google.com with SMTP id k6so5324321qkf.4 for ; Sat, 04 Jun 2022 12:31:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=WhmR3C90uYEYjp+kde23224eyviGHODVOPVLy3FkAts=; b=ZMcUhMN7PneEKzI04lW2BjU5GOLJjh0roCOHZq1FgI2ryEjJbBv4eH25CQYvuncy5G epsEkLAC7F3uNcPghWYiFOnX3ZAGMwidDUT7vCC02DlnsdW3pZuLKEAsZ3SQGSPxUbbg yNZ9qmVC6D4oDAWUoxBP0y3qCqEoOxdLsGzXTo2UeF+oIp7F4LnL1Pr62cgoqNXLLxJ4 X+GmUq1CsaiF0OT2Fgc0st4pes091sNm21nT+GbenydBiVHbfS8/sDYLsCiVC4LjgTzL Eka+B1GiNQaGU5ETIrYj8676L5DkIOBbrBfdmWj0tT6aHBE2jDLAU4818ksUIvUTTVld F6xQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=WhmR3C90uYEYjp+kde23224eyviGHODVOPVLy3FkAts=; b=zar3+24oC/5LtuYMN45tQXvznpu4FiY/HwjLVaW1aOL9/TosWvUIp2wUqKanWR7JST reAeTApyF3pl6+PKdu1Gne4xtQ3YysHAzjzC/myTUKugaupXr43+GC6pbOePGI/3h/Zs G4n9G2rRrtjZzCbyMi54V9GC2ty9q0pTpkUq3LuHNfjQCk9FwOJejka1uxAct3w4yE4D 3J2AQKvgTrTkXaOEodmhtmI3hxb7jl3doH5KaYYayaYTda/nBQjORLRRDF95zBpLihlb iGjloQ8urebaqjLOfPGAh6L+MF/fx0jWkifMUAzPNufWqn+PK1yzTrMKs4M2RFZvkAgc iJ1Q== X-Gm-Message-State: AOAM5328560bNY/HFvPK6XFppBd4BlsPlL1T4uaK8dvF6qz6JCrnTLWb uVz/6ymuMn2Q3pGGTFs23XE9jSnpc+OB X-Google-Smtp-Source: ABdhPJxsxFuCB+s6AKSRP2OLKx9N+iHZroV70wD9thxWrlwupwWUDtvOePsgCQQtDodEN10w+csWYQ== X-Received: by 2002:a05:620a:2158:b0:6a6:191:7099 with SMTP id m24-20020a05620a215800b006a601917099mr10660604qkm.519.1654371099328; Sat, 04 Jun 2022 12:31:39 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:38 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 32/33] tracing: Convert to printbuf Date: Sat, 4 Jun 2022 15:30:41 -0400 Message-Id: <20220604193042.1674951-33-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" This converts the seq_bufs in dynevent_cmd and trace_seq to printbufs. - read_pos in seq_buf doesn't exist in printbuf, so is added to trace_seq - seq_buf_to_user doesn't have a printbuf equivalent, so is inlined into trace_seq_to_user - seq_buf_putmem_hex currently swabs bytes on little endian, hardcoded to 8 byte units. This patch switches it to prt_hex_bytes(), which does _not_ swab. Otherwise this is largely a direct conversion, with a few slight refactorings and cleanups. Signed-off-by: Kent Overstreet --- include/linux/trace_events.h | 2 +- include/linux/trace_seq.h | 14 ++-- kernel/trace/trace.c | 45 ++++------- kernel/trace/trace_dynevent.c | 34 ++++---- kernel/trace/trace_events_filter.c | 2 +- kernel/trace/trace_events_synth.c | 2 +- kernel/trace/trace_functions_graph.c | 6 +- kernel/trace/trace_kprobe.c | 2 +- kernel/trace/trace_seq.c | 111 ++++++++++++++------------- 9 files changed, 100 insertions(+), 118 deletions(-) diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h index e6e95a9f07..48471e32f8 100644 --- a/include/linux/trace_events.h +++ b/include/linux/trace_events.h @@ -496,7 +496,7 @@ struct dynevent_cmd; typedef int (*dynevent_create_fn_t)(struct dynevent_cmd *cmd); =20 struct dynevent_cmd { - struct seq_buf seq; + struct printbuf seq; const char *event_name; unsigned int n_fields; enum dynevent_type type; diff --git a/include/linux/trace_seq.h b/include/linux/trace_seq.h index 5a2c650d9e..0aeb9760cb 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -2,7 +2,7 @@ #ifndef _LINUX_TRACE_SEQ_H #define _LINUX_TRACE_SEQ_H =20 -#include +#include =20 #include =20 @@ -13,14 +13,16 @@ =20 struct trace_seq { char buffer[PAGE_SIZE]; - struct seq_buf seq; + struct printbuf seq; + unsigned readpos; int full; }; =20 static inline void trace_seq_init(struct trace_seq *s) { - seq_buf_init(&s->seq, s->buffer, PAGE_SIZE); + s->seq =3D PRINTBUF_EXTERN(s->buffer, PAGE_SIZE); + s->readpos =3D 0; s->full =3D 0; } =20 @@ -39,7 +41,7 @@ trace_seq_init(struct trace_seq *s) */ static inline int trace_seq_used(struct trace_seq *s) { - return seq_buf_used(&s->seq); + return printbuf_written(&s->seq); } =20 /** @@ -54,7 +56,7 @@ static inline int trace_seq_used(struct trace_seq *s) static inline char * trace_seq_buffer_ptr(struct trace_seq *s) { - return s->buffer + seq_buf_used(&s->seq); + return s->buffer + printbuf_written(&s->seq); } =20 /** @@ -66,7 +68,7 @@ trace_seq_buffer_ptr(struct trace_seq *s) */ static inline bool trace_seq_has_overflowed(struct trace_seq *s) { - return s->full || seq_buf_has_overflowed(&s->seq); + return s->full || printbuf_overflowed(&s->seq); } =20 /* diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index f4de111fa1..b815a914b5 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1670,15 +1670,15 @@ static ssize_t trace_seq_to_buffer(struct trace_seq= *s, void *buf, size_t cnt) { int len; =20 - if (trace_seq_used(s) <=3D s->seq.readpos) + if (trace_seq_used(s) <=3D s->readpos) return -EBUSY; =20 - len =3D trace_seq_used(s) - s->seq.readpos; + len =3D trace_seq_used(s) - s->readpos; if (cnt > len) cnt =3D len; - memcpy(buf, s->buffer + s->seq.readpos, cnt); + memcpy(buf, s->buffer + s->readpos, cnt); =20 - s->seq.readpos +=3D cnt; + s->readpos +=3D cnt; return cnt; } =20 @@ -3725,11 +3725,7 @@ static bool trace_safe_str(struct trace_iterator *it= er, const char *str, =20 static const char *show_buffer(struct trace_seq *s) { - struct seq_buf *seq =3D &s->seq; - - seq_buf_terminate(seq); - - return seq->buffer; + return printbuf_str(&s->seq); } =20 static DEFINE_STATIC_KEY_FALSE(trace_no_verify); @@ -6762,12 +6758,12 @@ tracing_read_pipe(struct file *filp, char __user *u= buf, trace_access_lock(iter->cpu_file); while (trace_find_next_entry_inc(iter) !=3D NULL) { enum print_line_t ret; - int save_len =3D iter->seq.seq.len; + int save_pos =3D iter->seq.seq.pos; =20 ret =3D print_trace_line(iter); if (ret =3D=3D TRACE_TYPE_PARTIAL_LINE) { /* don't print partial lines */ - iter->seq.seq.len =3D save_len; + iter->seq.seq.pos =3D save_pos; break; } if (ret !=3D TRACE_TYPE_NO_CONSUME) @@ -6789,7 +6785,7 @@ tracing_read_pipe(struct file *filp, char __user *ubu= f, =20 /* Now copy what we have to the user */ sret =3D trace_seq_to_user(&iter->seq, ubuf, cnt); - if (iter->seq.seq.readpos >=3D trace_seq_used(&iter->seq)) + if (iter->seq.readpos >=3D trace_seq_used(&iter->seq)) trace_seq_init(&iter->seq); =20 /* @@ -6815,16 +6811,15 @@ static size_t tracing_fill_pipe_page(size_t rem, struct trace_iterator *iter) { size_t count; - int save_len; int ret; =20 /* Seq buffer is page-sized, exactly what we need. */ for (;;) { - save_len =3D iter->seq.seq.len; + unsigned save_pos =3D iter->seq.seq.pos; ret =3D print_trace_line(iter); =20 if (trace_seq_has_overflowed(&iter->seq)) { - iter->seq.seq.len =3D save_len; + iter->seq.seq.pos =3D save_pos; break; } =20 @@ -6834,14 +6829,14 @@ tracing_fill_pipe_page(size_t rem, struct trace_ite= rator *iter) * anyway to be safe. */ if (ret =3D=3D TRACE_TYPE_PARTIAL_LINE) { - iter->seq.seq.len =3D save_len; + iter->seq.seq.pos =3D save_pos; break; } =20 - count =3D trace_seq_used(&iter->seq) - save_len; + count =3D trace_seq_used(&iter->seq) - save_pos; if (rem < count) { rem =3D 0; - iter->seq.seq.len =3D save_len; + iter->seq.seq.pos =3D save_pos; break; } =20 @@ -9817,20 +9812,8 @@ static struct notifier_block trace_die_notifier =3D { void trace_printk_seq(struct trace_seq *s) { - /* Probably should print a warning here. */ - if (s->seq.len >=3D TRACE_MAX_PRINT) - s->seq.len =3D TRACE_MAX_PRINT; - - /* - * More paranoid code. Although the buffer size is set to - * PAGE_SIZE, and TRACE_MAX_PRINT is 1000, this is just - * an extra layer of protection. - */ - if (WARN_ON_ONCE(s->seq.len >=3D s->seq.size)) - s->seq.len =3D s->seq.size - 1; - /* should be zero ended, but we are paranoid. */ - s->buffer[s->seq.len] =3D 0; + printbuf_nul_terminate(&s->seq); =20 printk(KERN_TRACE "%s", s->buffer); =20 diff --git a/kernel/trace/trace_dynevent.c b/kernel/trace/trace_dynevent.c index e34e8182ee..eabeeb97b5 100644 --- a/kernel/trace/trace_dynevent.c +++ b/kernel/trace/trace_dynevent.c @@ -295,21 +295,19 @@ int dynevent_arg_add(struct dynevent_cmd *cmd, struct dynevent_arg *arg, dynevent_check_arg_fn_t check_arg) { - int ret =3D 0; - if (check_arg) { - ret =3D check_arg(arg); + int ret =3D check_arg(arg); if (ret) return ret; } =20 - ret =3D seq_buf_printf(&cmd->seq, " %s%c", arg->str, arg->separator); - if (ret) { + prt_printf(&cmd->seq, " %s%c", arg->str, arg->separator); + if (printbuf_overflowed(&cmd->seq)) { pr_err("String is too long: %s%c\n", arg->str, arg->separator); return -E2BIG; } =20 - return ret; + return 0; } =20 /** @@ -340,25 +338,23 @@ int dynevent_arg_pair_add(struct dynevent_cmd *cmd, struct dynevent_arg_pair *arg_pair, dynevent_check_arg_fn_t check_arg) { - int ret =3D 0; - if (check_arg) { - ret =3D check_arg(arg_pair); + int ret =3D check_arg(arg_pair); if (ret) return ret; } =20 - ret =3D seq_buf_printf(&cmd->seq, " %s%c%s%c", arg_pair->lhs, - arg_pair->operator, arg_pair->rhs, - arg_pair->separator); - if (ret) { + prt_printf(&cmd->seq, " %s%c%s%c", arg_pair->lhs, + arg_pair->operator, arg_pair->rhs, + arg_pair->separator); + if (printbuf_overflowed(&cmd->seq)) { pr_err("field string is too long: %s%c%s%c\n", arg_pair->lhs, arg_pair->operator, arg_pair->rhs, arg_pair->separator); return -E2BIG; } =20 - return ret; + return 0; } =20 /** @@ -373,15 +369,13 @@ int dynevent_arg_pair_add(struct dynevent_cmd *cmd, */ int dynevent_str_add(struct dynevent_cmd *cmd, const char *str) { - int ret =3D 0; - - ret =3D seq_buf_puts(&cmd->seq, str); - if (ret) { + prt_str(&cmd->seq, str); + if (printbuf_overflowed(&cmd->seq)) { pr_err("String is too long: %s\n", str); return -E2BIG; } =20 - return ret; + return 0; } =20 /** @@ -410,7 +404,7 @@ void dynevent_cmd_init(struct dynevent_cmd *cmd, char *= buf, int maxlen, { memset(cmd, '\0', sizeof(*cmd)); =20 - seq_buf_init(&cmd->seq, buf, maxlen); + cmd->seq =3D PRINTBUF_EXTERN(buf, maxlen); cmd->type =3D type; cmd->run_command =3D run_command; } diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events= _filter.c index b458a9afa2..70cfd12410 100644 --- a/kernel/trace/trace_events_filter.c +++ b/kernel/trace/trace_events_filter.c @@ -1059,7 +1059,7 @@ static void append_filter_err(struct trace_array *tr, FILT_ERR_ERRNO, 0); } trace_seq_putc(s, 0); - buf =3D kmemdup_nul(s->buffer, s->seq.len, GFP_KERNEL); + buf =3D kstrdup(printbuf_str(&s->seq), GFP_KERNEL); if (buf) { kfree(filter->filter_string); filter->filter_string =3D buf; diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_= synth.c index 627e0e45f0..ddb2a2737b 100644 --- a/kernel/trace/trace_events_synth.c +++ b/kernel/trace/trace_events_synth.c @@ -1512,7 +1512,7 @@ static int synth_event_run_command(struct dynevent_cm= d *cmd) struct synth_event *se; int ret; =20 - ret =3D create_or_delete_synth_event(cmd->seq.buffer); + ret =3D create_or_delete_synth_event(cmd->seq.buf); if (ret) return ret; =20 diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_func= tions_graph.c index 203204cadf..9f270fdde9 100644 --- a/kernel/trace/trace_functions_graph.c +++ b/kernel/trace/trace_functions_graph.c @@ -1022,9 +1022,9 @@ print_graph_comment(struct trace_seq *s, struct trace= _entry *ent, goto out; =20 /* Strip ending newline */ - if (s->buffer[s->seq.len - 1] =3D=3D '\n') { - s->buffer[s->seq.len - 1] =3D '\0'; - s->seq.len--; + if (s->buffer[s->seq.pos - 1] =3D=3D '\n') { + s->buffer[s->seq.pos - 1] =3D '\0'; + s->seq.pos--; } =20 trace_seq_puts(s, " */\n"); diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index 47cebef785..b97a912eed 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c @@ -915,7 +915,7 @@ static int create_or_delete_trace_kprobe(const char *ra= w_command) =20 static int trace_kprobe_run_command(struct dynevent_cmd *cmd) { - return create_or_delete_trace_kprobe(cmd->seq.buffer); + return create_or_delete_trace_kprobe(printbuf_str(&cmd->seq)); } =20 /** diff --git a/kernel/trace/trace_seq.c b/kernel/trace/trace_seq.c index 9c90b3a7dc..240eaad3e5 100644 --- a/kernel/trace/trace_seq.c +++ b/kernel/trace/trace_seq.c @@ -25,11 +25,9 @@ */ #include #include +#include #include =20 -/* How much buffer is left on the trace_seq? */ -#define TRACE_SEQ_BUF_LEFT(s) seq_buf_buffer_left(&(s)->seq) - /* * trace_seq should work with being initialized with 0s. */ @@ -54,7 +52,7 @@ int trace_print_seq(struct seq_file *m, struct trace_seq = *s) =20 __trace_seq_init(s); =20 - ret =3D seq_buf_print_seq(m, &s->seq); + ret =3D seq_write(m, s->seq.buf, printbuf_written(&s->seq)); =20 /* * Only reset this buffer if we successfully wrote to the @@ -80,7 +78,7 @@ int trace_print_seq(struct seq_file *m, struct trace_seq = *s) */ void trace_seq_printf(struct trace_seq *s, const char *fmt, ...) { - unsigned int save_len =3D s->seq.len; + unsigned int save_pos =3D s->seq.pos; va_list ap; =20 if (s->full) @@ -89,12 +87,12 @@ void trace_seq_printf(struct trace_seq *s, const char *= fmt, ...) __trace_seq_init(s); =20 va_start(ap, fmt); - seq_buf_vprintf(&s->seq, fmt, ap); + prt_vprintf(&s->seq, fmt, ap); va_end(ap); =20 /* If we can't write it all, don't bother writing anything */ - if (unlikely(seq_buf_has_overflowed(&s->seq))) { - s->seq.len =3D save_len; + if (unlikely(printbuf_overflowed(&s->seq))) { + s->seq.pos =3D save_pos; s->full =3D 1; } } @@ -111,17 +109,17 @@ EXPORT_SYMBOL_GPL(trace_seq_printf); void trace_seq_bitmask(struct trace_seq *s, const unsigned long *maskp, int nmaskbits) { - unsigned int save_len =3D s->seq.len; + unsigned int save_pos =3D s->seq.pos; =20 if (s->full) return; =20 __trace_seq_init(s); =20 - seq_buf_printf(&s->seq, "%*pb", nmaskbits, maskp); + prt_printf(&s->seq, "%*pb", nmaskbits, maskp); =20 - if (unlikely(seq_buf_has_overflowed(&s->seq))) { - s->seq.len =3D save_len; + if (unlikely(printbuf_overflowed(&s->seq))) { + s->seq.pos =3D save_pos; s->full =3D 1; } } @@ -140,18 +138,18 @@ EXPORT_SYMBOL_GPL(trace_seq_bitmask); */ void trace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) { - unsigned int save_len =3D s->seq.len; + unsigned int save_pos =3D s->seq.pos; =20 if (s->full) return; =20 __trace_seq_init(s); =20 - seq_buf_vprintf(&s->seq, fmt, args); + prt_vprintf(&s->seq, fmt, args); =20 /* If we can't write it all, don't bother writing anything */ - if (unlikely(seq_buf_has_overflowed(&s->seq))) { - s->seq.len =3D save_len; + if (unlikely(printbuf_overflowed(&s->seq))) { + s->seq.pos =3D save_pos; s->full =3D 1; } } @@ -174,18 +172,18 @@ EXPORT_SYMBOL_GPL(trace_seq_vprintf); */ void trace_seq_bprintf(struct trace_seq *s, const char *fmt, const u32 *bi= nary) { - unsigned int save_len =3D s->seq.len; + unsigned int save_pos =3D s->seq.pos; =20 if (s->full) return; =20 __trace_seq_init(s); =20 - seq_buf_bprintf(&s->seq, fmt, binary); + prt_bstrprintf(&s->seq, fmt, binary); =20 /* If we can't write it all, don't bother writing anything */ - if (unlikely(seq_buf_has_overflowed(&s->seq))) { - s->seq.len =3D save_len; + if (unlikely(!printbuf_overflowed(&s->seq))) { + s->seq.pos =3D save_pos; s->full =3D 1; return; } @@ -211,12 +209,12 @@ void trace_seq_puts(struct trace_seq *s, const char *= str) =20 __trace_seq_init(s); =20 - if (len > TRACE_SEQ_BUF_LEFT(s)) { + if (len > printbuf_remaining(&s->seq)) { s->full =3D 1; return; } =20 - seq_buf_putmem(&s->seq, str, len); + prt_bytes(&s->seq, str, len); } EXPORT_SYMBOL_GPL(trace_seq_puts); =20 @@ -237,12 +235,12 @@ void trace_seq_putc(struct trace_seq *s, unsigned cha= r c) =20 __trace_seq_init(s); =20 - if (TRACE_SEQ_BUF_LEFT(s) < 1) { + if (!printbuf_remaining(&s->seq)) { s->full =3D 1; return; } =20 - seq_buf_putc(&s->seq, c); + prt_char(&s->seq, c); } EXPORT_SYMBOL_GPL(trace_seq_putc); =20 @@ -263,12 +261,12 @@ void trace_seq_putmem(struct trace_seq *s, const void= *mem, unsigned int len) =20 __trace_seq_init(s); =20 - if (len > TRACE_SEQ_BUF_LEFT(s)) { + if (len > printbuf_remaining(&s->seq)) { s->full =3D 1; return; } =20 - seq_buf_putmem(&s->seq, mem, len); + prt_bytes(&s->seq, mem, len); } EXPORT_SYMBOL_GPL(trace_seq_putmem); =20 @@ -285,24 +283,17 @@ EXPORT_SYMBOL_GPL(trace_seq_putmem); void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, unsigned int len) { - unsigned int save_len =3D s->seq.len; + unsigned int save_pos =3D s->seq.pos; =20 if (s->full) return; =20 __trace_seq_init(s); =20 - /* Each byte is represented by two chars */ - if (len * 2 > TRACE_SEQ_BUF_LEFT(s)) { - s->full =3D 1; - return; - } + prt_hex_bytes(out, mem, len, 8, ' '); =20 - /* The added spaces can still cause an overflow */ - seq_buf_putmem_hex(&s->seq, mem, len); - - if (unlikely(seq_buf_has_overflowed(&s->seq))) { - s->seq.len =3D save_len; + if (unlikely(printbuf_overflowed(&s->seq))) { + s->seq.pos =3D save_pos; s->full =3D 1; return; } @@ -323,22 +314,22 @@ EXPORT_SYMBOL_GPL(trace_seq_putmem_hex); */ int trace_seq_path(struct trace_seq *s, const struct path *path) { - unsigned int save_len =3D s->seq.len; + unsigned int save_pos =3D s->seq.pos; =20 if (s->full) return 0; =20 __trace_seq_init(s); =20 - if (TRACE_SEQ_BUF_LEFT(s) < 1) { + if (printbuf_remaining(&s->seq) < 1) { s->full =3D 1; return 0; } =20 - seq_buf_path(&s->seq, path, "\n"); + prt_path(&s->seq, path, "\n"); =20 - if (unlikely(seq_buf_has_overflowed(&s->seq))) { - s->seq.len =3D save_len; + if (unlikely(printbuf_overflowed(&s->seq))) { + s->seq.pos =3D save_pos; s->full =3D 1; return 0; } @@ -369,8 +360,25 @@ EXPORT_SYMBOL_GPL(trace_seq_path); */ int trace_seq_to_user(struct trace_seq *s, char __user *ubuf, int cnt) { + int ret, len; + __trace_seq_init(s); - return seq_buf_to_user(&s->seq, ubuf, cnt); + + len =3D printbuf_written(&s->seq); + if (len <=3D s->readpos) + return -EBUSY; + + len -=3D s->readpos; + if (cnt > len) + cnt =3D len; + ret =3D copy_to_user(ubuf, s->buffer + s->readpos, cnt); + if (ret =3D=3D cnt) + return -EFAULT; + + cnt -=3D ret; + + s->readpos +=3D cnt; + return cnt; } EXPORT_SYMBOL_GPL(trace_seq_to_user); =20 @@ -378,24 +386,19 @@ int trace_seq_hex_dump(struct trace_seq *s, const cha= r *prefix_str, int prefix_type, int rowsize, int groupsize, const void *buf, size_t len, bool ascii) { - unsigned int save_len =3D s->seq.len; + unsigned int save_pos =3D s->seq.pos; =20 if (s->full) return 0; =20 __trace_seq_init(s); =20 - if (TRACE_SEQ_BUF_LEFT(s) < 1) { - s->full =3D 1; - return 0; - } - - seq_buf_hex_dump(&(s->seq), prefix_str, - prefix_type, rowsize, groupsize, - buf, len, ascii); + prt_hex_dump(&s->seq, buf, len, + prefix_str, prefix_type, + rowsize, groupsize, ascii); =20 - if (unlikely(seq_buf_has_overflowed(&s->seq))) { - s->seq.len =3D save_len; + if (unlikely(printbuf_overflowed(&s->seq))) { + s->seq.pos =3D save_pos; s->full =3D 1; return 0; } --=20 2.36.0 From nobody Tue Apr 28 06:32:47 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D491FC43334 for ; Sat, 4 Jun 2022 19:34:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241275AbiFDTeA (ORCPT ); Sat, 4 Jun 2022 15:34:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48474 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S241023AbiFDTc3 (ORCPT ); Sat, 4 Jun 2022 15:32:29 -0400 Received: from mail-qt1-x831.google.com (mail-qt1-x831.google.com [IPv6:2607:f8b0:4864:20::831]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4FCEB13FB4 for ; Sat, 4 Jun 2022 12:31:51 -0700 (PDT) Received: by mail-qt1-x831.google.com with SMTP id v1so7965051qtx.5 for ; Sat, 04 Jun 2022 12:31:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=YAjutGgW/wYFVhGnoiZ1fsOqhShcWq0PsdTZENR4l0g=; b=lew23pYoV7S4Tf6ic1SyvsN9LWeifabmlD1EXAsu6b0IbJ+aW9lqa2UcS3j1bmt7mS 3AokgnpOzGRDuAUoQMSBnaDINnv6P6e2fOuDIMx/yL3jHpWeCYglYKjdiGbBOwZ+LaHM i/qzmvMWjKK7h+sSuz5Kmt1X+m3hx2yzGHpB+Z5EqLAfx3Cvk+SSxs+1hf7TQnjmYnNZ TlLHjjT72/C5Jphi+lOsu+GovXqFjEWCQAHTiYJTvI0CxFlPczDO9HRGb8Jis7hQAKLm cdcmU174jgd42gCm3/+lkauTpIHnJgaPU6fmQ7zjM/VOiJF4Vlf5MjVIFGOKndRJFxNy 7LKA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=YAjutGgW/wYFVhGnoiZ1fsOqhShcWq0PsdTZENR4l0g=; b=Zdvjw0OytTxLBg2wFNYMTV3i8Lv/SZzl2VghFXZJXsubKon3i+5UAyK5MXSeLEpZWI k1kdssePNTu6ebcDvjHi49Xx9rAOgdjMl6AmSEW5h88Rta44rYBGKkF4Qb3mOyxl0BFM NYVRSbjhHGH6pgt4Rm9DDZex2Dq23aghZKaJDxKrd+c9AoDxh05XACshsrFFu1bCnZZo DAr6bFV0Zh8a+LxywiYcMbeMhUv8gsghoLdnI0Zxm7xcXbBq5TUNpi4BsCzIWRTQMNKu y0KobzKJu/su9L5omEKMwcuThUJ328oqsmzTFoZM+z8qPvB/LTrtJWbydUzGqB4FW739 57eQ== X-Gm-Message-State: AOAM532QpyVoev0Hr0EMU+O7TjkzFq+ILFyKyPN+ymMBbX1Ufz/zglOq Wl8PWbHlvAxZyCehkqOaWP6YlP3jGKCe X-Google-Smtp-Source: ABdhPJyCpfybNHSstjMUxf6dvDOcB9WIIs+/53XgUVaMaCNS2AiQtse4apCAiDW7UL9SQ75Y5Ub3jQ== X-Received: by 2002:ac8:7f08:0:b0:304:b3cb:8f5d with SMTP id f8-20020ac87f08000000b00304b3cb8f5dmr12555125qtk.532.1654371101154; Sat, 04 Jun 2022 12:31:41 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id o17-20020ac84291000000b00304defdb1b3sm3537426qtl.85.2022.06.04.12.31.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 04 Jun 2022 12:31:39 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org Cc: Kent Overstreet , pmladek@suse.com, rostedt@goodmis.org Subject: [PATCH v3 33/33] Delete seq_buf Date: Sat, 4 Jun 2022 15:30:42 -0400 Message-Id: <20220604193042.1674951-34-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.0 In-Reply-To: <20220604193042.1674951-1-kent.overstreet@gmail.com> References: <20220604193042.1674951-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" No longer has any users, so delete it. Signed-off-by: Kent Overstreet --- include/linux/seq_buf.h | 162 ---------------- lib/Makefile | 2 +- lib/seq_buf.c | 397 ---------------------------------------- 3 files changed, 1 insertion(+), 560 deletions(-) delete mode 100644 include/linux/seq_buf.h delete mode 100644 lib/seq_buf.c diff --git a/include/linux/seq_buf.h b/include/linux/seq_buf.h deleted file mode 100644 index 5b31c51479..0000000000 --- a/include/linux/seq_buf.h +++ /dev/null @@ -1,162 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _LINUX_SEQ_BUF_H -#define _LINUX_SEQ_BUF_H - -#include - -/* - * Trace sequences are used to allow a function to call several other func= tions - * to create a string of data to use. - */ - -/** - * seq_buf - seq buffer structure - * @buffer: pointer to the buffer - * @size: size of the buffer - * @len: the amount of data inside the buffer - * @readpos: The next position to read in the buffer. - */ -struct seq_buf { - char *buffer; - size_t size; - size_t len; - loff_t readpos; -}; - -static inline void seq_buf_clear(struct seq_buf *s) -{ - s->len =3D 0; - s->readpos =3D 0; -} - -static inline void -seq_buf_init(struct seq_buf *s, char *buf, unsigned int size) -{ - s->buffer =3D buf; - s->size =3D size; - seq_buf_clear(s); -} - -/* - * seq_buf have a buffer that might overflow. When this happens - * the len and size are set to be equal. - */ -static inline bool -seq_buf_has_overflowed(struct seq_buf *s) -{ - return s->len > s->size; -} - -static inline void -seq_buf_set_overflow(struct seq_buf *s) -{ - s->len =3D s->size + 1; -} - -/* - * How much buffer is left on the seq_buf? - */ -static inline unsigned int -seq_buf_buffer_left(struct seq_buf *s) -{ - if (seq_buf_has_overflowed(s)) - return 0; - - return s->size - s->len; -} - -/* How much buffer was written? */ -static inline unsigned int seq_buf_used(struct seq_buf *s) -{ - return min(s->len, s->size); -} - -/** - * seq_buf_terminate - Make sure buffer is nul terminated - * @s: the seq_buf descriptor to terminate. - * - * This makes sure that the buffer in @s is nul terminated and - * safe to read as a string. - * - * Note, if this is called when the buffer has overflowed, then - * the last byte of the buffer is zeroed, and the len will still - * point passed it. - * - * After this function is called, s->buffer is safe to use - * in string operations. - */ -static inline void seq_buf_terminate(struct seq_buf *s) -{ - if (WARN_ON(s->size =3D=3D 0)) - return; - - if (seq_buf_buffer_left(s)) - s->buffer[s->len] =3D 0; - else - s->buffer[s->size - 1] =3D 0; -} - -/** - * seq_buf_get_buf - get buffer to write arbitrary data to - * @s: the seq_buf handle - * @bufp: the beginning of the buffer is stored here - * - * Return the number of bytes available in the buffer, or zero if - * there's no space. - */ -static inline size_t seq_buf_get_buf(struct seq_buf *s, char **bufp) -{ - WARN_ON(s->len > s->size + 1); - - if (s->len < s->size) { - *bufp =3D s->buffer + s->len; - return s->size - s->len; - } - - *bufp =3D NULL; - return 0; -} - -/** - * seq_buf_commit - commit data to the buffer - * @s: the seq_buf handle - * @num: the number of bytes to commit - * - * Commit @num bytes of data written to a buffer previously acquired - * by seq_buf_get. To signal an error condition, or that the data - * didn't fit in the available space, pass a negative @num value. - */ -static inline void seq_buf_commit(struct seq_buf *s, int num) -{ - if (num < 0) { - seq_buf_set_overflow(s); - } else { - /* num must be negative on overflow */ - BUG_ON(s->len + num > s->size); - s->len +=3D num; - } -} - -extern __printf(2, 3) -int seq_buf_printf(struct seq_buf *s, const char *fmt, ...); -extern __printf(2, 0) -int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args); -extern int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s); -extern int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, - int cnt); -extern int seq_buf_puts(struct seq_buf *s, const char *str); -extern int seq_buf_putc(struct seq_buf *s, unsigned char c); -extern int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int= len); -extern int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, - unsigned int len); -extern int seq_buf_path(struct seq_buf *s, const struct path *path, const = char *esc); -extern int seq_buf_hex_dump(struct seq_buf *s, const char *prefix_str, - int prefix_type, int rowsize, int groupsize, - const void *buf, size_t len, bool ascii); - -#ifdef CONFIG_BINARY_PRINTF -extern int -seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary); -#endif - -#endif /* _LINUX_SEQ_BUF_H */ diff --git a/lib/Makefile b/lib/Makefile index b520024852..f8ad89dc9a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -32,7 +32,7 @@ lib-y :=3D ctype.o string.o vsprintf.o cmdline.o \ idr.o extable.o sha1.o irq_regs.o argv_split.o \ flex_proportions.o ratelimit.o show_mem.o \ is_single_threaded.o plist.o decompress.o kobject_uevent.o \ - earlycpio.o seq_buf.o siphash.o dec_and_lock.o \ + earlycpio.o siphash.o dec_and_lock.o \ nmi_backtrace.o nodemask.o win_minmax.o memcat_p.o \ buildid.o printbuf.o pretty-printers.o =20 diff --git a/lib/seq_buf.c b/lib/seq_buf.c deleted file mode 100644 index 0a68f7aa85..0000000000 --- a/lib/seq_buf.c +++ /dev/null @@ -1,397 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * seq_buf.c - * - * Copyright (C) 2014 Red Hat Inc, Steven Rostedt - * - * The seq_buf is a handy tool that allows you to pass a descriptor around - * to a buffer that other functions can write to. It is similar to the - * seq_file functionality but has some differences. - * - * To use it, the seq_buf must be initialized with seq_buf_init(). - * This will set up the counters within the descriptor. You can call - * seq_buf_init() more than once to reset the seq_buf to start - * from scratch. - */ -#include -#include -#include - -/** - * seq_buf_can_fit - can the new data fit in the current buffer? - * @s: the seq_buf descriptor - * @len: The length to see if it can fit in the current buffer - * - * Returns true if there's enough unused space in the seq_buf buffer - * to fit the amount of new data according to @len. - */ -static bool seq_buf_can_fit(struct seq_buf *s, size_t len) -{ - return s->len + len <=3D s->size; -} - -/** - * seq_buf_print_seq - move the contents of seq_buf into a seq_file - * @m: the seq_file descriptor that is the destination - * @s: the seq_buf descriptor that is the source. - * - * Returns zero on success, non zero otherwise - */ -int seq_buf_print_seq(struct seq_file *m, struct seq_buf *s) -{ - unsigned int len =3D seq_buf_used(s); - - return seq_write(m, s->buffer, len); -} - -/** - * seq_buf_vprintf - sequence printing of information. - * @s: seq_buf descriptor - * @fmt: printf format string - * @args: va_list of arguments from a printf() type function - * - * Writes a vnprintf() format into the sequencce buffer. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_vprintf(struct seq_buf *s, const char *fmt, va_list args) -{ - int len; - - WARN_ON(s->size =3D=3D 0); - - if (s->len < s->size) { - len =3D vsnprintf(s->buffer + s->len, s->size - s->len, fmt, args); - if (s->len + len < s->size) { - s->len +=3D len; - return 0; - } - } - seq_buf_set_overflow(s); - return -1; -} - -/** - * seq_buf_printf - sequence printing of information - * @s: seq_buf descriptor - * @fmt: printf format string - * - * Writes a printf() format into the sequence buffer. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_printf(struct seq_buf *s, const char *fmt, ...) -{ - va_list ap; - int ret; - - va_start(ap, fmt); - ret =3D seq_buf_vprintf(s, fmt, ap); - va_end(ap); - - return ret; -} -EXPORT_SYMBOL_GPL(seq_buf_printf); - -#ifdef CONFIG_BINARY_PRINTF -/** - * seq_buf_bprintf - Write the printf string from binary arguments - * @s: seq_buf descriptor - * @fmt: The format string for the @binary arguments - * @binary: The binary arguments for @fmt. - * - * When recording in a fast path, a printf may be recorded with just - * saving the format and the arguments as they were passed to the - * function, instead of wasting cycles converting the arguments into - * ASCII characters. Instead, the arguments are saved in a 32 bit - * word array that is defined by the format string constraints. - * - * This function will take the format and the binary array and finish - * the conversion into the ASCII string within the buffer. - * - * Returns zero on success, -1 on overflow. - */ -int seq_buf_bprintf(struct seq_buf *s, const char *fmt, const u32 *binary) -{ - unsigned int len =3D seq_buf_buffer_left(s); - int ret; - - WARN_ON(s->size =3D=3D 0); - - if (s->len < s->size) { - ret =3D bstr_printf(s->buffer + s->len, len, fmt, binary); - if (s->len + ret < s->size) { - s->len +=3D ret; - return 0; - } - } - seq_buf_set_overflow(s); - return -1; -} -#endif /* CONFIG_BINARY_PRINTF */ - -/** - * seq_buf_puts - sequence printing of simple string - * @s: seq_buf descriptor - * @str: simple string to record - * - * Copy a simple string into the sequence buffer. - * - * Returns zero on success, -1 on overflow - */ -int seq_buf_puts(struct seq_buf *s, const char *str) -{ - size_t len =3D strlen(str); - - WARN_ON(s->size =3D=3D 0); - - /* Add 1 to len for the trailing null byte which must be there */ - len +=3D 1; - - if (seq_buf_can_fit(s, len)) { - memcpy(s->buffer + s->len, str, len); - /* Don't count the trailing null byte against the capacity */ - s->len +=3D len - 1; - return 0; - } - seq_buf_set_overflow(s); - return -1; -} - -/** - * seq_buf_putc - sequence printing of simple character - * @s: seq_buf descriptor - * @c: simple character to record - * - * Copy a single character into the sequence buffer. - * - * Returns zero on success, -1 on overflow - */ -int seq_buf_putc(struct seq_buf *s, unsigned char c) -{ - WARN_ON(s->size =3D=3D 0); - - if (seq_buf_can_fit(s, 1)) { - s->buffer[s->len++] =3D c; - return 0; - } - seq_buf_set_overflow(s); - return -1; -} - -/** - * seq_buf_putmem - write raw data into the sequenc buffer - * @s: seq_buf descriptor - * @mem: The raw memory to copy into the buffer - * @len: The length of the raw memory to copy (in bytes) - * - * There may be cases where raw memory needs to be written into the - * buffer and a strcpy() would not work. Using this function allows - * for such cases. - * - * Returns zero on success, -1 on overflow - */ -int seq_buf_putmem(struct seq_buf *s, const void *mem, unsigned int len) -{ - WARN_ON(s->size =3D=3D 0); - - if (seq_buf_can_fit(s, len)) { - memcpy(s->buffer + s->len, mem, len); - s->len +=3D len; - return 0; - } - seq_buf_set_overflow(s); - return -1; -} - -#define MAX_MEMHEX_BYTES 8U -#define HEX_CHARS (MAX_MEMHEX_BYTES*2 + 1) - -/** - * seq_buf_putmem_hex - write raw memory into the buffer in ASCII hex - * @s: seq_buf descriptor - * @mem: The raw memory to write its hex ASCII representation of - * @len: The length of the raw memory to copy (in bytes) - * - * This is similar to seq_buf_putmem() except instead of just copying the - * raw memory into the buffer it writes its ASCII representation of it - * in hex characters. - * - * Returns zero on success, -1 on overflow - */ -int seq_buf_putmem_hex(struct seq_buf *s, const void *mem, - unsigned int len) -{ - unsigned char hex[HEX_CHARS]; - const unsigned char *data =3D mem; - unsigned int start_len; - int i, j; - - WARN_ON(s->size =3D=3D 0); - - BUILD_BUG_ON(MAX_MEMHEX_BYTES * 2 >=3D HEX_CHARS); - - while (len) { - start_len =3D min(len, MAX_MEMHEX_BYTES); -#ifdef __BIG_ENDIAN - for (i =3D 0, j =3D 0; i < start_len; i++) { -#else - for (i =3D start_len-1, j =3D 0; i >=3D 0; i--) { -#endif - hex[j++] =3D hex_asc_hi(data[i]); - hex[j++] =3D hex_asc_lo(data[i]); - } - if (WARN_ON_ONCE(j =3D=3D 0 || j/2 > len)) - break; - - /* j increments twice per loop */ - hex[j++] =3D ' '; - - seq_buf_putmem(s, hex, j); - if (seq_buf_has_overflowed(s)) - return -1; - - len -=3D start_len; - data +=3D start_len; - } - return 0; -} - -/** - * seq_buf_path - copy a path into the sequence buffer - * @s: seq_buf descriptor - * @path: path to write into the sequence buffer. - * @esc: set of characters to escape in the output - * - * Write a path name into the sequence buffer. - * - * Returns the number of written bytes on success, -1 on overflow - */ -int seq_buf_path(struct seq_buf *s, const struct path *path, const char *e= sc) -{ - char *buf; - size_t size =3D seq_buf_get_buf(s, &buf); - int res =3D -1; - - WARN_ON(s->size =3D=3D 0); - - if (size) { - char *p =3D d_path(path, buf, size); - if (!IS_ERR(p)) { - char *end =3D mangle_path(buf, p, esc); - if (end) - res =3D end - buf; - } - } - seq_buf_commit(s, res); - - return res; -} - -/** - * seq_buf_to_user - copy the sequence buffer to user space - * @s: seq_buf descriptor - * @ubuf: The userspace memory location to copy to - * @cnt: The amount to copy - * - * Copies the sequence buffer into the userspace memory pointed to - * by @ubuf. It starts from the last read position (@s->readpos) - * and writes up to @cnt characters or till it reaches the end of - * the content in the buffer (@s->len), which ever comes first. - * - * On success, it returns a positive number of the number of bytes - * it copied. - * - * On failure it returns -EBUSY if all of the content in the - * sequence has been already read, which includes nothing in the - * sequence (@s->len =3D=3D @s->readpos). - * - * Returns -EFAULT if the copy to userspace fails. - */ -int seq_buf_to_user(struct seq_buf *s, char __user *ubuf, int cnt) -{ - int len; - int ret; - - if (!cnt) - return 0; - - len =3D seq_buf_used(s); - - if (len <=3D s->readpos) - return -EBUSY; - - len -=3D s->readpos; - if (cnt > len) - cnt =3D len; - ret =3D copy_to_user(ubuf, s->buffer + s->readpos, cnt); - if (ret =3D=3D cnt) - return -EFAULT; - - cnt -=3D ret; - - s->readpos +=3D cnt; - return cnt; -} - -/** - * seq_buf_hex_dump - print formatted hex dump into the sequence buffer - * @s: seq_buf descriptor - * @prefix_str: string to prefix each line with; - * caller supplies trailing spaces for alignment if desired - * @prefix_type: controls whether prefix of an offset, address, or none - * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NO= NE) - * @rowsize: number of bytes to print per line; must be 16 or 32 - * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default =3D= 1) - * @buf: data blob to dump - * @len: number of bytes in the @buf - * @ascii: include ASCII after the hex output - * - * Function is an analogue of print_hex_dump() and thus has similar interf= ace. - * - * linebuf size is maximal length for one line. - * 32 * 3 - maximum bytes per line, each printed into 2 chars + 1 for - * separating space - * 2 - spaces separating hex dump and ascii representation - * 32 - ascii representation - * 1 - terminating '\0' - * - * Returns zero on success, -1 on overflow - */ -int seq_buf_hex_dump(struct seq_buf *s, const char *prefix_str, int prefix= _type, - int rowsize, int groupsize, - const void *buf, size_t len, bool ascii) -{ - const u8 *ptr =3D buf; - int i, linelen, remaining =3D len; - unsigned char linebuf[32 * 3 + 2 + 32 + 1]; - int ret; - - if (rowsize !=3D 16 && rowsize !=3D 32) - rowsize =3D 16; - - for (i =3D 0; i < len; i +=3D rowsize) { - linelen =3D min(remaining, rowsize); - remaining -=3D rowsize; - - hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, - linebuf, sizeof(linebuf), ascii); - - switch (prefix_type) { - case DUMP_PREFIX_ADDRESS: - ret =3D seq_buf_printf(s, "%s%p: %s\n", - prefix_str, ptr + i, linebuf); - break; - case DUMP_PREFIX_OFFSET: - ret =3D seq_buf_printf(s, "%s%.8x: %s\n", - prefix_str, i, linebuf); - break; - default: - ret =3D seq_buf_printf(s, "%s%s\n", prefix_str, linebuf); - break; - } - if (ret) - return ret; - } - return 0; -} --=20 2.36.0