From nobody Mon Apr 27 01:52:50 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 EB764C43334 for ; Mon, 20 Jun 2022 00:42:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237314AbiFTAml (ORCPT ); Sun, 19 Jun 2022 20:42:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42598 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237207AbiFTAmj (ORCPT ); Sun, 19 Jun 2022 20:42:39 -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 D23B3A187 for ; Sun, 19 Jun 2022 17:42:38 -0700 (PDT) Received: by mail-qk1-x730.google.com with SMTP id o73so6881158qke.7 for ; Sun, 19 Jun 2022 17:42:38 -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=3/nEaXcS+ZC6RKiVGkArvgF330nGs3znieMvRlKYBkE=; b=e40j//a0UpC8Y8sCD9pIwNHhYdrQIhc2TpikKiZ4J2M58W6FdUALdIMrL/eslykTBx 0nzlTt1rhftLuh0tiigwJVcXj9ODls1SlagoERnk2I9tk/8unLDu7c2cU7Xxtr2IRpom klekBzuOmbd+q2rtwDd1SS8iaPcXODF29ntc55eCRzRe0VDpqhOi6ClSPHanNkFJyDSV mk93zt+iji375miaTDKZXzPcuL4pNBZc0w1Mg8iqI/ssFgqHzCYzI09aFyg0mzVymSJF xrJ5GNt0sYGfdk6Tmbp5lnQ0xw27LP7efZPkEnox3epsAjRgZJYynUgbFAnVjQDfhWLC xmyg== 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=3/nEaXcS+ZC6RKiVGkArvgF330nGs3znieMvRlKYBkE=; b=3W3SjF11bCo1oIqZiIHU7gbR4hwuRWkws89gMIkb/rXssxszgZZN7t6tCezCwFtZWb 6/4fk+bCyJpFU1EBsKdVvHdYqChnaWoQ+LMZ0yXbHOyOZICdm7VwjcuhNjKNsPCg9vMx mPX3skFOcXJRsWzZbKoG+6haxvktp6x1XR4KosdR5TYG92Ysj+S4AI05pOoRE+xJPonk zVUSQw3E8WTdwHtNdjeOzO/cXT83rVbzZmWSCg2K2tSHEnLq/NcqJT/XlaDyEXYIMcj+ OOGuJtFpN/lLkOI66faIPoRN+gajp3q/Q+SHd2ueRejo7vc9iyPgZ+13Syd8ofrHotDK PIZg== X-Gm-Message-State: AJIora9PmYuwbxh6LY15H2MDRDPg+iirmeHV88LrBuGDNpsROJihIz6i gy7iSCgFNRa8EKoqeJrQuB0wAqD+n7qtkH4= X-Google-Smtp-Source: AGRyM1uNJejkIsePjPRiQmFzrgITMNPqpuy+TziXRtN0JNv8oawGRUrDCakDVv7mXhqbhNFu7mXR4g== X-Received: by 2002:a05:620a:4403:b0:6a6:d0ee:8b22 with SMTP id v3-20020a05620a440300b006a6d0ee8b22mr14672050qkp.144.1655685757374; Sun, 19 Jun 2022 17:42:37 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id u11-20020a05622a17cb00b00304bbcc1b8asm9451375qtk.28.2022.06.19.17.42.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:36 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 01/34] lib/printbuf: New data structure for printing strings Date: Sun, 19 Jun 2022 20:42:00 -0400 Message-Id: <20220620004233.3805-2-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 122 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 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..8186c447ca --- /dev/null +++ b/include/linux/printbuf.h @@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifndef _LINUX_PRINTBUF_H +#define _LINUX_PRINTBUF_H + +#include +#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_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_chars(struct printbuf *out, char c, unsigned n) +{ + unsigned i, can_print =3D min(n, printbuf_remaining(out)); + + for (i =3D 0; i < can_print; i++) + out->buf[out->pos++] =3D c; + out->pos +=3D n - can_print; +} + +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_bytes(struct printbuf *out, const void *b, unsigned= n) +{ + unsigned i, can_print =3D min(n, printbuf_remaining(out)); + + for (i =3D 0; i < can_print; i++) + out->buf[out->pos++] =3D ((char *) b)[i]; + out->pos +=3D n - can_print; + + 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.1 From nobody Mon Apr 27 01:52:50 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 197F4C43334 for ; Mon, 20 Jun 2022 00:42:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237303AbiFTAmr (ORCPT ); Sun, 19 Jun 2022 20:42:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237349AbiFTAmm (ORCPT ); Sun, 19 Jun 2022 20:42:42 -0400 Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E864B1F5 for ; Sun, 19 Jun 2022 17:42:41 -0700 (PDT) Received: by mail-qv1-xf2f.google.com with SMTP id q4so1924789qvq.8 for ; Sun, 19 Jun 2022 17:42:41 -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=7puxfADmpd5bpwduUlW40lUB3hrOm3tdyr/76v8FntU=; b=Xa176OeWdZMQYjSjmHh33Vcm6IAuh2AcL+z1TAIrWO67QhBU3iCFyaaJFCZeWG26rD 16XliIB16zdD+/cu14JfMxfr8/g+Y53vmPL7POZeLCfEKsfIwz/jswUbiLXZ3HJFnDQH 7obVryGwtzChjgsg+WGgwWBWQ8rsZZy7IXe7CKxGnFiuOMJT2vxQOH+h9bcPwIbcnWId FagWps8SL3YjnwwsBz1sZPobw+Pi69+P3J0ra4ZMRlyZ6BeGXeBMRbhUW4VqMntXUp1w /hEA0Bu/xZOzWY6toyMwDuxDXi686SC8jgAXpjDn0/UW3hPRkGPEb6RmLsgzgsEdTDJ+ 9cHQ== 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=7puxfADmpd5bpwduUlW40lUB3hrOm3tdyr/76v8FntU=; b=IjYz+av2bY99Qcjmnh1Rvr+tiOFvQwnhzGS+jONUURsgG4DFAuvuTiRX+D0JlH2BkX 1tWwBh9gBCBFJY2/J3nmVmksMU8NW7InG9KEX0519uZk8rEQPLDbg5rVnkS9swZBm/8p LGE6qe7aH2WCuQUvVbCiYBYWbmGbBmfC9FmYVtqPVJlqEk0WwTxhK0C1QhPpYn0RWmmg yXsaW1h/5g+4aF2pLI40NqfWW8bKEPRXMQSuiwzkli/tEXxpUFUAvInNX0iBGvkH+wU/ JStpbwc8tsOfXKIQOyyI/Mk+ayPMMzecrdtBHtzN/F7KxL4OJr2Aq3tDyWtXqs6ZK4OT 2QnA== X-Gm-Message-State: AJIora9GXpnW0ddKCT7G5q8IVKvxVo26dYvGGFIwyO6VSiBPhjyMYnvH +6dXVd2Pp5R++XA3AHAmCdm6zNswcfXj+q0= X-Google-Smtp-Source: AGRyM1uPh/R05FdXB4P79jDyI2BTeFwTjLIBEzI9eAqRYcd+puVm42gtv5KMq7VG610bMMqGC163Nw== X-Received: by 2002:a05:622a:174b:b0:307:1492:cdc3 with SMTP id l11-20020a05622a174b00b003071492cdc3mr16525632qtk.18.1655685759668; Sun, 19 Jun 2022 17:42:39 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id t10-20020a37ea0a000000b006a8b6848556sm10840309qkj.7.2022.06.19.17.42.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:39 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 02/34] lib/string_helpers: Convert string_escape_mem() to printbuf Date: Sun, 19 Jun 2022 20:42:01 -0400 Message-Id: <20220620004233.3805-3-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 217 ++++++++++++++++++--------------- 2 files changed, 126 insertions(+), 95 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..167c31f377 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 @@ -510,18 +459,11 @@ static bool escape_hex(unsigned char c, char **dst, c= har *end) * or %ESCAPE_HEX, because they cover most of the other character classes. * %ESCAPE_NAP can utilize %ESCAPE_SPACE or %ESCAPE_SPECIAL in addition to * the above. - * - * Return: - * The total size of the escaped output that would be generated for - * the given input and flags. To check whether the output was - * 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 +491,126 @@ int string_escape_mem(const char *src, size_t isz, c= har *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); + +/** + * string_escape_mem - quote characters in the given memory buffer + * @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 + * that would not normally be escaped by the classes selected + * in @flags, they will be copied to @dst unescaped. + * + * Description: + * The process of escaping byte buffer includes several parts. They are ap= plied + * in the following sequence. + * + * 1. The character is not matched to the one from @only string and thus + * must go as-is to the output. + * 2. The character is matched to the printable and ASCII classes, if aske= d, + * and in case of match it passes through to the output. + * 3. The character is matched to the printable or ASCII class, if asked, + * and in case of match it passes through to the output. + * 4. The character is checked if it falls into the class given by @flags. + * %ESCAPE_OCTAL and %ESCAPE_HEX are going last since they cover any + * character. Note that they actually can't go together, otherwise + * %ESCAPE_HEX will be ignored. + * + * Caller must provide valid source and destination pointers. Be aware that + * destination buffer will not be NULL-terminated, thus caller have to app= end + * it if needs. The supported flags are:: + * + * %ESCAPE_SPACE: (special white space, not space itself) + * '\f' - form feed + * '\n' - new line + * '\r' - carriage return + * '\t' - horizontal tab + * '\v' - vertical tab + * %ESCAPE_SPECIAL: + * '\"' - double quote + * '\\' - backslash + * '\a' - alert (BEL) + * '\e' - escape + * %ESCAPE_NULL: + * '\0' - null + * %ESCAPE_OCTAL: + * '\NNN' - byte with octal value NNN (3 digits) + * %ESCAPE_ANY: + * all previous together + * %ESCAPE_NP: + * escape only non-printable characters, checked by isprint() + * %ESCAPE_ANY_NP: + * all previous together + * %ESCAPE_HEX: + * '\xHH' - byte with hexadecimal value HH (2 digits) + * %ESCAPE_NA: + * escape only non-ascii characters, checked by isascii() + * %ESCAPE_NAP: + * escape only non-printable or non-ascii characters + * %ESCAPE_APPEND: + * append characters from @only to be escaped by the given classes + * + * %ESCAPE_APPEND would help to pass additional characters to the escaped,= when + * one of %ESCAPE_NP, %ESCAPE_NA, or %ESCAPE_NAP is provided. + * + * One notable caveat, the %ESCAPE_NAP, %ESCAPE_NP and %ESCAPE_NA have the + * higher priority than the rest of the flags (%ESCAPE_NAP is the highest). + * It doesn't make much sense to use either of them without %ESCAPE_OCTAL + * or %ESCAPE_HEX, because they cover most of the other character classes. + * %ESCAPE_NAP can utilize %ESCAPE_SPACE or %ESCAPE_SPECIAL in addition to + * the above. + * + * Return: + * The total size of the escaped output that would be generated for + * the given input and flags. To check whether the output was + * 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) +{ + 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.1 From nobody Mon Apr 27 01:52:50 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 9B7C8C43334 for ; Mon, 20 Jun 2022 00:42:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237463AbiFTAmx (ORCPT ); Sun, 19 Jun 2022 20:42:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42726 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237389AbiFTAmr (ORCPT ); Sun, 19 Jun 2022 20:42:47 -0400 Received: from mail-qv1-xf36.google.com (mail-qv1-xf36.google.com [IPv6:2607:f8b0:4864:20::f36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7D3AEB1FF for ; Sun, 19 Jun 2022 17:42:44 -0700 (PDT) Received: by mail-qv1-xf36.google.com with SMTP id o43so14020159qvo.4 for ; Sun, 19 Jun 2022 17:42:44 -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=B5NTM+DX5OuCQu+RxgBvZ5VjdLFhoELVr1qEqb2ZhLQ=; b=Rhv4feviw9RdGittMpU7oU44oDsojAee8Gbxv+LCU28t3PuUV2emo74fZuc8ES5XSF 46pKswSakgUnLeXGVfdpktpdmus0Hhsr4fwUaxWD7qfTWJlyjbcZ+uRhBLn26Tp2vTKt Fua+LdupmVHtOEdLi+zT15AWgiPxN5dTwLbhua3JahFMqQ7w1Rx5lyDrb1dtFTV4DJbl 0dbLgC57PyvQBQCl1ewqRGeGYDWiUpuNftbAT4rmtDxAUuTbsrAv/JkzANnLeoHC3+t6 RLL4ibSv0a6Wt1wUfgYI6a8jqxZXHeqrBN/pMF9Xd5uIkGUomK9OmCXv6MFPvjxWJEK8 9pPg== 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=B5NTM+DX5OuCQu+RxgBvZ5VjdLFhoELVr1qEqb2ZhLQ=; b=Alixd8Y/eZBpjvZvucqK2BAZTLuHtQs1kkHRb70LRHvT8Habiv46JxexqmVDaDBWC0 nuHLXwpk/8SVWISsNDebKgXTL35GsBsDpxeBRL2bvA8/7UmIsrCZhDievV2GXj2IyxEE S+t04W3tVjDf2vEzVpQDCv4g1uesYuv+nCzlOGQXK5O+R93V3c+HCOfjLqfd2NuQtXn3 /bpzQxPtuoIVh8vpT+D3W2j3rzpJDREqgPHK1d7iHaBoDHa5xYMKi80W/BPuq1xNT6vr kpZIh0H67Qw2hcyaKsSQNfPHkU/svnJebApYAmkO1vUBFf56qiLeAUIVlvLJOjsZ3MwK qubA== X-Gm-Message-State: AJIora98zNsRv0R0GqCswQIfLetGF3ew7hAbMMGuPiNwyhj5ukSVFeOR aLMdA2NpNnIjDmkcGpuGdFKqC6beSsbUCj4= X-Google-Smtp-Source: AGRyM1uhwAdH8EWU95MH393UUy2ig/oCQnJDcUCJOghb/Qw5TubDgtMZWK6bcjHnYaxI7XoTJmJpfw== X-Received: by 2002:ac8:5dce:0:b0:305:300e:146d with SMTP id e14-20020ac85dce000000b00305300e146dmr18151282qtx.546.1655685761705; Sun, 19 Jun 2022 17:42:41 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id h20-20020a05620a245400b006a6b374d8bbsm12182208qkn.69.2022.06.19.17.42.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:40 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 03/34] vsprintf: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:02 -0400 Message-Id: <20220620004233.3805-4-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 1367 +++++++++++++++++++--------------------- 3 files changed, 643 insertions(+), 733 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..7b24714674 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,43 @@ char *number(char *buf, char *end, unsigned long long= num, if (i > precision) precision =3D i; /* leading space padding */ - field_width -=3D precision; - if (!(spec.flags & (ZEROPAD | LEFT))) { - while (--field_width >=3D 0) { - if (buf < end) - *buf =3D ' '; - ++buf; - } + field_width =3D max(0, field_width - precision); + if (!(spec.flags & (ZEROPAD | LEFT)) && field_width) { + __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)) { + if (!(spec.flags & LEFT) && field_width) { 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; - } + if (field_width) + __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 +559,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 +592,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 strnlen(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 +650,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 +669,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 +685,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 +706,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 +795,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 +808,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 +861,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 +887,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 +910,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 +925,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 +933,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 +996,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 +1033,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 +1073,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 +1141,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 +1165,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 +1204,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 +1250,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 +1278,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 +1316,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 +1374,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 +1390,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 +1482,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 +1536,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 +1568,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 +1590,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 +1628,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 +1672,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 +1732,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 +1768,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 +1833,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 +1860,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 +1910,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 +1943,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 +1965,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 +1999,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 +2016,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 +2040,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 +2055,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 +2084,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 +2108,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 +2295,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 +2304,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 +2331,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 +2603,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 +2632,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 +2644,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 +2719,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 +2920,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 +2990,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 +3015,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 +3053,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 +3071,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 +3095,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 +3102,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 +3114,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 +3147,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 +3160,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 +3203,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.1 From nobody Mon Apr 27 01:52:50 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 65626C433EF for ; Mon, 20 Jun 2022 00:42:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237409AbiFTAmu (ORCPT ); Sun, 19 Jun 2022 20:42:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237357AbiFTAmq (ORCPT ); Sun, 19 Jun 2022 20:42:46 -0400 Received: from mail-qv1-xf31.google.com (mail-qv1-xf31.google.com [IPv6:2607:f8b0:4864:20::f31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EED1DB482 for ; Sun, 19 Jun 2022 17:42:44 -0700 (PDT) Received: by mail-qv1-xf31.google.com with SMTP id cs6so9535015qvb.6 for ; Sun, 19 Jun 2022 17:42:44 -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=DdayEjfdURqqo5DL1TngyVO9Ug9wfsh5D2pSgAQqgKg=; b=ToX0lzM6inBSnefVexV0X2pX3tawGLjQq+QnqETk5PE5v838/Izrg43KzHKkBN+prR Dq9QSzN/1YjZv1CfITBGCnhMGnk1Uilr1IVvlAdmvjYKBiky8Cn5LgA2ZSNgU3cgAs+S bwnoxYJph2Y9z5YLYAVFlyuT/aFiqvYh3dJ5fSKoCaZevWnoZkfgrWT3qwBxnWXNaHfB Ghqj2+lfhk0JUU3p5H5UAUjeCI7c3zzSAgtaUGW/Rr0VFtQbPoL4DvVo2YdFMnYtxhJh oX6ZNtwHPQehWRtdf+Pnz+dVpDEuv8PDC5d44SFxFiGLlaMSWzxZpdnlEovbVftEruCE /2Xw== 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=DdayEjfdURqqo5DL1TngyVO9Ug9wfsh5D2pSgAQqgKg=; b=BZk+kLx/hbmtsmZHSwoivQN7Kz5bFAC+jOr+qFKWQeTvF6oqrqIT1FlZNGz1mpmdIJ W7wQQ882y1PJ/ovmibJ2thJeiE4Ui2fwSrPGZjR2rCPmB41/jrTRrA0gjgsGRA3h3IwI hktJQdsDE21/NO9hA6SuE6af7Y6Fiqy1ghlNSbmwJI0yrrRDYTAOBJcyxU0lDs9z2un+ HuE5GME0jAcO5tW2AUkh0GAV0eetXNHiSbLckSEoInFG1X3mzHpITiwvQ9dMwMWc+2m2 yFvHZd9LXVuxmTVpEJI4Yr++ga+YVDPaetO/qwqryYS7Tm7e+pmHpCBUZ41ZkefwZcv8 GD/w== X-Gm-Message-State: AJIora8Wn7oWzTed+r1z5ERD6YDV+8zPKHT1bQFJjw8GzaS44NdMlLj4 g+yDseJx50OmT0SwsTvNB0jfuUZYG5EL3g0= X-Google-Smtp-Source: AGRyM1vzojG5h+79Cx16ld/P42D/5frE32+ZPrCHL1/lehjS3sfM7WtPN0MdbB4QMG5Lm5CKy//Cqw== X-Received: by 2002:ac8:7d95:0:b0:305:2b04:6b1 with SMTP id c21-20020ac87d95000000b003052b0406b1mr17868237qtd.586.1655685763407; Sun, 19 Jun 2022 17:42:43 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id v63-20020a372f42000000b006a6a5d1e240sm10116921qkh.34.2022.06.19.17.42.42 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:42 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 04/34] lib/hexdump: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:03 -0400 Message-Id: <20220620004233.3805-5-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1 From nobody Mon Apr 27 01:52:50 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 52C50CCA47A for ; Mon, 20 Jun 2022 00:42:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237645AbiFTAm6 (ORCPT ); Sun, 19 Jun 2022 20:42:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:42806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237414AbiFTAms (ORCPT ); Sun, 19 Jun 2022 20:42:48 -0400 Received: from mail-qv1-xf30.google.com (mail-qv1-xf30.google.com [IPv6:2607:f8b0:4864:20::f30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1A629B1FA for ; Sun, 19 Jun 2022 17:42:47 -0700 (PDT) Received: by mail-qv1-xf30.google.com with SMTP id o43so14020228qvo.4 for ; Sun, 19 Jun 2022 17:42: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=UGrl8Qfcvy38ICSsYjz56YZufleI8goZ2x0Erajkju0=; b=hr/Ir5woPFK9OzqwRCmFDwrKbx66HzKzOiP/kqFPd253JcHiOLK+E2/VlVUngKqRla TxjJbCOAxMmiHbAJSg+qYn6tQJ5i9tBvbCGTJdggjO4kfIYsj0VOqBHU1wOUOwRJkF2o Sdn7YOlzrXOAwToTO3jrU3w2QcmyBz27dHiWRg5AGs0OYVi1DXMCejBsywZtgmkho8JD s6f+MWt767GkbKxOxvttAV+4iB5ZcIoe6G/evlADxaxgsEi8c3PCw6w2jLJ5ZNo3igEa rehXbxaElnZRvJ38AHeBW++w4msBYLSJKWcN99Qv66iLYGLiY+1G7x+ReQvR7CJDrePg +BsQ== 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=UGrl8Qfcvy38ICSsYjz56YZufleI8goZ2x0Erajkju0=; b=jQ00nW6A657PqxAfPNEMgnD9jLDaDBr4zyGkLDWJG/RafMLosErCyotDtQzhYotW+T q+pEGF1971htZsEf7+KYulTSwkLHdWrEIw6OFmLCCK1UpbP1EQyzxVVPf1n6i1JyQKLY CWL/Rv3SibK7wBmHpvpodHBvbL/AoRzSYfGyxY2/qzpALFVID7UNVWEwE85vkkO0EfoR 3C+UYJEIm9ViW7YpCtQDciqWu9085p4KFiQhW2MPQ26xl1RdyNTFt2gyczl7zL4fUJYE Z2HXRuPw1ZOuZJI3wiVaqhUip84IQk/kfx1NBCZDT31r370La8qcIEs2/rQ0k6aZzmtf UPSQ== X-Gm-Message-State: AJIora/5vlTc4miuMGgLWr8LLcNlsxbhtdwDvjUKigC59WT+YvqK/cbR kHLtzDqy9ypBmErQW4IAOeY7Wuq+x38NT3c= X-Google-Smtp-Source: AGRyM1u8sStuUMJqJg8ijOIqYDwWaCA1Kva76DfZ22wXKjzTr96sGWWaXsdGat0PSBiOiFmPTe0TXg== X-Received: by 2002:a05:622a:486:b0:304:ec30:8c0f with SMTP id p6-20020a05622a048600b00304ec308c0fmr17526034qtx.236.1655685765685; Sun, 19 Jun 2022 17:42:45 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id w10-20020ac84d0a000000b00304dec6452csm9345092qtv.78.2022.06.19.17.42.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:45 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 05/34] vsprintf: %pf(%p) Date: Sun, 19 Jun 2022 20:42:04 -0400 Message-Id: <20220620004233.3805-6-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 27 ++++++++ lib/vsprintf.c | 83 ++++++++++++++++++++++- 3 files changed, 130 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..e3de52da91 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -783,6 +784,31 @@ test_pointer(void) fourcc_pointer(); } =20 +static void printf_test_fn_0(struct printbuf *out) +{ + prt_str(out, "0"); +} + +static void printf_test_fn_1(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("0", "%pf()", printf_test_fn_0); + test("1", "%pf(%p)", printf_test_fn_1, &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 +820,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 7b24714674..5afa74dda5 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 { @@ -2520,7 +2521,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 '%': @@ -2602,6 +2612,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 @@ -2665,6 +2718,32 @@ 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 (*fmt !=3D ')') { + if (nr_args) { + if (fmt[0] !=3D ',') + goto out; + fmt++; + } + + if (fmt[0] !=3D '%' || fmt[1] !=3D 'p') + goto out; + fmt +=3D 2; + + if (WARN_ON_ONCE(nr_args =3D=3D ARRAY_SIZE(fn_args))) + goto out; + fn_args[nr_args++] =3D va_arg(args, void *); + } + + 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.1 From nobody Mon Apr 27 01:52:50 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 59224C433EF for ; Mon, 20 Jun 2022 00:43:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237719AbiFTAnL (ORCPT ); Sun, 19 Jun 2022 20:43:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43634 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237661AbiFTAnG (ORCPT ); Sun, 19 Jun 2022 20:43:06 -0400 Received: from mail-qv1-xf33.google.com (mail-qv1-xf33.google.com [IPv6:2607:f8b0:4864:20::f33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0F41331C for ; Sun, 19 Jun 2022 17:42:50 -0700 (PDT) Received: by mail-qv1-xf33.google.com with SMTP id n15so10001087qvh.12 for ; Sun, 19 Jun 2022 17:42:49 -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=mEyqeuvyYVFCq68f4Sk4QZALU7t6VA5DEezL7DQis8Y=; b=fLu3mcbah3LeFFcLd6Sx4ixRcKu0bTfXOqe3wbxf8BJ/DFjC9wL0kNwb/EUtHx+yFz 8ppi9jdAqVGLub6K7TW0N1Rw5me8QfiKIL50CH8ksgTyNpisxLe4Q/4nO2shsPeItLEw /Cr7czGYPiY9moaX2Rc+i/wFJT9AsM05eEQrpNPzBi8ZRTNFaYrgX3v2HIu/HlJ4JpU0 uYU/mgQmWRG73TeXu6m04lU1h8RaMkVD9JobbgM8IkCBpjakHTvS1J8xWo3NglcCQeM3 bdjGN0Zxo4FCJ5RnoRqUif+F4XMSg5aVyUViwoU34GrE5kWhyORUvLbgup9Vw3TrAkuG Vs8g== 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=mEyqeuvyYVFCq68f4Sk4QZALU7t6VA5DEezL7DQis8Y=; b=IyH4VP5Z23Kedf/MF0TrGYS/nul7dACcy/XyNb4Ns47VvfkDESCyFHJ4/3MnlWxuoi G3PA4+QBT+pwltIPKOXlD8RCrmBzR0X18jdyOSO8anT6PygiC9rtF6/rKfsTg7Izuh47 eWoAuunybfU7ztiDJ4oKnN7k4ir2hQ7fFRnGTNKOet5IIwmH8781mNOFAv4NkbywEoac fWXgak+tBP8LGF86yFaVUNM6gj+u0JFHhpkn5POBoeOtNvt/cAdDhfvOeqdtGulUN+Mh chz4234OmP45sdwTWXHhxVUoFvSeSPqGzJqHSSSXwHMUlCXuy31uSgyW4TGc/0CT0MzJ 66Qg== X-Gm-Message-State: AJIora9zDXDRirpRXpNdz3zfRW4j8xsLVBhLdpkisqbOWf/1AUhQLzNw FgFlEmyVVzCI2ccYzxMPCYPi0yrrDynikX4= X-Google-Smtp-Source: AGRyM1vqcEN8zqRw3lIFKIxZcvzXrdHxzPNSGUo0ecIByl4eOVuaZ3nH1CAHTH2mUn4bKReF7j7P5A== X-Received: by 2002:a05:6214:d05:b0:464:6293:be35 with SMTP id 5-20020a0562140d0500b004646293be35mr17200317qvh.120.1655685767967; Sun, 19 Jun 2022 17:42:47 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a2-20020ac86102000000b00307c9b5e087sm7097089qtm.3.2022.06.19.17.42.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:46 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 06/34] lib/string_helpers: string_get_size() now returns characters wrote Date: Sun, 19 Jun 2022 20:42:05 -0400 Message-Id: <20220620004233.3805-7-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 167c31f377..c1c8d4dfc9 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.1 From nobody Mon Apr 27 01:52:50 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 2D4E0C433EF for ; Mon, 20 Jun 2022 00:43:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237705AbiFTAnO (ORCPT ); Sun, 19 Jun 2022 20:43:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237696AbiFTAnH (ORCPT ); Sun, 19 Jun 2022 20:43:07 -0400 Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4EF80EBB for ; Sun, 19 Jun 2022 17:42:51 -0700 (PDT) Received: by mail-qv1-xf35.google.com with SMTP id cu16so13426196qvb.7 for ; Sun, 19 Jun 2022 17:42: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=sRvBrdNqHSOuaoyss77k+WXhFUbhXQ/IETYNRL++H68=; b=C0iy85m5EuxdFG09Uh6+Haq+2q/rP3zXWcbwUJqs4YtBMwxq/vLtLbpPqkuakivAnS ERWQbldL9l9Kg5o9jHhW0xACtq8slkMT8ajsWOzPiBM1CNZhx4DG7LjmuSYVJEC0XnjG B6uawwH76VEa/hLnq+G8O+A1rKHcebJtjF/N6zbqbAa6U5kpWUWDbW+WN10ocx5NnMsL mV0Vq8Ujxr7mnxKyOgvit6Iez+Jfn9+vpjwrAKltmw9A7ZUZJs7z/JyH6XrWtpZQv8VK 33hPYUZKtz2gESvicUXyk5SE+EUdRBdogDul0KWQhLRmvb9dMHUWpaBnbQgklvUM3ZpI Fm3A== 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=sRvBrdNqHSOuaoyss77k+WXhFUbhXQ/IETYNRL++H68=; b=swBXAwzGTyheCTJy3Y7+XmRhhIZTXRPu56XxUPJOBlKhJKlj4yennxDXamJTIeuWj5 88pngVVZCrVqslBTASWd/mQHJjqPoIMmN7++TIhNbh5UF/W89qkBboWJpJDGA5Blo/ZZ 8mc3sWPMReCzvp3DukypVUt3SLeUG2pCNQFz6o25Y8mw7LM470HejFQueohc2P210Xez hbu7O/d1V9IJXOphlHeBIhyheM1sn3KeKcgzivIwUbwlHXOxhn36daP2Nw8LHWY+h2/N BOIfSn+0K1fzelT7oLJ2jVHPJYO8gejM/4wiMllCnlp2WbBtxD5ieXQ88ax7aH5ayYF1 vsng== X-Gm-Message-State: AJIora/mqBR0OgJG3ZX25QXbgf9PdVh+nI8DKIZmjUk7WPGS8UD5T47L kYabBDilwIkmpLNLZdJyMcQvl/ut3QqjTUQ= X-Google-Smtp-Source: AGRyM1scNnKLdDPjDmLLvYvy5kkK6KyNyDdCsMJnrp7LkoNXR5fOfae3fke6nNaiaLijdgXoPJsvNA== X-Received: by 2002:a05:622a:d0:b0:305:c643:68fe with SMTP id p16-20020a05622a00d000b00305c64368femr17928566qtw.232.1655685769928; Sun, 19 Jun 2022 17:42:49 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id t20-20020ac86a14000000b00304b5eef8aasm9398994qtr.32.2022.06.19.17.42.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:49 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 07/34] lib/printbuf: Heap allocation Date: Sun, 19 Jun 2022 20:42:06 -0400 Message-Id: <20220620004233.3805-8-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 120 +++++++++++++++++++++++++++++++++------ lib/Makefile | 2 +- lib/printbuf.c | 71 +++++++++++++++++++++++ 3 files changed, 175 insertions(+), 18 deletions(-) create mode 100644 lib/printbuf.c diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h index 8186c447ca..382863afa7 100644 --- a/include/linux/printbuf.h +++ b/include/linux/printbuf.h @@ -4,19 +4,69 @@ #ifndef _LINUX_PRINTBUF_H #define _LINUX_PRINTBUF_H =20 -#include -#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 +#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: */ @@ -49,26 +99,36 @@ 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_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); printbuf_nul_terminate(out); } =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) { unsigned i, can_print =3D min(n, printbuf_remaining(out)); =20 @@ -79,13 +139,18 @@ 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_bytes(struct printbuf *out, const void *b, unsigned= n) { - unsigned i, can_print =3D min(n, printbuf_remaining(out)); + unsigned i, can_print; + + printbuf_make_room(out, n); + + can_print =3D min(n, printbuf_remaining(out)); =20 for (i =3D 0; i < can_print; i++) out->buf[out->pos++] =3D ((char *) b)[i]; @@ -101,22 +166,43 @@ static inline void prt_str(struct printbuf *out, cons= t 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..8c70128e31 --- /dev/null +++ b/lib/printbuf.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: LGPL-2.1+ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifdef __KERNEL__ +#include +#include +#else +#define EXPORT_SYMBOL(x) +#endif + +#include +#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.1 From nobody Mon Apr 27 01:52:50 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 207DFC43334 for ; Mon, 20 Jun 2022 00:43:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237821AbiFTAnR (ORCPT ); Sun, 19 Jun 2022 20:43:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43710 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237722AbiFTAnH (ORCPT ); Sun, 19 Jun 2022 20:43: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 F300A2725 for ; Sun, 19 Jun 2022 17:42:52 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id c144so6864144qkg.11 for ; Sun, 19 Jun 2022 17:42: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=K9eoCaahKKF8GPcnHNvxh314XQP7M2mbXnjspgXSnVM=; b=kzWZ14UhWQpr2qaOlYS9QzrKiCUW6Xki1/EC5YcTuk5f5Mk9/O4KLB0qiX8Ne65In/ CmjidGpj819sto9/TLGGZUjJKfvvwrmOFdiMD/9uWzMgdeK7tfjDZkqutc+4PAEotN2v s7GlrUlWfy8+xJ2pmBRxTpwR8JDtUYuzd47cbQL8pc/+33zJ6IRYXnIm/5CsjhSY6HQn F/0au4BW21jw3kHihRksYnCPYw/0rff3z+YAT4juNJkTsUJAf8rLZp/RPy/fVltfOyFs C0LLJvdJYnIPwGuJxVS4z0qr1Ce8p79jMu0IOjuO1gZptsD5LxffMCQzXk8MpOtyklAH Vd7A== 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=K9eoCaahKKF8GPcnHNvxh314XQP7M2mbXnjspgXSnVM=; b=kNesjNbch9cDpnMKVKgBFLBCzYBUYGtoYKmnCsKXw4f4CMqWFCcF0hyHzvB3V6IxzD T8Apw515L4SQtICiwDIMlOKmrtkOmzgUPwSgyPFm5PkYiXDaYSXRfPVaPiYQBeYRSQVs wD9ouOvUz6FFqzx3AkQ8MrGpDvBFI4uD7DfDy0+iiHmTfHgV0mYhqF5DvBV0LMm9rWOl blGDSgafOmSyDxE4c1fm7Mx1hMvzgBYPE03/RRrVISHuOFH0u5GdyWilGdEAxONVe4Gj KcsSc4crXhsuIEAkmfVIR/LkgKBDcgS11IoL5k9bIBhb5S32I0FlCOOZAlIPYLxqXIsf Usdw== X-Gm-Message-State: AJIora80YvA2cSjws/3E9AO293JxlvzzW2Fo8hqtM0QpI3SgNNvM1cXK tHjTMUfSCYpkl/1YtF6jF/ArtCRvCdXaHwg= X-Google-Smtp-Source: AGRyM1sMZcU2iV/7Pecfr7pTe2lv/4b97s6iQX0qqt/h/ZDOAxOF/7yxG51Ro60SoZQ5zTofSHExNw== X-Received: by 2002:a37:9fc9:0:b0:6a6:c16b:e634 with SMTP id i192-20020a379fc9000000b006a6c16be634mr14842818qke.230.1655685771574; Sun, 19 Jun 2022 17:42:51 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id u3-20020a05620a454300b006a69ee117b6sm11144854qkp.97.2022.06.19.17.42.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:50 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 08/34] lib/printbuf: Tabstops, indenting Date: Sun, 19 Jun 2022 20:42:07 -0400 Message-Id: <20220620004233.3805-9-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 30 ++++++++++ lib/printbuf.c | 125 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h index 382863afa7..1e43c47891 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 @@ -45,18 +62,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 @@ -187,6 +215,8 @@ static inline void printbuf_reset(struct printbuf *buf) { buf->pos =3D 0; buf->allocation_failure =3D 0; + buf->indent =3D 0; + buf->tabstop =3D 0; } =20 /** diff --git a/lib/printbuf.c b/lib/printbuf.c index 8c70128e31..a7f80f63ca 100644 --- a/lib/printbuf.c +++ b/lib/printbuf.c @@ -12,6 +12,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; @@ -69,3 +74,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.1 From nobody Mon Apr 27 01:52:50 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 DDDEBC43334 for ; Mon, 20 Jun 2022 00:43:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237965AbiFTAnX (ORCPT ); Sun, 19 Jun 2022 20:43:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43722 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237747AbiFTAnI (ORCPT ); Sun, 19 Jun 2022 20:43:08 -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 5F1466585 for ; Sun, 19 Jun 2022 17:42:54 -0700 (PDT) Received: by mail-qk1-x72e.google.com with SMTP id d128so6880176qkg.8 for ; Sun, 19 Jun 2022 17:42: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=fmnZsBS7ICfhtPbFVJE00Af049vTUvEMSfkA9G33Z+Y=; b=FS+p1cBlMgrvZr0p4b+tva3wEIao0KwdEJw4GNGD0MkRDG+Q78eE9bMbYmNKtz1DFW GYcGcOEivpoUJV4yz/3AMofzVI9M8D5IHkPwmR43g0hZNzL2RqObGCtM+s3hyXdZq783 xLNOzqLaOM6J7c3kv6aoM5vBqMw0zgVGzD2LoWbaO7xkjPaZXtnuAlFvKDfkD8uYtTZd ZRCJVXDTZy/0Ev8v0CWU9Eb7XNDiYE0PjEzKuUhKWCrILL/AKr1H5WNdMMggHtDpzHM/ clj7iSjtJR+pHdqJp9SNzOJ7LOOnh768E6/lULh9I5d3iDT6/zzudxsdIJHoxuM45QLq OktA== 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=fmnZsBS7ICfhtPbFVJE00Af049vTUvEMSfkA9G33Z+Y=; b=tttIGVoLdvN6moR2cU9O/Uyey8/Vx9xnmIBxY5KMiAWYszEfOq7TmUereCavKq0c5V HbZMPMTRY2uZTO/BjBdz2VqjhASSIRgfqS4pzF1Acw8rLr+sC/TFRCf2LXnWKjDYLpu3 Fpi20Yzo1mMBHQCL2XwPj2qN7HXEPfY6SUSibUy2idxk8C+V6PRRBJSl88bmTxLoJZQr DnxtPS/B3FRNO3gUp70bKPUKs1rEoJIutiNojNBsANnjlntw3TEv2I6eGnBkMa5n61jt UMl8UUNjulT4vJTTLsw+/DZWOGXAwHc4/tyGuUsmAAnbwgIOg4i8Gjxq5DGOeVsNhxb+ oHQg== X-Gm-Message-State: AJIora/wMfd6uOj+IEwhJMxMnBE/rqLV+7rZoaSwk5tkhREARFaI/wYx YKPAe+5ohGCu93wPdRVnjJCt9tYmMZ3Vae8= X-Google-Smtp-Source: AGRyM1tBmrxf1indi/uvJgmAPcm0cBP3mfXeFK9mluLQyQy1jfh9ZCHnRGgEBFB8u9JlPE8+z6ipmw== X-Received: by 2002:a05:620a:d94:b0:6a6:6c9c:c7ec with SMTP id q20-20020a05620a0d9400b006a66c9cc7ecmr14807435qkl.221.1655685772861; Sun, 19 Jun 2022 17:42:52 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id i21-20020a05620a405500b0069fe1dfbeffsm11316870qko.92.2022.06.19.17.42.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:52 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 09/34] lib/printbuf: Unit specifiers Date: Sun, 19 Jun 2022 20:42:08 -0400 Message-Id: <20220620004233.3805-10-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 1e43c47891..5100287eed 100644 --- a/include/linux/printbuf.h +++ b/include/linux/printbuf.h @@ -53,11 +53,20 @@ * * 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 #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; @@ -71,6 +80,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]; }; @@ -84,6 +95,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 a7f80f63ca..553f89ebc1 100644 --- a/lib/printbuf.c +++ b/lib/printbuf.c @@ -10,6 +10,7 @@ =20 #include #include +#include #include =20 static inline size_t printbuf_linelen(struct printbuf *buf) @@ -194,3 +195,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.1 From nobody Mon Apr 27 01:52:50 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 0A614C43334 for ; Mon, 20 Jun 2022 00:45:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237974AbiFTAnY (ORCPT ); Sun, 19 Jun 2022 20:43:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43698 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237786AbiFTAnJ (ORCPT ); Sun, 19 Jun 2022 20:43:09 -0400 Received: from mail-qv1-xf29.google.com (mail-qv1-xf29.google.com [IPv6:2607:f8b0:4864:20::f29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C3850B4A2 for ; Sun, 19 Jun 2022 17:42:56 -0700 (PDT) Received: by mail-qv1-xf29.google.com with SMTP id i17so7357747qvo.13 for ; Sun, 19 Jun 2022 17:42: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=q4yiyjFbZ5Juzr+Gz/H2w54X4y4pvmCy/Lt7Z6lfmMw=; b=fXdKF00OwYkVBQf5hc3gb32tV7KgsiOs4n11yQWXVgL+6mj6VmTxCqqddq1hNVmhhU KnOhYxLu3QkN7RTkyQTS1gssSo1Bs8yCPVd83VicRXKVetgS5XGkH4BVuQwGgNEMsyzt f+5N9qn32cEEPz+/h0lsztWQc+7wEmOd/oF4eBS3qD+OMHV5abMffRwqYiZEzYdQSV0f VNb70uSvAss1oYJz7Lyvz5M5d+FXM4ct3UUdozsqRSgbcm7tXrrifgDWO1e5AnZYs8RN I3NpuImwcCt1EKiid56vxO5FhQQhJrihSRM+lKNsbjKK1UPRLtQ8Xa62KQ6MyLdF+vyR BOUg== 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=q4yiyjFbZ5Juzr+Gz/H2w54X4y4pvmCy/Lt7Z6lfmMw=; b=eLOj7NU10r0Ss/5J1uuEN4VGwU/UcIx1Rxieg0Her6/akilDxStu+hFqYO+vqIh59g ukfo29y1YoR9GkcWNdiva8VDDcobnwv1wmb/m911jIsyicFi4xH8znFSrauONqeKyY/O ec01N/Xd8dIISyQi1BIQJgh+7yGrv5O9pkeS5w9VGlVQU+/VNRtpWTMJ26am2OyD4ubx SXf2gwy86FV9pEtVD0+1io+zSPdyMKwm6+gPHGGv1DfKM7Qc9iWMEEcwKOIsQ/noEZT4 TlFHkKtTpVc8US1sxIWXtXYamKaiUvWgwt7XkvE1EvB1TcOGdMeUQxgsdACoRAUt/bFe GcXQ== X-Gm-Message-State: AJIora+P60lnOYLau5UwA0WdfYe5Hz7CKLNRo2udBiHn5f/nA4QHe6Mm DlInCB0gi0Depef6siuCrxCASEAelmFmHFo= X-Google-Smtp-Source: AGRyM1tYNk5fbWQsttURTreDFM+BkJM6BzdKKxG44Rqes86jH7ptzH4Kis++RT67FHxHEe1SWABRfg== X-Received: by 2002:ac8:57c3:0:b0:305:2dbd:92b3 with SMTP id w3-20020ac857c3000000b003052dbd92b3mr17904388qta.173.1655685774989; Sun, 19 Jun 2022 17:42:54 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id q4-20020ac87344000000b00304e5839734sm9303936qtp.55.2022.06.19.17.42.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:54 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 10/34] lib/pretty-printers: prt_string_option(), prt_bitflags() Date: Sun, 19 Jun 2022 20:42:09 -0400 Message-Id: <20220620004233.3805-11-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 60 +++++++++++++++++++++++++++++++++ 3 files changed, 71 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..addbac95e0 --- /dev/null +++ b/lib/pretty-printers.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: LGPL-2.1+ +/* Copyright (C) 2022 Kent Overstreet */ + +#include +#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.1 From nobody Mon Apr 27 01:52:50 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 DF2EFCCA47A for ; Mon, 20 Jun 2022 00:43:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237439AbiFTAn0 (ORCPT ); Sun, 19 Jun 2022 20:43:26 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43720 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237816AbiFTAnL (ORCPT ); Sun, 19 Jun 2022 20:43:11 -0400 Received: from mail-qv1-xf2a.google.com (mail-qv1-xf2a.google.com [IPv6:2607:f8b0:4864:20::f2a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 69880B4B4 for ; Sun, 19 Jun 2022 17:42:58 -0700 (PDT) Received: by mail-qv1-xf2a.google.com with SMTP id p31so13998603qvp.5 for ; Sun, 19 Jun 2022 17:42: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=4+doRSndIqb/FisTLPVe5Bh/ofBw5aQUkb0tO+s0zbQ=; b=WRsAgh5sLiSXnUWsFWUdKfv3snQ371BnO978e4fY372IVVti8PHQr4mdmPcHCoZIfl cWczSiCcC50anmfaWm5q+8+IS6sHDTgs3xufm0GoK1c6bn3oMXlKLNMszpjs0bDm7H9b VJm2O7Ylezs9ZcWjgYT74IdKN+FJ+ItstRUT58jSjskNJXfCspOSSunzLuskncp+UTom ETzU9mOWaaMZ0IN7+jLeqWPNOuFYTit5m4dagIJPviypEkq0hnRkrDJ4tK9AgOtHougZ o2L9q/1OmXm/Y7ZyrFN6uDiZMnY883rXN8+npJm2rHrMai7cWfip3CRSNksw6aBnugVH J6wg== 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=4+doRSndIqb/FisTLPVe5Bh/ofBw5aQUkb0tO+s0zbQ=; b=u4k/HewOLoewD/82d+CP7BMxlOunqfQi8GAi/xjRK/gA/uxs8u71Lvu3aofnjkMnNL e9uXIfV7V0Dn9cVJizoXo50kTznVYS/dqIa8yI7QEfMBJ61uCTfHZA+iuxLOKocX0BrY NqDqUnPt1Ohwv4ZuVHE48/KL7Say8O2Zyqw/ysv0OY8Qi4ufFp0FAM5qypbtqruR2lpQ BPbHqRyArJTcqKUseVwFRA0wKppw/Sv/XsEfzQZQvXpNTaRcHR40sI+XXD+4SjfAHfHP OPpk/q1v9S2AbbHLUmLV/8G5wdK3hT4N6SJubTVoLHUkAn0QR6EXuwSrNubxP+VfBwyi zhPA== X-Gm-Message-State: AJIora/1i1qlXlaryHKk09+5vCrun/HmV69VKHhQFjWQhHHYz9TjRZ2W Xe6NXH/T/n3Roe3/0LysD61MiqzXk745HAY= X-Google-Smtp-Source: AGRyM1vA0V9RjbIKZsYA7zZoD0L520hpVBmC/QV5Y4Fl5nCasrnrNz3TXtyGGqCBHjwmSFxKxKwLGQ== X-Received: by 2002:a05:6214:c82:b0:46a:b677:e284 with SMTP id r2-20020a0562140c8200b0046ab677e284mr16988331qvr.28.1655685777230; Sun, 19 Jun 2022 17:42:57 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id l16-20020a05620a28d000b006a6cadd89efsm11521487qkp.82.2022.06.19.17.42.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:55 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 11/34] vsprintf: Improve number() Date: Sun, 19 Jun 2022 20:42:10 -0400 Message-Id: <20220620004233.3805-12-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 83 +++++++++++++++++++++++++------------------------- 1 file changed, 41 insertions(+), 42 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index 5afa74dda5..7d20406deb 100644 --- a/lib/vsprintf.c +++ b/lib/vsprintf.c @@ -458,93 +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)) && field_width) { - __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) && field_width) { - 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) && field_width) + __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 */ - if (field_width) - __prt_chars(out, ' ', field_width); + if ((spec.flags & LEFT) && field_width) + __prt_chars_reserved(out, ' ', field_width); =20 printbuf_nul_terminate(out); } --=20 2.36.1 From nobody Mon Apr 27 01:52:50 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 9EC25C43334 for ; Mon, 20 Jun 2022 00:43:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237716AbiFTAn5 (ORCPT ); Sun, 19 Jun 2022 20:43:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43654 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237720AbiFTAnL (ORCPT ); Sun, 19 Jun 2022 20:43:11 -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 3ADFEB7D2 for ; Sun, 19 Jun 2022 17:43:01 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id c144so6864144qkg.11 for ; Sun, 19 Jun 2022 17:43: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=87vr5hheCjxa+C+zJDx+UhCXUzg+Bvxner7x63Be5z0=; b=ocbtVxqlFRKBq2hJSLkb1jSAZI+z+3QG9/JSVg+4RFJ1C/ow58U8dZhOK82LCCUPOB 3HRqKTj9Vp+ypkb2xtG+NnDyZobOOfEob5du36/KgfSpRRen4GXLuTwz7CXEUpsCaCrA +L5PUA1xlnrN0JSOja7JY9f+NodUqwMC92vxSt0iM9vHyNyEzklb13A3yLvzlmrcjC/k yFACZSug+zUrJkcC+DiHt70wi+qd6LAArh2Zp4szCWvuqY92HgZqwFeQjeT5rcl99DMp ml+k7YYcbgaj5BXOB3em38kBqjfsUY3OzwQ5+dsgnScr1TBqSN+Un3SRuBO3CY3ws5wt k3JQ== 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=87vr5hheCjxa+C+zJDx+UhCXUzg+Bvxner7x63Be5z0=; b=yi3R5sO9WZARY1Tec2QDZjLrv4WNy6EmiaN2+Q7e4S+moG0Rrx3+wNlV9D/AMibkRh 6sHLrxgyfqSelY6aQKgUEkyBky7hgzuCZbjK+rWfknRJP3DbCYGpRXEtnKTgtcU86fYG Ly52WqS4fO+jXQFcJGczT9ErT7F56LPxexMUXVe4olnWMziPQSzYoiE7zYV3sBMWpugk WJaX5rAxlo/KFXdesolCzEk9vllvInqxDRsXDN516MQHeKYhhW6khZwukEzST7T+AwIV OiIbCugVsmZ1A7Uo0k1EQ8kJuJABpR1h4QquZJ7qGEMrnKEf//VqlxBNqwUcXjTCfSXD 13OQ== X-Gm-Message-State: AJIora8thd86yyqU4DR/leezdBurucX3RgrstSbYPT0+o7kD7C8E7Q4U DjHG+TYqpp70eKTvJW7vTevL1Mp95Fy7gW8= X-Google-Smtp-Source: AGRyM1vHltOnT6lZQxwYcHcDmIe/iCQZuLx8M068VFsShpd1IhADyohd3Ftmhz+guiDL0E8AM8B5gQ== X-Received: by 2002:a37:ad09:0:b0:6a6:ae2b:9d54 with SMTP id f9-20020a37ad09000000b006a6ae2b9d54mr14777059qkm.424.1655685780208; Sun, 19 Jun 2022 17:43:00 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id y26-20020ac87c9a000000b00304ecf35b50sm9055654qtv.97.2022.06.19.17.42.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:42:59 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 12/34] vsprintf: prt_u64_minwidth(), prt_u64() Date: Sun, 19 Jun 2022 20:42:11 -0400 Message-Id: <20220620004233.3805-13-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 7d20406deb..e65115f90f 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.1 From nobody Mon Apr 27 01:52:50 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 084BAC43334 for ; Mon, 20 Jun 2022 00:45:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238577AbiFTApf (ORCPT ); Sun, 19 Jun 2022 20:45:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237887AbiFTAnM (ORCPT ); Sun, 19 Jun 2022 20:43:12 -0400 Received: from mail-qv1-xf36.google.com (mail-qv1-xf36.google.com [IPv6:2607:f8b0:4864:20::f36]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A72E8B85E for ; Sun, 19 Jun 2022 17:43:03 -0700 (PDT) Received: by mail-qv1-xf36.google.com with SMTP id g18so6506831qvn.2 for ; Sun, 19 Jun 2022 17:43: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=jzrJaN7GJ4zvwlB0O2GIJnZ1v/nEIhK2TK9aO5Rtgmc=; b=Lx1lmnEKLmHMo8GHFAGvtwT3kPHmLRskpKD6CEVJIlEOc7OOqPkS+AyPuQjC6rkL/R RVK8+PQf6sJtv6K7a1/JuyP1Tc8zux4etc1R1OE3bbgEZ3C8RrskO7A6KayUFnodw0Pi /nvSWAOB9bk2S6Md2QizVlUhMvW8PKZGGu8BijiTIUeuUUB/OGAuTBxCrEE/ciQCaAUX Rml/JegJzNmIz1eCPDhc3Qw9qhEClxDG6UowIKZUFCXu6kOW63ydkkszQeUimcN+3KHr RuJ/x1XnWgd11/FREucrvMRD+5RQLlaQC0XKRsSPIHg0Gshd7s5dqqdASW/2g/yvTaQo gWfw== 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=jzrJaN7GJ4zvwlB0O2GIJnZ1v/nEIhK2TK9aO5Rtgmc=; b=r8kdixNkOjs59Imbledaw3FOrWGPzvT6xQmayshKJwD/N1zq057SQW/C5EKuj11kaW ATE9+F3KtTqVf9/60FYZagzso9ZynING9Za4yQuGrT356cdBVDVzjiMKa+/yK1qsN5Nb iKuM0GqmFFi9su34S9IMQS7W2vHqXYU+3jf4ASKJSDhBIzAD64PJfQhOK+wHrRfbeCEj zCWgbACSMhO7h9nZZx8qNuuCk/u7rZcR/7c0+SLU+70jNRGFK19LJyhwdhPogMil+Pfz Jq/ds9WcENSNt5EB+Bdo7O24kuok2TI9p4uaT6IVjuioJgpEhLseWShCEKROoxxyPjT7 LvOA== X-Gm-Message-State: AJIora/tDIjIcNd/qc1oXV78HzTIV37qp+Ha+rsOdWz2jOin8BT/wW2i 5t0EUSUSbx5MSsRGoqz0KSHb2pAcsBQiDpA= X-Google-Smtp-Source: AGRyM1sksTfZsVTyUyCjlAQdG4wXyI6RZnc1sCTZrHrYV9IC64sOB5+yfZ27xlwBXuwuV9wyMa93IA== X-Received: by 2002:ac8:5750:0:b0:304:fcfa:67db with SMTP id 16-20020ac85750000000b00304fcfa67dbmr17632697qtx.249.1655685781656; Sun, 19 Jun 2022 17:43:01 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id c10-20020a05620a0cea00b006a6ab259261sm9905480qkj.29.2022.06.19.17.43.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:01 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 13/34] test_printf: Drop requirement that sprintf not write past nul Date: Sun, 19 Jun 2022 20:42:12 -0400 Message-Id: <20220620004233.3805-14-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 e3de52da91..853e89e2f8 100644 --- a/lib/test_printf.c +++ b/lib/test_printf.c @@ -79,12 +79,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.1 From nobody Mon Apr 27 01:52:50 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 F3448C433EF for ; Mon, 20 Jun 2022 00:44:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237868AbiFTAoC (ORCPT ); Sun, 19 Jun 2022 20:44:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237776AbiFTAnO (ORCPT ); Sun, 19 Jun 2022 20:43:14 -0400 Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 76FE8B87C for ; Sun, 19 Jun 2022 17:43:06 -0700 (PDT) Received: by mail-qk1-x72b.google.com with SMTP id d23so6897371qke.0 for ; Sun, 19 Jun 2022 17:43: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=4dx5EHxS+Bc5zmGRj8O4zivffDN8YwyAXPhwFUi8JmI=; b=NZBGR44vTQygj+rXdGeg1grnsecIqyGEdQybcB20cmv/nA7GLergqXllRPWwikUSZV pZkWWljOwKQ8Kd1JRCCGD1S5WJOf1GLGEjAXccVOqCom/SDwO7EgxT7imTTdRnGx9PJo GYkrv5zYJORePNAM5bmalc81mTSbwNhEaVTN0VDVXi5ZTpwOFVtwSObQGB+DjRcYR0aL qHzhHcrMypjrg3fBWbe9ROTiKhTPsZh/ipLpNwGt/QAEn9ac/wqve81VYHcgsE3QO7K7 gaNv89ST8mjxu4E7me7L6HQLLQxb4FQZBhU/HzH7eCmmXo0JVI5kCo9sC+pnY/PtejO0 eP3A== 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=4dx5EHxS+Bc5zmGRj8O4zivffDN8YwyAXPhwFUi8JmI=; b=SNr5Ilykzib3zQjkw5ClTj2hlQcT7CaovtT6n67sW+TS3zlLE3r88NPDp6fFWC+C8L 1UuXdDzbzeD+8C2IUMcsUFZov+Iau+BKoNuAj4RStwzQAhX+gVt1IkvRcjmm0knXjwuP 1F7kXNjv3V3TbpjT/wYkB8oFihTIFfs2jJWuo8Gh8UdKYVGJ0HruhhI091Rz11jhLq/e uZ3cOGMNVdUmDfiO5OJCJ2B51xbpWpPIen9EzfTKqLr4eWtFmpsI9keU5heJ3BlinCes jHlLDAiWBT6UdTwkt7a3DBgXLfITN+zuQIa/0vO7PxYcxxN313jzuXW495pa6yIcMiGk KKnQ== X-Gm-Message-State: AJIora+8ZI1F139UXCMP3t4sn9QB+QqSUiW2S1mLA+8jT6deIu2nz13s ALwlJ2EGz75j7I7B/2BpVVYs5d3y1NztLrA= X-Google-Smtp-Source: AGRyM1uCbwc6eS6HefaqKgmuvMSQHpNDhPpI5ZgkmJ8fzosWwAs5hQiSxbV2HtlLCuCC2Njhd8jk9Q== X-Received: by 2002:ae9:c30d:0:b0:6a6:90b7:3905 with SMTP id n13-20020ae9c30d000000b006a690b73905mr14938486qkg.371.1655685784512; Sun, 19 Jun 2022 17:43:04 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id j17-20020a05622a039100b00304fe96c7aasm9962839qtx.24.2022.06.19.17.43.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:03 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 14/34] vsprintf: Start consolidating printf_spec handling Date: Sun, 19 Jun 2022 20:42:13 -0400 Message-Id: <20220620004233.3805-15-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 248 ++++++++++++++++++++++++++++--------------------- 1 file changed, 141 insertions(+), 107 deletions(-) diff --git a/lib/vsprintf.c b/lib/vsprintf.c index e65115f90f..feaca085cd 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); @@ -2704,7 +2733,12 @@ void prt_vprintf(struct printbuf *out, const char *f= mt, va_list args) break; =20 case FORMAT_TYPE_STR: - string(out, va_arg(args, char *), spec); + /* + * we can't use string() then do_width_precision + * afterwards: people use the field width for passing + * non nul terminated strings + */ + string_spec(out, va_arg(args, char *), spec); break; =20 case FORMAT_TYPE_PTR: @@ -3199,7 +3233,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.1 From nobody Mon Apr 27 01:52:50 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 EAF57C433EF for ; Mon, 20 Jun 2022 00:44:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237924AbiFTAoE (ORCPT ); Sun, 19 Jun 2022 20:44:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44230 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238015AbiFTAn0 (ORCPT ); Sun, 19 Jun 2022 20:43:26 -0400 Received: from mail-qv1-xf33.google.com (mail-qv1-xf33.google.com [IPv6:2607:f8b0:4864:20::f33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DFC19EBB for ; Sun, 19 Jun 2022 17:43:09 -0700 (PDT) Received: by mail-qv1-xf33.google.com with SMTP id t16so9021471qvh.1 for ; Sun, 19 Jun 2022 17:43: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=VCq6AKFAlUXGqF4DA0HsDCSO8h2xYDtnNCe5ZdhSdK4=; b=Oe5cJFCnVbXEmZUpE7rqgrX5IjJnEG7SbQFZ95e/WKbGj1Hl2J7mTiwwDWsyD6Z3YS /a/iW28zNI9mTxABs6ipe4wRhdybAdBIcl4ZM4Wg/CYV3PGvElUmDIPPmg0IUZMSOixi zvfjYtdqjzx+H+inYmA3agMXfKKOgSGja8sRQO+i+mXan3sQJza85N4S5a5u9QmNpv25 KeJtv0wR/K+QCTorLCHhZCESxOluSs0Hk21DZbqOSMEvCyr5fz2IuXUpRIOn4k2Ol25r grRxL+L0ufPcKnYfY8ch9ncR5CDqJbnR/z1vhd68AwnhmBbssvIvYXSenZLuA2HxKfZc L5Dg== 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=VCq6AKFAlUXGqF4DA0HsDCSO8h2xYDtnNCe5ZdhSdK4=; b=dtcrOz9cyJ+ZkiNzJkBUX0AZ0Adk84/dW4jS6JDcEMojfaGVYg8g7lacLTv8U8kxzi Jsq4dH8pO1RXg2oMk4ruC0HzviYNlV9NRKFUZOwu2Bh6+WFkpVZKMLEQu1NQdeP9x/3W SXVgBmA/iPn+aaIcBJ4phy3u+J7uqQi+tzJqDjTUA92Y4WheYgiXRT/lfc5IDocDMMwZ qi5uBhk6oeJC2f3INiXDuOfa/jeplgG89uUWFFSDYXa08zJNRfMoCKzQI7kpvA/C9KJl +g8mcbRdjPydGOsKbZzoR5lZgPN/9rc0MC0LnYykcphsakXPzjVGJljRNzYztAwZGQjl /rbQ== X-Gm-Message-State: AJIora9R3O6Amhee3ZKbh8iuwePfA4GLS7xSLHhRP+TvmUg86D9fF6ri W3Hy6ZZt+72zjrY6SDWADjeVh1MtWuVRgnk= X-Google-Smtp-Source: AGRyM1sMsY6x0wzYYG8F8zSOj+RzNa5QMB0waNv1G3LpplIDOxZ1RPdMTxyR3MGURfWs8xYml8DWAQ== X-Received: by 2002:ad4:584c:0:b0:464:5904:998d with SMTP id de12-20020ad4584c000000b004645904998dmr16937211qvb.33.1655685788313; Sun, 19 Jun 2022 17:43:08 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id d8-20020a05620a240800b006a6b564e9b8sm11073547qkn.4.2022.06.19.17.43.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:07 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 15/34] vsprintf: Refactor resource_string() Date: Sun, 19 Jun 2022 20:42:14 -0400 Message-Id: <20220620004233.3805-16-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 feaca085cd..5e96ab24f5 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.1 From nobody Mon Apr 27 01:52:50 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 6B53BC433EF for ; Mon, 20 Jun 2022 00:44:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238060AbiFTAoM (ORCPT ); Sun, 19 Jun 2022 20:44:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44278 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238050AbiFTAn1 (ORCPT ); Sun, 19 Jun 2022 20:43:27 -0400 Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 25062656A for ; Sun, 19 Jun 2022 17:43:13 -0700 (PDT) Received: by mail-qv1-xf2f.google.com with SMTP id 89so14069525qvc.0 for ; Sun, 19 Jun 2022 17:43: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=rD78V5jn1N8Qdh8WX66Tgx5067gCW12nmDhtWQN/Hb4=; b=PEHIi110xCak8AXVWGSSap54Pb3USEO9D47CylrpBEx4MJ3ouTQwqPgT4GZ9rVlhyB SnTRPhdrnXptGBWT1LHKZwuf13+w6RjNidTCElH8Ll7be4wSPEz4Q7qPFqVtyaM3iXXB RavwfM25FtdagApCSwiOkPh510cx1/eNb/Uj3cIg7zudX2l2BOxIkuy8Do6PbgPQyl8B SQk6KMTD316/9v7azqlhz/9mosPw+vcMplfWWWfHYjviLJDMN3pbml1uhRgjULpzLaQN NbO5+f/zzkzL7xhb82vHwNj2pAXwCY2vPRDXQwAduqdvb9bj/93NYmeFfSOFtGbY0Lu4 22qQ== 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=rD78V5jn1N8Qdh8WX66Tgx5067gCW12nmDhtWQN/Hb4=; b=YQWcHE3NCueAYbePQVXAg2BnMLJM2nMgIRsmb5Je0vmnmpa4gAabcJL/qmjto4wkhP T6wdStHCCVa9/s6h9KkA/tQfdcKwd10owEBsdv4fXrFym98qYzXzxKgBy47t4qbbWCQo xrd3JbmlIgSvv8LvbjGd6NVXaA7I4PJssgaIZbCA1zv91C30YbEey996dHTN7OddAXTF Hf6aTH1e+klGvNabtS0qgq+d31f/xemANl6N8AEYgJlHIDsSC+sgN0QXoz82e8he0rkd fNfwaqCsLL29XFclkGl2pq5G1ufkCqVtjkxb85XWML5k9gtLIpzJKT0oN+sSEs06NWzi DYLQ== X-Gm-Message-State: AJIora+eG3Xps7pQRkTBpLS75qnjUmj0fT2Pd6jLCcjWhdvAATUOM96y 6DEshZ2Kbj20fnxEIU1FwlOH4/iT2qtOqB8= X-Google-Smtp-Source: AGRyM1ukasHrNUoaju59Y3ImRLnZitdczZF1RrTQDLGOqeCLU/+h7uKC/COyy1yeyTenIYYSYX31Fg== X-Received: by 2002:a05:622a:11d4:b0:305:222d:8469 with SMTP id n20-20020a05622a11d400b00305222d8469mr17545019qtk.324.1655685791162; Sun, 19 Jun 2022 17:43:11 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id d14-20020a05620a240e00b006a6b6638a59sm11167409qkn.53.2022.06.19.17.43.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:10 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 16/34] vsprintf: Refactor fourcc_string() Date: Sun, 19 Jun 2022 20:42:15 -0400 Message-Id: <20220620004233.3805-17-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 5e96ab24f5..55a42ae055 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.1 From nobody Mon Apr 27 01:52:50 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 1814BC43334 for ; Mon, 20 Jun 2022 00:44:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238075AbiFTAoP (ORCPT ); Sun, 19 Jun 2022 20:44:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238067AbiFTAn1 (ORCPT ); Sun, 19 Jun 2022 20:43:27 -0400 Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0181865A9 for ; Sun, 19 Jun 2022 17:43:15 -0700 (PDT) Received: by mail-qv1-xf2f.google.com with SMTP id t16so9021661qvh.1 for ; Sun, 19 Jun 2022 17:43: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=zAaaB7BPzM5EIrGQgkWN70MkkmVNwbYet4dekg796sA=; b=MoZI9+GQspHo00TU3bi0nZhx+5j2QBc5KmRJtrnf6gLeKNidHTro+4EoEVgJQJBFWp lQ/bnhZe7nogMNTLRD4V3MHqOpCVve7WX7atjsPhA9BPyjIASo0B2Fgf5xzQLCSc6OJj heVAk+50nn9u47fdgRWUwTc+8kkiFW24+z4/61YnBxiW7BxqDeMLFUGu7EsrYlSpSxzY kpLNm1zEs4j5zGK4GOxaUg+ClQmx8nQxexM254kfG+WGP7R9hlor/zdG4AjfurOkWvxl ZU4kbXD5zOl5J2EirQTk6+XmlUnljt8HWEW1r37z3Wja+Wi8Fk4zGIIRR0KhphVFXZjN 7C1Q== 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=zAaaB7BPzM5EIrGQgkWN70MkkmVNwbYet4dekg796sA=; b=2EsgUXT6lj/F+R+2/1H6Mfmads19TpWrvR7y8CYZwy7HR2lCltzr4XguGU6aWgSn6e v+l9UCO8xfjpAzcQLNEp/eP6qSgVBbh1EagJV83DnMhf1xaA41s7wUO61kB4svTrZ1Us 0Vub30PzNh+avV82oAOV271lINUbcbzV12DIDN60MOiVCqtkPy6vfOabJ3zF0sXKFG2S ryWOW92kk+406hsQkZ/ces1+wd98H3cP4vbUUdYZsZgTrhmP58PitR2+dn8gfa8Xt2SP th19AiZxD2sE0HYGj1ULBs+LoTaKW2iD9xUohP5lBRnNM7tWWaZNvpXVKvVlj/APV+If 0cGg== X-Gm-Message-State: AJIora+xhGJs3UsAMVs8IowPUmc6rVBW5DTTlSxci8bZUOBsGbAmHdyx 3rKC00iTI6O9815ihBCeje18NJGQIIO5JJw= X-Google-Smtp-Source: AGRyM1sjMbmVVjnL+wojUunsiX2UzDwVWpxKDcnMKNTZnQ/JsgUszLITOuijL19jbO916YwEf2WMHg== X-Received: by 2002:a05:6214:4016:b0:470:45d8:3be5 with SMTP id kd22-20020a056214401600b0047045d83be5mr1400880qvb.126.1655685793530; Sun, 19 Jun 2022 17:43:13 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id s3-20020a05620a29c300b006a79aa0c8b1sm11393436qkp.113.2022.06.19.17.43.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:12 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 17/34] vsprintf: Refactor ip_addr_string() Date: Sun, 19 Jun 2022 20:42:16 -0400 Message-Id: <20220620004233.3805-18-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 55a42ae055..5c9a529415 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.1 From nobody Mon Apr 27 01:52:50 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 42FC5C43334 for ; Mon, 20 Jun 2022 00:44:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236587AbiFTAoS (ORCPT ); Sun, 19 Jun 2022 20:44:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43676 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238119AbiFTAn2 (ORCPT ); Sun, 19 Jun 2022 20:43:28 -0400 Received: from mail-qv1-xf33.google.com (mail-qv1-xf33.google.com [IPv6:2607:f8b0:4864:20::f33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95FD7B4B2 for ; Sun, 19 Jun 2022 17:43:17 -0700 (PDT) Received: by mail-qv1-xf33.google.com with SMTP id t16so9021718qvh.1 for ; Sun, 19 Jun 2022 17:43: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=ts7V5k9ar980hnXI+/jYl6A3OMW+Txe0RmaID5nDbjU=; b=c4/Q7W5X+EjmJys3owsRTWii+P0aglll0Gr2oy623S3gzsOHRLzXVseBghxCBofAY4 bSju/DjO3Hj+RUrvorRKDtZx4aIStaGIJe6TuxKU6H1ptG6rRgDIOb/cjeqQSwC6OpEG 3dhtBbodhxXzjN7J9BnQmwDbFS+q+OoROzmbQnWpt6iugmrkW/ps0yVlaMxZUC9f2D8f Ej2h9h0xw/gog+GRFjrcwFCjxlzau0N4gwVmxa0XV+mJAvZmZqowTlEWJ4Kw+yp2hsMP HL5eWRol5yzVwYB/crpyUw651XMULnk8P5d0dtKsqbw763qemfxyyKt7x7gQKdR7tRoy Qvxw== 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=ts7V5k9ar980hnXI+/jYl6A3OMW+Txe0RmaID5nDbjU=; b=Shm8UHv1XP/k3NRt/N796tvtw4QbMLC63T3onulnaM/MROB+Sj2aq9pLGT8ZK2tTM4 VLFLB89AuNbNiNQwp+syz1S3VLB93MfHJAm8xt+TThnITM0y2t0d9VnTKzHvTazt89/D kngKIue7w317BQOanEvUojYijsU4YTwIN6yXLnvDlF0uFOMfOJfnwuy5g12MummLANFo Ar/bXG6SrhAXipgUdANzKF79/wdA/1keV0Q1a7x7K9O4EYhJbOaZ5BGsw4fExc/4I2eH x3YvoqDqkpzWifPWnt3TRiPdS/tux6HJG+5lbuSRYQxJ3AJ0uO+B/z/8hX88dvLc3BXC sQsg== X-Gm-Message-State: AJIora+xru7/xuiOoH9sU0WusnVbSQttUe5grh3/BEk3/jy++NhtYB6e eol1bw8Np2l07bodHBK+HDdOnf6KGi/i+iM= X-Google-Smtp-Source: AGRyM1vy+CGWiExOc4qKH9vFswZkD8+gTh0kn7nLEz2j5++2CQxb8nvp8M3iPA/mUyRpEL/aS71JyA== X-Received: by 2002:a05:622a:1109:b0:305:20de:4d21 with SMTP id e9-20020a05622a110900b0030520de4d21mr17807588qty.197.1655685795836; Sun, 19 Jun 2022 17:43:15 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id t10-20020a37ea0a000000b006a8b6848556sm10841259qkj.7.2022.06.19.17.43.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:15 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 18/34] vsprintf: Refactor mac_address_string() Date: Sun, 19 Jun 2022 20:42:17 -0400 Message-Id: <20220620004233.3805-19-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 5c9a529415..486c09b4ad 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.1 From nobody Mon Apr 27 01:52:50 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 91F95C43334 for ; Mon, 20 Jun 2022 00:44:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238289AbiFTAoe (ORCPT ); Sun, 19 Jun 2022 20:44:34 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43750 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238140AbiFTAn3 (ORCPT ); Sun, 19 Jun 2022 20:43:29 -0400 Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 037DEBC1F for ; Sun, 19 Jun 2022 17:43:20 -0700 (PDT) Received: by mail-qk1-x72b.google.com with SMTP id d23so6897371qke.0 for ; Sun, 19 Jun 2022 17:43: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=7klV3vdNzn8/A87P4NR4f70XoVa4SM0sCvYSYAJUFs4=; b=Z3bzbCoaTUPOIlSJfmP24rQbW9QXTC2u/4OSlp5WsFbVg32IAjNFiVf7vpfBvUqED4 mX8ohRYUETDXPDKpqRWJq7h06hM1H/joHmCP/Qep7+Wg6RJl6T9s9cdHAUy5u2/p4kTQ 6bIFpx6gCBuCrJH8WVnm2K9eTM8FDhQmf1VcfWCVWmTq/q35S+TCxwaSPKAEeeJbpEP2 Rb6I7WqUrcsXBBKUfvKm54t/KKbYLsPivsXZ3Cewri90jbqHE93VSRyzNXSeTx9hEGMU XwFh/U+CohoHOqHWVCXT/0u8g1+SvDXxnM4d2sIsFmG6NEw6Qt0o8Ar2OC8dbDIubw5h Hmkw== 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=7klV3vdNzn8/A87P4NR4f70XoVa4SM0sCvYSYAJUFs4=; b=ZxyXdAnHzkCF+zKt97gdb31N6Jj3/vs3grU1alWST4X+wwicCYDN+FK4UPz6V016Hd QFAzB67UchmbdC0yYjNEc846VF10vPKzleE55W3UzgWT4x9AtE8B7h+y11YjKyVVO4os 54ox5JMw66FXQNdh3vwZzlyxyX7v35a1/2cbuR3jZ00ikzUhjbA9J/ps0aIOyZY2OPfC r2ARZJYKnCO+EInp7439n5XFRxAZx6zdKu2TbxH4ga+vCX188UH6eiM0UZac3XILrDWB ZsWMtWUaASHOlz1rf03ALuAFsPMrKVO9fJBItcSoNhluUi5B0Hz/hRxQ05yloNCOylul gztg== X-Gm-Message-State: AJIora9XZ+j7wqSxP2HBBJM6EiHwCg9+lARMc3IJIh0yH9923t2nborQ QVWe85HPS3T42dEhs20k4H5o89NfkEWLAw0= X-Google-Smtp-Source: AGRyM1umLaPAf/akasIsSgksCEhoGwYZ3ZODEavmbk0rCbtNu+YACEOmp4mlkvsk1Aepg/nAjndhmg== X-Received: by 2002:ae9:e70d:0:b0:6ab:94ad:fe23 with SMTP id m13-20020ae9e70d000000b006ab94adfe23mr9066959qka.739.1655685799180; Sun, 19 Jun 2022 17:43:19 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id s7-20020a05620a254700b006a6ab8f761csm11425215qko.62.2022.06.19.17.43.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:17 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 19/34] vsprintf: time_and_date() no longer takes printf_spec Date: Sun, 19 Jun 2022 20:42:18 -0400 Message-Id: <20220620004233.3805-20-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 486c09b4ad..affe2b0bcc 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.1 From nobody Mon Apr 27 01:52:50 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 A1A18C43334 for ; Mon, 20 Jun 2022 00:44:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238228AbiFTAo2 (ORCPT ); Sun, 19 Jun 2022 20:44:28 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43870 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238152AbiFTAn3 (ORCPT ); Sun, 19 Jun 2022 20:43:29 -0400 Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9E004BC28 for ; Sun, 19 Jun 2022 17:43:22 -0700 (PDT) Received: by mail-qv1-xf35.google.com with SMTP id cu16so13426196qvb.7 for ; Sun, 19 Jun 2022 17:43:22 -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=oFSr89aEU92gWcunlU5vS2f7TnOlgJfvUBwY+HXlWFw=; b=cgxYlVJ4GLr3WkdItoWKiuQPJXd0/Yj+V7c1QPL/3/kcDcVxN2pyVSRSVKCySEDzli BNYCNb17DVymCnCJL362udOhu/AJAbK9iwMjJuy9M9l+18C16sPzNhw3Tco8nWT3Qu7W vMhLiaOq69smKx8migXhSCfkKo6rlhgmyYvB1Mvx2m3CAcHjCiiHi1tOoLHuBZS2FaTZ 73/zfoNTLVn4p5wG5pTLFURCPiku9Qa75shYPRR3B+Gq0OXW3D54CnGhCFQA0KxQIELo zNFaycSH2cHnwvWQteHgtf2UnrkymMkegc2Qr3q6snyK1xQjVN0RIbwRRzORQ/SJG8AM AUUA== 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=oFSr89aEU92gWcunlU5vS2f7TnOlgJfvUBwY+HXlWFw=; b=z+IaC8L2nVjUwv4gre2MIDMuctWKx4LOYbNYM+Wm9SHnXO+V25p4qFWQJ+hd2XSNA3 9shf+hw17l0YCmgjKFzfHhThl4hPuzcFVFbsTbTrVCXbGs0hHYGq99x4jekrcZkHaX8h 6KFLc6jim1AF2fSIeQHU11T7AhyQv+qBhqrKgp6n/ulp829+y9f5UgjMLeV4GEeTTs/H 1d269igLOoK3VtQn2MENT5zEhjzjK6tNz2XUe09oVILemnYibim2Px93ZRDT1HGHUi1Z 3Ud4UEInnFfgx3bQuZQ/mHAGOiOrDVF+xD6mflIpmzjUoFVxWbjQJ5Xkse1nsItD3bQf vnUQ== X-Gm-Message-State: AJIora/dgEpoQhco/JPjpaCz8XiniXHcHpdQKHL/i8QSWVU1e3hTgfms 0wwgMcQsnmrcJOMAXWjEMSl6ZS7Ab9MYiBU= X-Google-Smtp-Source: AGRyM1uM1OOd6wF+UQ3AdfkXj7CcsIPtdmf+wpKlLPB24tvyPh8HWTFZTJz/0aRTR4yVX2WPdDwz8w== X-Received: by 2002:ac8:5a01:0:b0:305:205e:5b61 with SMTP id n1-20020ac85a01000000b00305205e5b61mr17841821qta.218.1655685801680; Sun, 19 Jun 2022 17:43:21 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id g2-20020ac80702000000b00304f79b2bcfsm9626734qth.49.2022.06.19.17.43.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:20 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 20/34] vsprintf: flags_string() no longer takes printf_spec Date: Sun, 19 Jun 2022 20:42:19 -0400 Message-Id: <20220620004233.3805-21-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 affe2b0bcc..3900f7a1a5 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.1 From nobody Mon Apr 27 01:52:50 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 34FFEC433EF for ; Mon, 20 Jun 2022 00:44:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238329AbiFTAoi (ORCPT ); Sun, 19 Jun 2022 20:44:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43720 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238252AbiFTAno (ORCPT ); Sun, 19 Jun 2022 20:43:44 -0400 Received: from mail-qv1-xf2f.google.com (mail-qv1-xf2f.google.com [IPv6:2607:f8b0:4864:20::f2f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 10FB4BC82 for ; Sun, 19 Jun 2022 17:43:25 -0700 (PDT) Received: by mail-qv1-xf2f.google.com with SMTP id 89so14069525qvc.0 for ; Sun, 19 Jun 2022 17:43:25 -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=HWerF38n5tR4uSTYJFoRyRIOxNHFK081RFLAVt0+9RY=; b=gdle2QPYdF/YDxgrZ9pCDc5ZojhpY5013lioWippA7pS5CQtIdOHGV0VF6XVa7t8ur E4yDb9mwxMBv1FoxU33la1kQe+PkFQh+p4f404l5zrxKPcn7TqNGt2UAOeSLXL4sc9KE XTUgUbfGvRPlBJCKZYScvl0eybu5/QUXFImffx6qGE9NmZz830DBTO+DCBDXTRmWC66O Po1GeL6X5PVq6XXZ61vXr/ublbiswEFasOtyLVMIwXoK2hTpb15WdTu9/fuuVMnZPaUo mZWzHxOUGkR4pdoohQxvviHKsTD8mB0XpzPBuVFY+tNQg5HNEefdc4RGvWTO+Uq850ej 9HWw== 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=HWerF38n5tR4uSTYJFoRyRIOxNHFK081RFLAVt0+9RY=; b=1BHKAF43yuGg/dHbkN1DM+q9sFSWzWSzf/9n3CCgERZdlTvgByxdsvuNh1N+QU9xHy TS6ZLIzErnm74t2qDkurIg1Gw6jHlZk3g5P7CaNe1rbQMdY/6dN9hqTHKBFnWJKuRlO7 yAZjYGqQkd3U4rRLJIUMYt1OQDxBqYVNRcJcq0gkWEwcQW0Y0viRyEQtYkvu3h/dlca/ DB+MKQy92gMZjJGYnZKZJJVglmCLjYGV1wKnuD4U0kBUnW+MMz/Qk+JpwHqFuStdtRDq Fw3Gfpk+UdMW5HTN9gS5RT9GU3E2wtWkntk5+ksB70mKhydJr0yFMNfagRTMU4iGopkW C6gQ== X-Gm-Message-State: AJIora8EIUXJuZNqtUugcd4KvUXM8Tn22CgnGQayfCQDrddA+5cei4N9 yTZ6XePJCtq7/YMJ4NkbBV1JW0zzYghC2Oo= X-Google-Smtp-Source: AGRyM1sqZc0tCgtuhT0Syhi5cozDr+xp4LtE9SWos2+SZBuOvssoygcA8ICZRj2oL8lN6sg+wRIGtw== X-Received: by 2002:a05:6214:62a:b0:46e:5f25:56b6 with SMTP id a10-20020a056214062a00b0046e5f2556b6mr17206265qvx.12.1655685803670; Sun, 19 Jun 2022 17:43:23 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id bi20-20020a05620a319400b006a6dcd92eb3sm10291756qkb.121.2022.06.19.17.43.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:23 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 21/34] vsprintf: Refactor device_node_string, fwnode_string Date: Sun, 19 Jun 2022 20:42:20 -0400 Message-Id: <20220620004233.3805-22-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 3900f7a1a5..7f47533ed8 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.1 From nobody Mon Apr 27 01:52:50 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 EF339C433EF for ; Mon, 20 Jun 2022 00:44:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238364AbiFTAon (ORCPT ); Sun, 19 Jun 2022 20:44:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44020 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238307AbiFTAnp (ORCPT ); Sun, 19 Jun 2022 20:43:45 -0400 Received: from mail-qv1-xf29.google.com (mail-qv1-xf29.google.com [IPv6:2607:f8b0:4864:20::f29]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 559CAB7D2 for ; Sun, 19 Jun 2022 17:43:27 -0700 (PDT) Received: by mail-qv1-xf29.google.com with SMTP id n15so10002237qvh.12 for ; Sun, 19 Jun 2022 17:43:27 -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=Q+ZrKVYsWw5cNOUTh5FoAEVyiDPKL3entVW3ZPKBcpU=; b=OHgAtZQ6ySjldVX8pc24fFfTjF1EAs15UPJBeLpGxXUzTKVvwzSqiTAMWWCyezmzma LpF8Kk9CW5tO43zGl4/vNaPHh4F2mclGiGwK3o56ye7Zf97BNQibXKpPr5MRaPnuY9WQ /dGJQZUr1hqXx4FnlguF6bxSv9kXjJUexI0hs01sASvB9AT3LanNwaS+zPprVHzs8UNe kL/NLo1MZ/xoA+rKm9jXFvHwNBz6oMdZfiYID/39uymh7POHtj/Fww7LVD5zD4jasWs7 ZMKSK7iYjrYHjuuSYMrhqXvTzuQa6mvVMGngb/914V3hrnHfHsNO2L+UoRa9DAuUCKCx Xsrw== 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=Q+ZrKVYsWw5cNOUTh5FoAEVyiDPKL3entVW3ZPKBcpU=; b=y0maavtLmBiOWMDdmZtEnTVon+aFJLjvJsAcgyPHtw0mVSOUOd9FGwhBqVg38z1HDk 4sQ1JD3nM089dH9PeNbVypQX2Of0dA2FxRIIT48WM3HUh99gmTENV4yLOr5g1d2Jrr9C y8s2ADsEPCWWBU034eDcKGNo6O0qbg8ZDwXro8RdlV4ZVad5N5lnIUgBkUHmeb57Q+md RFS1lEPeIGEHcjsJDAdGg+i1jEHgwaLQq69tk8kDqSJWVbwEyraNtyD2yBl9Gf1IOwLw Zhu0F/VEIWMfNG0sTFpB2qA/DlTCm6oJhp0rTvtnZo5cXnx36QCbVTQIYhx1Jaqj9P8C K+UA== X-Gm-Message-State: AJIora/j3oV7O+F1acm6Rk+RMOm9R0++VBmEpVlnr67MJZ6NIhJSG+8K mCAbF7SwnG0C8clRCcTME4BPzq63BlGUQfY= X-Google-Smtp-Source: AGRyM1uQlGT66NzFCddbaTYNbzmbaqITcI52TERSTBxYTP606LkGhInp1bFsIHt/1tjHVOrOlnCSww== X-Received: by 2002:a0c:f5c1:0:b0:470:47b1:7ca8 with SMTP id q1-20020a0cf5c1000000b0047047b17ca8mr127311qvm.35.1655685805997; Sun, 19 Jun 2022 17:43:25 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id j2-20020ac85c42000000b00304df6f73f0sm10699866qtj.0.2022.06.19.17.43.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:25 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 22/34] vsprintf: Refactor hex_string, bitmap_string_list, bitmap_string Date: Sun, 19 Jun 2022 20:42:21 -0400 Message-Id: <20220620004233.3805-23-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 7f47533ed8..fcdf187b21 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.1 From nobody Mon Apr 27 01:52:50 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 B1EB2C433EF for ; Mon, 20 Jun 2022 00:44:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238384AbiFTAop (ORCPT ); Sun, 19 Jun 2022 20:44:45 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238351AbiFTAnq (ORCPT ); Sun, 19 Jun 2022 20:43:46 -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 05DC6B7D8 for ; Sun, 19 Jun 2022 17:43:30 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id c144so6864144qkg.11 for ; Sun, 19 Jun 2022 17:43:29 -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=oHZ6nQT/N9bLil/etCt1wSEx4xhnhUtuxCNLNmvznXY=; b=S9XptWh8DqC+66cgLZqvqnxt6sGYteRfU4WLgKm4FNZ10hcJXl3XfADdQTOVFiFzSz g2sKvhZHX5aF0c6SSfjPkhOt3+ZQmjDPvT6/7sEIBw7MBAy0F1W+LYUZXPDTAL+E6//y N47O9ZxAj/+D0i5xhCQeW9QoS9wbJmSXkIk4TedVlQepn6nf4x7bG/IaN6GWv+v+5Ot2 jTSYwCujqxHC4+Ln4Uyecczl4f/4FsdrMtsZAiv/Mfp0wTEH2BkwUpT904cAi2PMzd4+ j5RHs9XmNNnMrGU/lRUtAkx/NPoQdv7d9u63cb33KjqgG7qqkvQFaGNkqs/98/s04ZUs ZEvg== 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=oHZ6nQT/N9bLil/etCt1wSEx4xhnhUtuxCNLNmvznXY=; b=XHpzahXDCXEPyNiRGc8dfwdsYnkEqI4oEE9hYKI1xJfYTkC3v3Tf+c20QUT3U0bSzy x2abRT+mbbJN7dm0lSEDRxwBed/aQldCcRd+i4eQiEWWMYrMeFhAIDaDSKTPv04wCkcT xygYAxeHpVFW++Qm1ESUeAROr1t9PsufXleZb3VD7oJQTGFnJqZUwRqSMCdpgtg3p7v5 AnDVTmn4z2eigHoqkcHObs6bX41/wxTt1/3vhK8bHrhblBk00RQJ0Zbk56uWcVRaECEg YYvDdTcL3u+cBNPLdxb19JFeQ0wz6lLARgq+PcSFTKvn2Rx68t7GPKfbGheZ8YWSUwXe Hw4g== X-Gm-Message-State: AJIora94MeWDsYkTd7x0BVpkIMRFLDThm0iOQQAqNMhZMbjKK9+xnnqx g5oQ7+ZxJpPcKH2pHHJ9jjpoSyoot+yoXa4= X-Google-Smtp-Source: AGRyM1skuA5LbWzNEHZ7Lk4CN7aJYyltI0ZJ+LVvNJE8kd9aywds6JcebeSrNRYxQ5JcxvYG8liLvw== X-Received: by 2002:a05:620a:130d:b0:6a6:bb03:d8ab with SMTP id o13-20020a05620a130d00b006a6bb03d8abmr14522452qkj.133.1655685808583; Sun, 19 Jun 2022 17:43:28 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id l27-20020ac84cdb000000b003051ea4e7f6sm9828308qtv.48.2022.06.19.17.43.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:27 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 23/34] Input/joystick/analog: Convert from seq_buf -> printbuf Date: Sun, 19 Jun 2022 20:42:22 -0400 Message-Id: <20220620004233.3805-24-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1 From nobody Mon Apr 27 01:52:50 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 40464C433EF for ; Mon, 20 Jun 2022 00:44:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238445AbiFTAou (ORCPT ); Sun, 19 Jun 2022 20:44:50 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238363AbiFTAnr (ORCPT ); Sun, 19 Jun 2022 20:43:47 -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 30959B7FC for ; Sun, 19 Jun 2022 17:43:32 -0700 (PDT) Received: by mail-qk1-x736.google.com with SMTP id 15so6879985qki.6 for ; Sun, 19 Jun 2022 17:43:32 -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=NyLJo+KoIiEhpVGAQ2QxyVkabvxhAF2JfmbYzoDAQFQ=; b=ZwMhY+29YOmX0RvGbQvKKpPUJ/LqiQlfG/fgzGyHH2KruyCzuGFG7Cx9DBTnJkvwbK gAaCicWiyizg4Ns7w9SJIH9poWXfXv4BSJRB8E3LDl9mvltSXu+AiBCzfX/xNZFzqIjQ v8SpfIbUg2ZXZgRZ48WZbDJ4lNh+p6rokBEkhGJAC1sQYvtHz9gEd0+35p9o8Bt+BNE1 pZmzrLUxry5FvQMPKjEHsa+YCN8WwrOA/Rhd1OQ5cJCvVgyG64UUWUMsgq1X6/YcQeP2 5fmQ5xebpkhNfdNLRNu2ImCzxKO2l/tZuPB9FyaW/6ikTd+q6pzU6aFO9/E7fP4o/7/M tMxA== 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=NyLJo+KoIiEhpVGAQ2QxyVkabvxhAF2JfmbYzoDAQFQ=; b=W6ReSAzmCDYTFpS0wdjL1z2F5SdzOkyhWSAr/AxZ7SA9Gvr8uIWA3SNPxqzA+pBU7R hTrNJd2FoOBpo1SAPCFjbmWa0Xp0Wk7kRBqp9lNRkKgtSLwWs5erQ0Gr9FDMShNIA3NL /vpcmOYZSHMHD7sUlxWpLv7+txNFtCwtmtZoKgKfBwIa7RuZMguvIiuqsI2ZywdnaN+q 64AOHSaUP+8/k0EP+OaK6MZWYJxeWgBnpsn0EHpWvpkTVFhRDGDFMijwfxr6tiVxtm5w uXQ4O0qeRdoCkW3x5KOCY7AjvSMTZTymovTCNmVR0CMqT1Ebg9eV33GWqwZ5riemdGEB k65Q== X-Gm-Message-State: AJIora8WN78bhsV+fRZD0E9+iu8L/B3TBS78S8fTR/uz2FVI8QVDYudN DcSvjSieh4O/SdSQiht9v0PYC1sW6UG2x7Y= X-Google-Smtp-Source: AGRyM1uaH48yIvoz9xPy//ybN6M0Bpovt4qpzmAy41Tiev9BddZLDAZCbKgQyHBrnnXmG62fhuA/aw== X-Received: by 2002:ae9:ef47:0:b0:6a6:809a:aab5 with SMTP id d68-20020ae9ef47000000b006a6809aaab5mr14526624qkg.615.1655685810646; Sun, 19 Jun 2022 17:43:30 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id g10-20020a05620a40ca00b006a791a42693sm11091058qko.133.2022.06.19.17.43.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:29 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 24/34] mm/memcontrol.c: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:23 -0400 Message-Id: <20220620004233.3805-25-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1 From nobody Mon Apr 27 01:52:50 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 D8823C433EF for ; Mon, 20 Jun 2022 00:44:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237724AbiFTAox (ORCPT ); Sun, 19 Jun 2022 20:44:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44298 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238382AbiFTAnt (ORCPT ); Sun, 19 Jun 2022 20:43:49 -0400 Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 42F226582 for ; Sun, 19 Jun 2022 17:43:34 -0700 (PDT) Received: by mail-qv1-xf35.google.com with SMTP id i17so7358941qvo.13 for ; Sun, 19 Jun 2022 17:43:34 -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=gsfcZAwqlEFdpq95DCanp3EHZzLLogwQwMtGGhdzNxc=; b=IJg+Op9gT+0zu+I1RSZ69r2h/io0Iax9HRwqmS4TNZwJTDJb7fQj026KZbjdqpzkeQ jl63+ujHD9wLMzImVc5A4YY4qI9U2LNA4I8nLz6Ol+iQOJjRrtaICS3bqCJLtm94lkMX HlRwKatR1EWzhIi0kVdHwo7ijnkdt45FIgHRrvgsVL5dZRFPVZofaM8mB83/j4l1Y5JR de2b8vrhPFqHXAhnsiNg9oAo1naki+8XE3L9tyvz45B1eG2U/C1sxsCrFe0K1ge80Tq2 QxqXh5GjwwdfbGbY3qllndBsStR188f/LqZMiittFETjyR0Ev3SqPq0l+ztbB3+OacT6 qoXw== 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=gsfcZAwqlEFdpq95DCanp3EHZzLLogwQwMtGGhdzNxc=; b=IqE3lEmqV2Ico727s9PVPjaUlb+vIlLINsABxqv4XCl9O39ybnOardIyKtE6EgBN+4 ljFC4383jm2S6BcnpfI1kxxqBMuROVI6gD/hnXlUk6JMrVcPf2UPOM62XOvumTAXMUUb t4Bh2RZTz4KU1EmGvQCKq/lN8RtiLUXqvtkE3kfyQnp2vMwkQ662M9BQ1NF6VKy33Vlh Br7ODgD+I0ErSyZcPTAWfvCVEjYWPBpa3gMd6EjgGTRs88YrhV2sgosTxOhC8MdVbYbB rK3QprrY66CqNB+aB2xnnsHaMQQjSO0GWyfvw+QsJpWqoUSD7+wf5zYPIEk6IPMLl5lA Q4og== X-Gm-Message-State: AJIora/Kj9SvXcciyGVs2ZZote98APs1NNoVOzAagUPmDl2+XvIz/iEn rV1goKjf14qcJgKOkrgwHRN/E9TP/wqYMEc= X-Google-Smtp-Source: AGRyM1tQ+0xDN5He/7+qn3hDH+zCCBLc6Ym4XEqTwDgs43uHcX8GDVZ/W0pK2YuJv48o6g71jadKkQ== X-Received: by 2002:a05:622a:493:b0:306:7794:a16 with SMTP id p19-20020a05622a049300b0030677940a16mr17925571qtx.605.1655685812910; Sun, 19 Jun 2022 17:43:32 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id b7-20020ac86787000000b002f93be3ccfdsm9462183qtp.18.2022.06.19.17.43.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:32 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 25/34] clk: tegra: bpmp: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:24 -0400 Message-Id: <20220620004233.3805-26-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1 From nobody Mon Apr 27 01:52:50 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 904FEC433EF for ; Mon, 20 Jun 2022 00:45:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238504AbiFTAo7 (ORCPT ); Sun, 19 Jun 2022 20:44:59 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44312 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238396AbiFTAnt (ORCPT ); Sun, 19 Jun 2022 20:43:49 -0400 Received: from mail-qk1-x72f.google.com (mail-qk1-x72f.google.com [IPv6:2607:f8b0:4864:20::72f]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8B2DFB85C for ; Sun, 19 Jun 2022 17:43:36 -0700 (PDT) Received: by mail-qk1-x72f.google.com with SMTP id n197so6891429qke.1 for ; Sun, 19 Jun 2022 17:43: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=c+8VrBQ9WReeZhxiPy4cLYIhVweEbjxzP+O3PD/upkI=; b=hG1zSXlqMLSt6C53e/b9Mbo0SIVK2m3R3jUS+uuyLNSYU7h0hemVP+PRCJbhYgLMX7 FyNfHr+aW+bfF+gBFHQVtjYmTqBlPCmff2HDumH0thLuIMmi+5xTZif5rFBJ+/Im7rAY 1iX2kT7GRCrIcIEadxyY1d1XK2xwI+VfWhMkRQQXdVqaQ1Fe0sWfvN1U4Bkz0s0EOCFP 8abRX4B1TCxLaNePhLqRU6tlIUx0JP4G+9qFcUhjmBSi/tOCHoHYoFp9xNjydTdju9/h wJokcyg3abuBPNvUSNp4Rqz/gHfQqlC/+laxZ12aplYKKmjtUIHJTaMhGSQZkwxGp0ta ffZA== 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=c+8VrBQ9WReeZhxiPy4cLYIhVweEbjxzP+O3PD/upkI=; b=JoE5hvaHUJOnponFisbxZakcA1E/2FNNrmNeZBpo+MQE1N05w6b7bOLX5nFJGEyvIX sR3Dsi+sZ+RBA5IiVsD6AjUWUElobFvxDxo6lo1ey+ImDZQsi00AzOn34yQ1LkizjHVx YWh9/MHSakC9OsPzy2V7siYpnXuoN4eN+FCM/OS0uazpQdMeS4xZ0XAEL5/iqHxbDJ/N e/H0E9/IBiiofMc6KiR1rq507fNm9TMsbeILS/Bix81RSjMCUqlojshauPgxyGM/DDjI 9MyBIKtITj4dtQp8vBVfzGzQACU9XrZOC+xEvAiP1KqyY2HrgL9x+OIrAopcKsP6zrTu 3OEA== X-Gm-Message-State: AJIora8xVICR4Px32s3s+GTqVoUNZ5g/qaXW75A1kA1vU6SUU/czdIh9 Duo3MXq61bNfeVzbPgd4gmzbNDZK+8vUwrQ= X-Google-Smtp-Source: AGRyM1sebw4W5sjFrt3VW++8K/4IO2JYqZAC0xgWvLT2GDMfU7O1Du2uxp+uMD8HWJJW0TKREzVJcA== X-Received: by 2002:a05:620a:f05:b0:6a9:7122:edb1 with SMTP id v5-20020a05620a0f0500b006a97122edb1mr14790338qkl.82.1655685814618; Sun, 19 Jun 2022 17:43:34 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id y17-20020a37f611000000b006a69f6793c5sm9944488qkj.14.2022.06.19.17.43.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:33 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org, Dan Williams , Dave Hansen , nvdimm@lists.linux.dev Subject: [PATCH v4 26/34] tools/testing/nvdimm: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:25 -0400 Message-Id: <20220620004233.3805-27-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 Acked-by: Dan Williams --- 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.1 From nobody Mon Apr 27 01:52:50 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 5F448C43334 for ; Mon, 20 Jun 2022 00:44:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237765AbiFTAo5 (ORCPT ); Sun, 19 Jun 2022 20:44:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43666 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238397AbiFTAnt (ORCPT ); Sun, 19 Jun 2022 20:43:49 -0400 Received: from mail-qk1-x72d.google.com (mail-qk1-x72d.google.com [IPv6:2607:f8b0:4864:20::72d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 70D44B488 for ; Sun, 19 Jun 2022 17:43:38 -0700 (PDT) Received: by mail-qk1-x72d.google.com with SMTP id g15so6878217qke.4 for ; Sun, 19 Jun 2022 17:43:38 -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=2nzGqFu+zHLzrMtmSIDmXnbGgXz0ZoUV2UNHlwfAYis=; b=qgc7SgH+16gmkiml4CM55Sc/NiPCmG43s+8mnXVuSjWJR+qnDFN+VRyjVt3jWNXz+V se4AYMrcDghbfK3vCuVrlw1rGNYR3WRWfgDjnemLQd0+xUmBohaKWSoVBJZi+/rVjb1d 4u7SFtvPGSO29vjhRjn59EWi45PR+z8JFRjlm2SxKUM6RecPMSBgyZr5R34ogtBtRwWQ uOqW0fGzirpaYNKRBxr/h+Em5z7d9t/dYT786nB/9Oc7Ak+lSGm8wf48t7mhOyYRUoL6 HeGuiN+ALvJLjx+E2jjO7li0VzB9YNWNLQSviSJInscDgOxRMqoegcFJBixRTnNEolTY d0cQ== 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=2nzGqFu+zHLzrMtmSIDmXnbGgXz0ZoUV2UNHlwfAYis=; b=R/Vs4Q3fP9pcBCPZxrtaHYRzMk0Wy2+lUlwG1sorrHYn5A2HbE3+/PuxnmijvsE7pw jVIiXp3yLZzagI68EhgArLUoBsLmwtQiUpKC5TXLec6Vtx+aZilaU1RNfmFXWe6YUhEB eZglGs/Orx9ZnKG7qUDzOV63pZ8j+7P2TsNd8MyO+8TuWLyhm3q5JU7Ho490rfhfW6fQ 5INi7kNWQXBBmhAXUverR5j4oapNYCcetcatRZEbfEjsjS0KlAgGUaRJdUAd/UNB3VJt 056Ch0k1q4hMMRSCEQYGqXP+XOes1EAH2ZwLI4HkMjQ7W3G4UNdwsrwS2tgptwHH+yuV KVJg== X-Gm-Message-State: AJIora9TaCJNOnvZxYIM+xNGyukgfNZ4wXEEDpscAMIAJqq6QkVlsq3A W/oomKYV3Pf5wUQ/ZgI8MWfwMNlO/452FNg= X-Google-Smtp-Source: AGRyM1t8MdXUx5SALS5SayNF2uuahMxKQ6ZwFtczQoVY1aB8OhLl5wSWuzDcjoh/34x6wWj9s8wVeA== X-Received: by 2002:a05:620a:4553:b0:6a6:fcb5:c2f9 with SMTP id u19-20020a05620a455300b006a6fcb5c2f9mr15185639qkp.299.1655685816923; Sun, 19 Jun 2022 17:43:36 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id j16-20020a05620a147000b006addb0af23asm1545655qkl.78.2022.06.19.17.43.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:36 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 27/34] powerpc: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:26 -0400 Message-Id: <20220620004233.3805-28-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1 From nobody Mon Apr 27 01:52:50 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 9A3ECC433EF for ; Mon, 20 Jun 2022 00:45:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237855AbiFTApC (ORCPT ); Sun, 19 Jun 2022 20:45:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238407AbiFTAnu (ORCPT ); Sun, 19 Jun 2022 20:43:50 -0400 Received: from mail-qv1-xf2b.google.com (mail-qv1-xf2b.google.com [IPv6:2607:f8b0:4864:20::f2b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2101B48B for ; Sun, 19 Jun 2022 17:43:39 -0700 (PDT) Received: by mail-qv1-xf2b.google.com with SMTP id cs6so9536748qvb.6 for ; Sun, 19 Jun 2022 17:43:39 -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=+Vdy/3q0z+zupAiyg6Yh4GOKkpWfVuARDkMzaW4uflk=; b=lBJ/nMwGEn+uWKxFE6E0xhdfP4zJLmfjV2Nrc5Ovw3Fi6FKL38hoxWIThEo3s2IhA9 FJeOSspstzISx+42nRSaO8wVE9bJg4lXJNahcHxa2GW4NFD8Nprgv81TdWCyNqgydSSV w8KSIKhlYbrHt1XFl5TwkpjD3sUFMh2VRYTtXn/H8IpMePgGHHVxwT14A08+bS7szPKo ybAZX1rthru7tk0HirpC5pKjoJMH5L2UKtPDX0+Q8otXr+EHMp8mcm5nuss2+P2AEVjA tK34nsw1diiQ5kkI2D0CvD85QpKnLH3mqDx2x7Z6cL01Dsy3vnz5FBqybvFZ1+zAeGzk F6fQ== 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=+Vdy/3q0z+zupAiyg6Yh4GOKkpWfVuARDkMzaW4uflk=; b=GmD14aoVTXwuuP9ijii/vSVQnNyZfQEntgE8SixQojsccMU9Webhr1AHKmZvtbAVlq PkdUcpXUpHpIZVeZa+bQMAZvnh+zOSDyWAeS3DY8pEt+RBEBzT8lFAEAI80aI8YSKzl0 xHTKs0H64M2JdLIvtVA365ch1AtwrLDyaq1lstG+cXQpmj9sjp7L4az75FJb+LGAUciT 9XKf6NSQmNqquqDjBdqBrB+gHcY9r4xyALGasMAfqk+7zopUewy6RQD7R+QLxJugtOjj zrihq8JwV6ueZZwl7hy3bPYenQys54h+PeEY7AwCy/tmOPAq7HC4/AGo35GHfsTeycJ/ mdMg== X-Gm-Message-State: AJIora9+akSXHpWDKhCf39ooChYTocYh3GUpk43Gr5abq2QjPZOjud+e DoRJkvIddOUt+BPZk2IuTPc8rskYmIhGApQ= X-Google-Smtp-Source: AGRyM1tS4spvl8xZaQS5aL6s94wW+yGTeZDkgIKbZLzYbzrC5075+0KCox5+j5QeYPUegh322eL+9g== X-Received: by 2002:a05:6214:21e5:b0:46d:82b5:b1a2 with SMTP id p5-20020a05621421e500b0046d82b5b1a2mr17234499qvj.116.1655685818521; Sun, 19 Jun 2022 17:43:38 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id z9-20020ac84549000000b0030515374a6asm9759352qtn.51.2022.06.19.17.43.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:37 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org, x86@kernel.org Subject: [PATCH v4 28/34] x86/resctrl: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:27 -0400 Message-Id: <20220620004233.3805-29-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1 From nobody Mon Apr 27 01:52:50 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 EE0BDC433EF for ; Mon, 20 Jun 2022 00:45:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238524AbiFTApF (ORCPT ); Sun, 19 Jun 2022 20:45:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43744 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238401AbiFTAnu (ORCPT ); Sun, 19 Jun 2022 20:43:50 -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 8C94DB847; Sun, 19 Jun 2022 17:43:42 -0700 (PDT) Received: by mail-qk1-x733.google.com with SMTP id p63so6869820qkd.10; Sun, 19 Jun 2022 17:43:42 -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=+Xg1dB8Y2o2fTfyU6/JMm3V6r0Q6Byu7YKRWwJ+H+P4=; b=YMEMmazsTJymTBZg5B+MMIRicoAxtJ7ZVBPY72BhCaDEL02Th5qRPhx4J9aamZdt2R AX6lCzjBTjorsmk12pbSZSnV0blpooWefBhQa6O2wBOTFFgCptAUNs6vG+zx+1sNT2Mw LsDQZlzhxIvqKfjVGHbfpXG9X53Bhl1mbztGVaEhDrq+vD3TvA+a3nopvnrSOryggHkf UClv9V+ds1nzIuGbf+Yfl6o/j7LxV6WRfVzHcH3rr6l+9uBQi3CPFh2zdLvJhef/dXM3 4QAWd9MFzvQ0BmraqaKTlWNuOtkOTVXJWKV3g7AsUDD1EU1RBhJcxlTykX8tjZ3KXK0p br0A== 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=+Xg1dB8Y2o2fTfyU6/JMm3V6r0Q6Byu7YKRWwJ+H+P4=; b=D5cCQjNK4ZV5k8u0E55GXNtDpdw5liqm3aZr0vlPyip/vRuHmojWMOnDwC6GCrdjNo P/om2v4/FDiuBwfmoLk62BfM2OYxKBkf65HEVx6NI0bD9kDhtcJ3ws7udogYnJ4zNzoV hL86EAYod9ZLg51vZvYfQRHZpKcpWj/Cg7pjwEubkmE2bjkh/gTyrjL3VPTnoSRtu158 ChPTL5F/3JA+f6yxIARZKh30ymqsuHrBoGENeVeIAnRlnVC0wG2EAuyiwQPTmgCvd4xs AUTW3y9Wds1fhy/wyT2nPUCeN7II93pC5PCXTWhi8DBpG6S64eGzVna+QixYWRixrNIa byXg== X-Gm-Message-State: AJIora/cv7gH4lAYu5q1i2OTnrQ30P1VDcj4O9/E4aS9rlEZ+yOFEQoc l7JApDkRx2td1O9l4qECjQzwr0UK0pyRNDQ= X-Google-Smtp-Source: AGRyM1uCfrheAlhgCp9i1EFrQVHXoukF22l+FI6Up40z4nZppqvuTPxoWyFhEbHIP29gGwI1wSisVA== X-Received: by 2002:a37:5e46:0:b0:6ab:90dc:d9d6 with SMTP id s67-20020a375e46000000b006ab90dcd9d6mr9561307qkb.131.1655685821224; Sun, 19 Jun 2022 17:43:41 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id ci6-20020a05622a260600b003051ce7812asm9739089qtb.5.2022.06.19.17.43.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:40 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org, linux-pci@vger.kernel.org Subject: [PATCH v4 29/34] PCI/P2PDMA: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:28 -0400 Message-Id: <20220620004233.3805-30-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/pci/p2pdma.c b/drivers/pci/p2pdma.c index 30b1df3c9d..3b7a6ca446 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 @@ -516,11 +511,11 @@ calc_map_type_and_dist(struct pci_dev *provider, stru= ct pci_dev *client, } =20 if (verbose) { - acs_list.buffer[acs_list.len-1] =3D 0; /* drop final semicolon */ + acs_list.buf[acs_list.pos-1] =3D 0; /* drop final semicolon */ pci_warn(client, "ACS redirect is set between the client and provider (%= s)\n", pci_name(provider)); pci_warn(client, "to disable ACS redirect for this path, add the kernel = parameter: pci=3Ddisable_acs_redir=3D%s\n", - acs_list.buffer); + acs_list.buf); } acs_redirects =3D true; =20 --=20 2.36.1 From nobody Mon Apr 27 01:52:50 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 4B07FC433EF for ; Mon, 20 Jun 2022 00:45:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238534AbiFTApK (ORCPT ); Sun, 19 Jun 2022 20:45:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43858 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238415AbiFTAnu (ORCPT ); Sun, 19 Jun 2022 20:43:50 -0400 Received: from mail-qv1-xf31.google.com (mail-qv1-xf31.google.com [IPv6:2607:f8b0:4864:20::f31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E9FBAC3C for ; Sun, 19 Jun 2022 17:43:44 -0700 (PDT) Received: by mail-qv1-xf31.google.com with SMTP id 88so10493708qva.9 for ; Sun, 19 Jun 2022 17:43:44 -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=fhCWzyYhHQUfgLaJoA4/luR9p1DQeXQQcw2AdhNu860=; b=LNOtI32q4WsSf62+lp4sxFsq0bvgPEpDH7tubWopigkHyJasJcMXtxp6uhe/k056YK mHTCf4zl7jPsNE7ZDlNYCWbiEDRe7d2d6hBWTTvbyfN8QNhTuGyfoiOgpVBh5jbwxYNb wN4IEHaZ5JKnXGFqcxJcgQ356aOF+2/EiAu4mYPbQ0G9LRzp2dF14oqFlIfb+GgMCboF /svbE10GemkPJ/8PCTtYi25sf4XvEi7xd2lfrcq3Sikn1ZC55Ns7T+T4SJUvkWF/Xl6a pBoPIuzg4YVajlJR0+oHaAKlw9vN0nVxPk56KJucHUH+c7dt8C7G5JCpd/2Psqi2xQZ3 7pBA== 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=fhCWzyYhHQUfgLaJoA4/luR9p1DQeXQQcw2AdhNu860=; b=z96r/GoEqttVBg+D2vPEmJNY2HAKK7gvszh9TtNcksD3b3rGedcnUprBDdt7rePmHt pEB52qvzKvCt2OeanmObN9B7/AeIzZ1IwHL8oCudNCFeH5iFmM/KrqVeCPUerUMI8R0S kHpK+kgGHBvLg0tDuz/NmedaO6mX3Pz0FjRg13fIfxTH4yeIFaqwskNStqrHTkFTKr9J qxSwXWy+UYZBZ/WHEwgh8SwKuQ7MXmS5f0jYoXPIlFqgcknT+1FFP0gyb+3Zy/BoyNNN m9Fqkro0zRHpG63Lil8B/qxZeGfRKWZHbcfo6yF/Je9nm/U2rgM+CxFHP/kLTP+lT00c e6Nw== X-Gm-Message-State: AJIora+oujuytRowK/3NeG+bkRnVS2DJa5HAFjde09O9L3T75BC4QZtH 4faD/d5fEfvtHt7vG/Ir2CTzLpGXEaEKW0I= X-Google-Smtp-Source: AGRyM1uK4SE0R2rC8ICXr/1qyDRW063L27/c5mYvQJDhXdbWpPTz/vsIaae7XwlBInXy3JqUohNKFQ== X-Received: by 2002:a05:6214:23c8:b0:45f:b582:346e with SMTP id hr8-20020a05621423c800b0045fb582346emr17516453qvb.109.1655685823664; Sun, 19 Jun 2022 17:43:43 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id b198-20020a3767cf000000b0069fc13ce1f3sm10580202qkc.36.2022.06.19.17.43.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:42 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org, Ingo Molnar Subject: [PATCH v4 30/34] tracing: trace_events_synth: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:29 -0400 Message-Id: <20220620004233.3805-31-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1 From nobody Mon Apr 27 01:52:50 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 9021DC433EF for ; Mon, 20 Jun 2022 00:45:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238561AbiFTApN (ORCPT ); Sun, 19 Jun 2022 20:45:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43860 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238418AbiFTAnv (ORCPT ); Sun, 19 Jun 2022 20:43:51 -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 8949325F for ; Sun, 19 Jun 2022 17:43:47 -0700 (PDT) Received: by mail-qk1-x72c.google.com with SMTP id c83so6889035qke.3 for ; Sun, 19 Jun 2022 17:43: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=X/vHm1f3WoFXRt6JUj3SilR7opGdtbcYgwZ9r1atlS8=; b=merDOSNMLYB6urSNHfDzTPlO9cTnNP2/a+Co95AIL+tp45UY1ESEm0GqSiRzYXGjPq lKJyO17f8asxDNlFx3YoHH74RPB12Y1OXa3miHqcxl3nepJtQLBUO9Vv5UHdySoFPh8K PGKEHVHhgt9ZYBn4DvdxjpTQB5GqGkaI+LQAnRZWVQ8SX7TbDJNlwW2CW67lMlBrQaqM fHJMTDRHSDe1GvdIBQNm34YtHj7FhTmUjvYWB9DPu2p8WHbZTwICJGdaIzqbiHLk2tuN ZC81jsJMxRKZ1U5KcvigCc/Eahf5rQRytJ7Y04hPgHNB3cyrUwmXC8gLtHcpNZqCkTdj ugFw== 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=X/vHm1f3WoFXRt6JUj3SilR7opGdtbcYgwZ9r1atlS8=; b=RNpibXciZBe1JI2iQu6GRfQih+FQnTZir4KnBSwwf0XK/EptASStvZ9mWFD6EY35Mv 6Ld5Wx3S5b6lYCf2lnt8SDUzgCzjVXQBbqMEi7iLlCT8xk5gwF0MCSVpaemnc+za+JQ0 HhsglhcWB0/zVVSYFfXeeXM09tCVceReNY8maWT2HTzyCci8Efa5b6ycH9k64oBCNA0N T7qUIxQNJ9Bs3o5wVf9D6WqpJPGzIQaPVau1Ko47VPzKL/Sfn/vG4L9D+YBi+OyFfCg4 //37bewFjBRXrmQDvPPpJnMM4hNTKePNLrTMyByOfBa5hYvaQUG8h1ov7J3KuoezzYRK wMQQ== X-Gm-Message-State: AJIora81UwKzHr5tR0n857GjpEXxMw7tHF4Tsh2W1aOSYbvsrZ0m/ZcW oWXc4pavf4X5FS9k7GbSQO9U43e6bVkj+Hk= X-Google-Smtp-Source: AGRyM1shE4oiEAmMw5aoUvXut3DE6PwvQ/fgFRcao0IJAPOeGEA0eOkJ0l5lxSyNWcz00L20yvlfpg== X-Received: by 2002:a05:620a:2720:b0:6a7:c28:3afa with SMTP id b32-20020a05620a272000b006a70c283afamr14575088qkp.438.1655685825745; Sun, 19 Jun 2022 17:43:45 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id bq38-20020a05620a46a600b006a785ba0c25sm10096007qkb.77.2022.06.19.17.43.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:44 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 31/34] d_path: prt_path() Date: Sun, 19 Jun 2022 20:42:30 -0400 Message-Id: <20220620004233.3805-32-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 35 +++++++++++++++++++++++++++++++++++ include/linux/dcache.h | 1 + 2 files changed, 36 insertions(+) diff --git a/fs/d_path.c b/fs/d_path.c index e4e0ebad1f..1bd9e85f2f 100644 --- a/fs/d_path.c +++ b/fs/d_path.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "mount.h" =20 @@ -294,6 +295,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_t(size_t, 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.1 From nobody Mon Apr 27 01:52:50 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 1BC32C433EF for ; Mon, 20 Jun 2022 00:45:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238146AbiFTAp3 (ORCPT ); Sun, 19 Jun 2022 20:45:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43046 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238421AbiFTAnv (ORCPT ); Sun, 19 Jun 2022 20:43:51 -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 681EFC31 for ; Sun, 19 Jun 2022 17:43:49 -0700 (PDT) Received: by mail-qk1-x729.google.com with SMTP id o73so6882163qke.7 for ; Sun, 19 Jun 2022 17:43:49 -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=Xv+tIa48UrOnTpHHPCzrOKYFNSv+Nn5TCx9go9g+iVw=; b=eaiXZoK60MvQ2CdtXu2PKhXT8ZplmCpv6qZBmPhhRT6rU2xYRyXdZB1+R8eXU1S/qT HhozAYwmzcVyoaCt0qvx1Syis9C82cWy/ZWngnhXuo1SInk+5vmM8qPqTAB6iNBlVEm5 qXeOiX8WY68mu+PI5TUIICPdFSNaBtfIw84y9jtE1YWKTEoqOOkxnngPKLovgYlEoPnU HbUboPBVLgLM0sMuy9GDMTxY8OKmk3+ujgOfgWSOaTNgxjH1EminncL9p9ytrwV6+hoG VGibstPfbF0Ff2sntd85ZRZqAJjyA5J62LM0NCWVXtR56CN9omTm0Z5LgE1xyRuNGK1X rxRQ== 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=Xv+tIa48UrOnTpHHPCzrOKYFNSv+Nn5TCx9go9g+iVw=; b=29rEK/N+IgBffi3vwZuYf1SKgQLK8WJNjm11yK6nRkUKPQRl9UnzU7YEroJjy/WXSl 7hSXG8HNYYzKlDdkW3OMsThgED7e313M5okhmO276q70fc467Dj0+5TFymW7OxrfFjmI PYIcyHP0QmREnG7fVKw9S8tYv6KMXGybdQVPpdJKnTHejzT1zJyrRpjvPt+gCjJ/NSsI KVLLPZNP/kH0+CJDiMU01go2gfQJRxT3mzmyAVVFnzIJmsF4D46UQ7ItHOo7o6pcJJsL h1kLY+BL19m6PV/8wrgZA9zSnul5NKnBW6eD9WTee0eQcxWbeI2mGrmqllkv3KZ06FLI R5Aw== X-Gm-Message-State: AJIora9LdbievqRqD+aBblxwKv6zpjxnBROsFg7GJgPFGmZvAvs3kE5t hLjQYTVjzITtnRLD64PN7kamrnihHkKJ/V4= X-Google-Smtp-Source: AGRyM1sSYBZpSG6ZKIG2kKHTTolELNxubEJe5pVBUEcpCqD1kkcqL+HgabyrFTApw9T4QrGr9yrf9w== X-Received: by 2002:a37:98b:0:b0:6a6:b2ca:194c with SMTP id 133-20020a37098b000000b006a6b2ca194cmr15003040qkj.470.1655685827787; Sun, 19 Jun 2022 17:43:47 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id bj6-20020a05620a190600b006a73ad95d40sm10706091qkb.55.2022.06.19.17.43.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:46 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 32/34] ACPI/APEI: Add missing include Date: Sun, 19 Jun 2022 20:42:31 -0400 Message-Id: <20220620004233.3805-33-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 upcoming patch to switch tracing from seq_buf to printbuf means we're no longer pulling in headers that we used to; this adds a missing include so things don't break. Signed-off-by: Kent Overstreet --- drivers/acpi/apei/erst-dbg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/acpi/apei/erst-dbg.c b/drivers/acpi/apei/erst-dbg.c index c740f0faad..90aa034dce 100644 --- a/drivers/acpi/apei/erst-dbg.c +++ b/drivers/acpi/apei/erst-dbg.c @@ -11,6 +11,7 @@ * Author: Huang Ying */ =20 +#include #include #include #include --=20 2.36.1 From nobody Mon Apr 27 01:52:50 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 44C5EC43334 for ; Mon, 20 Jun 2022 00:45:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238165AbiFTApR (ORCPT ); Sun, 19 Jun 2022 20:45:17 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:43778 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238425AbiFTAnx (ORCPT ); Sun, 19 Jun 2022 20:43:53 -0400 Received: from mail-qv1-xf35.google.com (mail-qv1-xf35.google.com [IPv6:2607:f8b0:4864:20::f35]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 932A4CE6 for ; Sun, 19 Jun 2022 17:43:51 -0700 (PDT) Received: by mail-qv1-xf35.google.com with SMTP id cu16so13426196qvb.7 for ; Sun, 19 Jun 2022 17:43: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=REYl/Kybw+QGOp3MKvOBE9VFTohBSgCoBZHGLGjR7yo=; b=SIV11o6c4n5zvMP1XmLZbKyVVbM8kHdlWfdGCqw3L5wQ8w4/Q8TlFtlmfsKK72puBl G9vZkcbm1Jkd0pdqdzhLGOOpakjzJsHgsBdp7rlLwirwxUkBOSQ7q91VGdtfqUKnS9/n kBvJ19oMnUjZGNujcSMiK3uozGTarsR2yad98lk7DwQ+mtUlLCn+uKEjkqRvEAldkcCx ZzNFeZU0zCNfjHvjUh6dkITW1i2hM6fWcvkO+lFuLheeMf+7iET7Clx+a7MYJhacEaQT B7u9Duirf52NLnR/reVrC3gYXKObjHnvfDolP3hmIxtqYVy2kIYosqyAy1+WWgYf1uIk /TlA== 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=REYl/Kybw+QGOp3MKvOBE9VFTohBSgCoBZHGLGjR7yo=; b=D+0mjl97KXozvuFFJNLPTywnhZnK6Y1zxIrh0gaURp+RDTsWycAFFCBfsv6QKp4W3/ t4PzDVJ/AGMVpp7oGCsTmn6SPVrz9Xt24uJSFUSN6VXsCkDxUKye36JXILWglYca/hPF BJtDL6vppzp3MdfKWDBy3tA40ClrrmyRtdq0mehWpNCYPXIXHuhke/Ti5lPEdsf7LWt4 pN6DH8bHBJI36DCRpxNRym2s+YqICJonRH1OTPKXUcfqYKZu0Oaemr2Rg49SDkX8dJyW kltpVZfPLu6e4yvwv3FwXeywDEoyBnm/dRAQxNc1Zb94XemklTPGaN+uhsVC+gHQNTLu PJ5w== X-Gm-Message-State: AJIora95GyhCvJItQPmILx84SLhReyhBC9WSqyKB42twmHsxWE44IUz1 kg9WXnPRfezt7hO//dCTOgW85EnhKr6soR0= X-Google-Smtp-Source: AGRyM1t5gBaXytT+IVdgBcfGLTFuRAQjLFb3HfPV7oLFNQeuv6NcUXOCk6z1ok5wjD9l/5AfthMQUg== X-Received: by 2002:ac8:7f15:0:b0:306:6adf:8ae9 with SMTP id f21-20020ac87f15000000b003066adf8ae9mr17414973qtk.137.1655685830506; Sun, 19 Jun 2022 17:43:50 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id n4-20020a05620a294400b006a793bde241sm11843958qkp.63.2022.06.19.17.43.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:49 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 33/34] tracing: Convert to printbuf Date: Sun, 19 Jun 2022 20:42:32 -0400 Message-Id: <20220620004233.3805-34-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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 | 17 ++-- 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, 103 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..d2b51007b3 100644 --- a/include/linux/trace_seq.h +++ b/include/linux/trace_seq.h @@ -2,10 +2,12 @@ #ifndef _LINUX_TRACE_SEQ_H #define _LINUX_TRACE_SEQ_H =20 -#include +#include =20 #include =20 +struct seq_file; + /* * Trace sequences are used to allow a function to call several other func= tions * to create a string of data to use (up to a max of PAGE_SIZE). @@ -13,14 +15,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 +43,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 +58,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 +70,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 /* @@ -87,6 +91,7 @@ extern void trace_seq_putc(struct trace_seq *s, unsigned = char c); extern void trace_seq_putmem(struct trace_seq *s, const void *mem, unsigne= d int len); extern void trace_seq_putmem_hex(struct trace_seq *s, const void *mem, unsigned int len); +struct path; extern int trace_seq_path(struct trace_seq *s, const struct path *path); =20 extern void trace_seq_bitmask(struct trace_seq *s, const unsigned long *ma= skp, 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..48c08f29c3 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(&s->seq, 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.1 From nobody Mon Apr 27 01:52:50 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 AD845C43334 for ; Mon, 20 Jun 2022 00:45:33 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238240AbiFTApc (ORCPT ); Sun, 19 Jun 2022 20:45:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237684AbiFTAn4 (ORCPT ); Sun, 19 Jun 2022 20:43:56 -0400 Received: from mail-qv1-xf2b.google.com (mail-qv1-xf2b.google.com [IPv6:2607:f8b0:4864:20::f2b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95B281117 for ; Sun, 19 Jun 2022 17:43:54 -0700 (PDT) Received: by mail-qv1-xf2b.google.com with SMTP id cs6so9536748qvb.6 for ; Sun, 19 Jun 2022 17:43: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=QRYNM4YOAyVk4ZMF2hc42bRe9CfEeZSSkthl3NyHx3U=; b=CtO1GgbgUzRTwX5Egh6hLP57RiqDH0juVom8UqlY1meZRqzq5FC0d89Lyge75ulR4y f5rETQq3HmIeHMHuYdDQPEWlUeT0IVqXpYqRIubq66Jrif39CXGWSB3zP6fWg7sP00Jx pYuAEkqklYpxrrHweta9zBR/ppR6bT1moPQp8sy2/OzGzSd7FoRGMecY1ct3CMFxitwn 87uvdGPPf68fgZnDFxA+vGLPiiZSMlrzXXrMBEnWvcCiHEGXJZW4Ol1akEbp5b66tXWo bumbNI+2Vgm0yNGlc0KsJRdgKlt4SpSuQkenBPbIkU/W6re1QXIV/AkF3N94djB9VN57 72Vw== 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=QRYNM4YOAyVk4ZMF2hc42bRe9CfEeZSSkthl3NyHx3U=; b=4FSTtQpA5IcJNfWBGImrwUg7a4iixoRBUONIbbJSv3mXVqG4wjbnXsOFiEKL2Inw1Q 3KpMtWPcrUmKaCTyqxfK6TEFGdkYFlT64U5fa1etYHP3b7n6rADKkCgy9+s7l3U3nhWc +vd0BKSAj5+4Ta3GLX19R0lMFhc8UnHOHoyyM3/egnri5tDZBukCrbxEMJgK3lUiFKK1 BMgfW3UUKoTODLi6SX7TJhFQnxDQTev7hdin39mDGlROMxvXDf0GuQV8KWe03ceax4J5 b8WlfQYG5UtEro1iEI/ZhNbZskjPNojir5xjFhgpYEQDuQhmFWuocJHlt+FYQ42bO/ov XXFQ== X-Gm-Message-State: AJIora+8KBLZ69z7onstZvONH1IxdlJbcVLJkvnLZFViC5HdB1Yfc1aA t1F5sgNeZ1BbG/uhgGlKgRrjs8ZP8N9nisA= X-Google-Smtp-Source: AGRyM1tnggbBTHHAGLLBpnswcFmiKBJZ9EA7HUIEngJMCN/XZ1atyi8Uwn9hf95GNATYeWLyn+y36Q== X-Received: by 2002:a05:6214:c41:b0:45f:380d:2f6a with SMTP id r1-20020a0562140c4100b0045f380d2f6amr17088442qvj.54.1655685833523; Sun, 19 Jun 2022 17:43:53 -0700 (PDT) Received: from localhost (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id y9-20020a05620a25c900b006ab93e0e053sm7159217qko.30.2022.06.19.17.43.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 19 Jun 2022 17:43:51 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, pmladek@suse.com Cc: Kent Overstreet , rostedt@goodmis.org, enozhatsky@chromium.org, linux@rasmusvillemoes.dk, willy@infradead.org Subject: [PATCH v4 34/34] Delete seq_buf Date: Sun, 19 Jun 2022 20:42:33 -0400 Message-Id: <20220620004233.3805-35-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220620004233.3805-1-kent.overstreet@gmail.com> References: <20220620004233.3805-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.1