From patchwork Thu Apr 21 23:48:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822579 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 91D8EC4167D for ; Thu, 21 Apr 2022 23:48:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442795AbiDUXvr (ORCPT ); Thu, 21 Apr 2022 19:51:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49376 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442782AbiDUXvq (ORCPT ); Thu, 21 Apr 2022 19:51:46 -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 4269F433B1; Thu, 21 Apr 2022 16:48:54 -0700 (PDT) Received: by mail-qv1-xf33.google.com with SMTP id n11so4906693qvl.0; Thu, 21 Apr 2022 16:48: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=5WhyHlyJy4xU6YReftUXEs5LTZutZa3HDofMmOBXTLE=; b=AQLPRW36rsBuMa8/xIUdaNbDiyRqcAQz684qwwVv5jdLQnu/zUNtGDUw/B7bFrni4C pAWeJ3oN4Pj6oXtZ5lkmXkMrHv+tbMMT1sD7mBY1yESyD9eO2i5x9amEzL1U4/DhFLbO ejC1kTWj5x5vdx4D9HqkqzSrRHXcg4r8zcPJLUJI8A+cLrh9EXaLh3Mev/xfVD1zji97 ANZPDGmBJXJb5dWzh58VEUAaFZxFgnsrJPE5oOlfVAPTmm9emNVVRm7DuIUtBZjQTFHF H0YYlZzmDAKDikd3+AF86phqxO3cd9iyh4TejHR60t/GdthAMVRNpHI9zHNQtzy+/VpA GkCQ== 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=5WhyHlyJy4xU6YReftUXEs5LTZutZa3HDofMmOBXTLE=; b=EoPnVRvfNjF9maaenmDs2gfJXobomj5la/equ+uuFqK+cL3MfcTHPppTj7Oii13BVF ixEUy/mU1eh4vhRNqxsxPhAyf6SK2c2l6B53r6CeIMKX/v5ffDti9CBHMhTGthzdrg1J WOXYa8Nderkt/6OSmeIU0pPXSi9ivJ9LK1PKN61ClqSXKYfhR9NrtScXRurtlB81B595 wC4mu4baIfH4gBvBiaMv/nPvOG34dwaKbiaCtU5NC2CqE8k9IerN4F6zx/SyKwF7LQSv veTaP0ZRjhyYWBavIcEMx5MZPyRXdz0nqwwah6zAGHpGtjYPOlkAabZVFyr9Wct/R+t4 hqaQ== X-Gm-Message-State: AOAM530UjxzCBoEcJJc/34VRxNOjljw6LIQLngZes3mRufQGp0o0RJve +sOIawHOmJT3Nn9OVAvgCVQPJRfO95br X-Google-Smtp-Source: ABdhPJzTeuKYtVKzuVMuXWGTjw9xC0J0QgXOrkVmCWcRl3U4YiWy6z27w1kaozh6EXBlAv8VPDLQqQ== X-Received: by 2002:a05:6214:21a4:b0:446:5514:82b7 with SMTP id t4-20020a05621421a400b00446551482b7mr1507048qvc.54.1650584932740; Thu, 21 Apr 2022 16:48:52 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.48.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:48:52 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 1/8] lib/printbuf: New data structure for heap-allocated strings Date: Thu, 21 Apr 2022 19:48:30 -0400 Message-Id: <20220421234837.3629927-7-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This adds printbufs: simple heap-allocated strings meant for building up structured messages, for logging/procfs/sysfs and elsewhere. They've been heavily used in bcachefs for writing .to_text() functions/methods - pretty printers, which has in turn greatly improved the overall quality of error messages. Basic usage is documented in include/linux/printbuf.h. The next patches in the series are going to be using printbufs to implement a .to_text() method for shrinkers, and improving OOM reporting. Signed-off-by: Kent Overstreet --- include/linux/printbuf.h | 164 +++++++++++++++++++++++ lib/Makefile | 2 +- lib/printbuf.c | 274 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 439 insertions(+), 1 deletion(-) create mode 100644 include/linux/printbuf.h create mode 100644 lib/printbuf.c diff --git a/include/linux/printbuf.h b/include/linux/printbuf.h new file mode 100644 index 0000000000..276cdecf08 --- /dev/null +++ b/include/linux/printbuf.h @@ -0,0 +1,164 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifndef _LINUX_PRINTBUF_H +#define _LINUX_PRINTBUF_H + +/* + * Printbufs: Simple heap allocated strings, with some features for structered + * formatting. + * + * This code has provisions for use in userspace, to aid in making other code + * portable between kernelspace and userspace. + * + * Basic example: + * + * struct printbuf buf = PRINTBUF; + * + * pr_buf(&buf, "foo="); + * foo_to_text(&buf, foo); + * printk("%s", buf.buf); + * printbuf_exit(&buf); + * + * 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 allocations + * will be done with GFP_ATOMIC 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 does 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. + * + * pr_indent_push() and pr_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, pr_tab() will output spaces up to the next tabstop. + * pr_tab_rjust() will also advance the current line of text up to the next + * tabstop, but it does so by shifting text since the previous tabstop up to the + * next tabstop - right justifying it. + * + * Make sure you use pr_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 output + * numbers: a raw value (e.g. directly from a superblock field), as bytes, or as + * human readable bytes. pr_units() and pr_sectors() obey it. + * + * Other helpful functions: + * + * pr_human_readable_u64, pr_human_readable_s64: Print an integer with human + * readable units. + * + * pr_time(): for printing a time_t with strftime in userspace, prints as an + * integer number of seconds in the kernel. + * + * pr_string_option: Given an enumerated value and a string array with names for + * each option, prints out the enum names with the selected one indicated with + * square brackets. + * + * pr_bitflags: Given a bitflag and a string array with names for each bit, + * prints out the names of the selected bits. + */ + +#include +#include + +enum printbuf_units { + PRINTBUF_UNITS_RAW, + PRINTBUF_UNITS_BYTES, + PRINTBUF_UNITS_HUMAN_READABLE, +}; + +struct printbuf { + char *buf; + unsigned size; + unsigned pos; + unsigned last_newline; + unsigned last_field; + unsigned indent; + enum printbuf_units units:8; + /* + * If nonzero, allocations will be done with GFP_ATOMIC: + */ + u8 atomic; + bool allocation_failure:1; + /* SI units (10^3), or 2^10: */ + enum string_size_units human_readable_units:1; + u8 tabstop; + u8 tabstops[4]; +}; + +#define PRINTBUF ((struct printbuf) { .human_readable_units = STRING_UNITS_2 }) + +/** + * printbuf_exit - exit a printbuf, freeing memory it owns and poisoning it + * against accidental use. + */ +static inline void printbuf_exit(struct printbuf *buf) +{ + kfree(buf->buf); + buf->buf = ERR_PTR(-EINTR); /* poison value */ +} + +/** + * printbuf_reset - re-use a printbuf without freeing and re-initializing it: + */ +static inline void printbuf_reset(struct printbuf *buf) +{ + buf->pos = 0; + buf->last_newline = 0; + buf->last_field = 0; + buf->indent = 0; + buf->tabstop = 0; + buf->allocation_failure = 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--; +} + +void pr_buf(struct printbuf *out, const char *fmt, ...) + __attribute__ ((format (printf, 2, 3))); + +void pr_char(struct printbuf *buf, char c); +void pr_newline(struct printbuf *); +void pr_indent_push(struct printbuf *, unsigned); +void pr_indent_pop(struct printbuf *, unsigned); +void pr_tab(struct printbuf *); +void pr_tab_rjust(struct printbuf *); +void pr_human_readable_u64(struct printbuf *, u64); +void pr_human_readable_s64(struct printbuf *, s64); +void pr_units(struct printbuf *, s64, s64); +void pr_sectors(struct printbuf *, u64); +void pr_time(struct printbuf *, u64); +void pr_uuid(struct printbuf *, u8 *); +void pr_string_option(struct printbuf *, const char * const list[], size_t); +void pr_bitflags(struct printbuf *, const char * const list[], u64); +const char *printbuf_str(const struct printbuf *); + +#endif /* _LINUX_PRINTBUF_H */ diff --git a/lib/Makefile b/lib/Makefile index c588a126a3..31a3904eda 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -34,7 +34,7 @@ lib-y := 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 lib-$(CONFIG_PRINTK) += dump_stack.o lib-$(CONFIG_SMP) += cpumask.o diff --git a/lib/printbuf.c b/lib/printbuf.c new file mode 100644 index 0000000000..e0dfa82cda --- /dev/null +++ b/lib/printbuf.c @@ -0,0 +1,274 @@ +// SPDX-License-Identifier: LGPL-2.1+ +/* Copyright (C) 2022 Kent Overstreet */ + +#ifdef __KERNEL__ +#include +#include +#else +#define EXPORT_SYMBOL(x) +#endif + +#include +#include +#include + +static inline size_t printbuf_remaining(struct printbuf *buf) +{ + return buf->size - buf->pos; +} + +static inline size_t printbuf_linelen(struct printbuf *buf) +{ + return buf->pos - buf->last_newline; +} + +static int printbuf_realloc(struct printbuf *out, unsigned extra) +{ + unsigned new_size; + char *buf; + + if (out->pos + extra + 1 < out->size) + return 0; + + new_size = roundup_pow_of_two(out->size + extra); + buf = krealloc(out->buf, new_size, !out->atomic ? GFP_KERNEL : GFP_ATOMIC); + + if (!buf) { + out->allocation_failure = true; + return -ENOMEM; + } + + out->buf = buf; + out->size = new_size; + return 0; +} + +void pr_buf(struct printbuf *out, const char *fmt, ...) +{ + va_list args; + int len; + + do { + va_start(args, fmt); + len = vsnprintf(out->buf + out->pos, printbuf_remaining(out), fmt, args); + va_end(args); + } while (len + 1 >= printbuf_remaining(out) && + !printbuf_realloc(out, len + 1)); + + len = min_t(size_t, len, + printbuf_remaining(out) ? printbuf_remaining(out) - 1 : 0); + out->pos += len; +} +EXPORT_SYMBOL(pr_buf); + +void pr_char(struct printbuf *buf, char c) +{ + if (!printbuf_realloc(buf, 1)) { + buf->buf[buf->pos++] = c; + buf->buf[buf->pos] = 0; + } +} +EXPORT_SYMBOL(pr_char); + +void pr_newline(struct printbuf *buf) +{ + unsigned i; + + pr_char(buf, '\n'); + + buf->last_newline = buf->pos; + + for (i = 0; i < buf->indent; i++) + pr_char(buf, ' '); + + buf->last_field = buf->pos; + buf->tabstop = 0; +} +EXPORT_SYMBOL(pr_newline); + +void pr_indent_push(struct printbuf *buf, unsigned spaces) +{ + buf->indent += spaces; + while (spaces--) + pr_char(buf, ' '); +} +EXPORT_SYMBOL(pr_indent_push); + +void pr_indent_pop(struct printbuf *buf, unsigned spaces) +{ + if (buf->last_newline + buf->indent == buf->pos) { + buf->pos -= spaces; + buf->buf[buf->pos] = 0; + } + buf->indent -= spaces; +} +EXPORT_SYMBOL(pr_indent_pop); + +void pr_tab(struct printbuf *buf) +{ + BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops)); + + while (printbuf_remaining(buf) > 1 && + printbuf_linelen(buf) < buf->tabstops[buf->tabstop]) + pr_char(buf, ' '); + + buf->last_field = buf->pos; + buf->tabstop++; +} +EXPORT_SYMBOL(pr_tab); + +void pr_tab_rjust(struct printbuf *buf) +{ + BUG_ON(buf->tabstop > ARRAY_SIZE(buf->tabstops)); + + if (printbuf_linelen(buf) < buf->tabstops[buf->tabstop]) { + unsigned move = buf->pos - buf->last_field; + unsigned shift = buf->tabstops[buf->tabstop] - + printbuf_linelen(buf); + + printbuf_realloc(buf, shift); + + if (buf->last_field + shift + 1 < buf->size) { + move = min(move, buf->size - 1 - buf->last_field - shift); + + memmove(buf->buf + buf->last_field + shift, + buf->buf + buf->last_field, + move); + memset(buf->buf + buf->last_field, ' ', shift); + buf->pos += shift; + buf->buf[buf->pos] = 0; + } + } + + buf->last_field = buf->pos; + buf->tabstop++; +} +EXPORT_SYMBOL(pr_tab_rjust); + +void pr_human_readable_u64(struct printbuf *buf, u64 v) +{ + printbuf_realloc(buf, 10); + string_get_size(v, 1, buf->human_readable_units, buf->buf + buf->pos, + printbuf_remaining(buf)); + buf->pos += strlen(buf->buf + buf->pos); +} +EXPORT_SYMBOL(pr_human_readable_u64); + +void pr_human_readable_s64(struct printbuf *buf, s64 v) +{ + if (v < 0) + pr_char(buf, '-'); + pr_human_readable_u64(buf, abs(v)); +} +EXPORT_SYMBOL(pr_human_readable_s64); + +void pr_units(struct printbuf *out, s64 raw, s64 bytes) +{ + switch (out->units) { + case PRINTBUF_UNITS_RAW: + pr_buf(out, "%llu", raw); + break; + case PRINTBUF_UNITS_BYTES: + pr_buf(out, "%llu", bytes); + break; + case PRINTBUF_UNITS_HUMAN_READABLE: + pr_human_readable_s64(out, bytes); + break; + } +} +EXPORT_SYMBOL(pr_units); + +void pr_sectors(struct printbuf *out, u64 v) +{ + pr_units(out, v, v << 9); +} +EXPORT_SYMBOL(pr_sectors); + +#ifdef __KERNEL__ + +void pr_time(struct printbuf *out, u64 time) +{ + pr_buf(out, "%llu", time); +} +EXPORT_SYMBOL(pr_time); + +void pr_uuid(struct printbuf *out, u8 *uuid) +{ + pr_buf(out, "%pUb", uuid); +} +EXPORT_SYMBOL(pr_uuid); + +#else + +#include +#include + +void pr_time(struct printbuf *out, u64 _time) +{ + char time_str[64]; + time_t time = _time; + struct tm *tm = localtime(&time); + size_t err = strftime(time_str, sizeof(time_str), "%c", tm); + + if (!err) + pr_buf(out, "(formatting error)"); + else + pr_buf(out, "%s", time_str); +} + +void pr_uuid(struct printbuf *out, u8 *uuid) +{ + char uuid_str[40]; + + uuid_unparse_lower(uuid, uuid_str); + pr_buf(out, uuid_str); +} + +#endif + +void pr_string_option(struct printbuf *out, + const char * const list[], + size_t selected) +{ + size_t i; + + for (i = 0; list[i]; i++) + pr_buf(out, i == selected ? "[%s] " : "%s ", list[i]); +} +EXPORT_SYMBOL(pr_string_option); + +void pr_bitflags(struct printbuf *out, + const char * const list[], u64 flags) +{ + unsigned bit, nr = 0; + bool first = true; + + while (list[nr]) + nr++; + + while (flags && (bit = __ffs(flags)) < nr) { + if (!first) + pr_buf(out, ","); + first = false; + pr_buf(out, "%s", list[bit]); + flags ^= 1 << bit; + } +} +EXPORT_SYMBOL(pr_bitflags); + +/** + * printbuf_str - returns printbuf's buf as a C string, guaranteed to be null + * 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); From patchwork Thu Apr 21 23:48:31 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822578 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 638FFC46467 for ; Thu, 21 Apr 2022 23:48:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442802AbiDUXvs (ORCPT ); Thu, 21 Apr 2022 19:51:48 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49384 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442787AbiDUXvq (ORCPT ); Thu, 21 Apr 2022 19:51:46 -0400 Received: from mail-qv1-xf2d.google.com (mail-qv1-xf2d.google.com [IPv6:2607:f8b0:4864:20::f2d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BA98042EF1; Thu, 21 Apr 2022 16:48:55 -0700 (PDT) Received: by mail-qv1-xf2d.google.com with SMTP id c1so4878901qvl.3; Thu, 21 Apr 2022 16:48:55 -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=SE94/Kbz0iYkWqSiwiZXgkxJUhacoUay8DsU/fM4rGc=; b=O+Cm9zSSCAsfuY1cv1uyHWIfLd6AHQdXHkxkvQ1owHl1q4ed7gdNQPhDpX5U39ujmv yxHn/O7exq1vCm2R4Di+f5GdGcazARxVpYR+LbOz/om50ZJUiuhNwSe/W6O8i7ARpSGQ sY60BVfp3B8pLDaUfDS918qDgPQvki6XTXv1SXJUne0mHecVCvAkhP5SeB7Jl11anPcV tOw2oSITm50Hq0EvbwOmG5qp2GC/7aihcvhgAY7xt6OtbutHsyMm6T/DKNO72WWyzLXb 2+dFGD2ybpnAYizCWKXrnWd+g1rkN8/gCfZSr+xRjYSlsTPkWNm/Ms8qB1RnC85iuZTd JJzA== 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=SE94/Kbz0iYkWqSiwiZXgkxJUhacoUay8DsU/fM4rGc=; b=kI9ve79GTJP9TH4fUIhtIe5rbWwpMg09m529I99NoFP92ggHBzvgDOFdVLW//LyuSI QQv/t3PTRFkcr2a0HrW+0ff+qZW8srkY6nuZ5PLLCEGSUgTQDBZM/OKrAHQ1ofdWaI6r wcFXc3c7PZ48sI+5BMBe9n///RV1ohx0dcB5h843+WoRG9Zz93zGTlRf3kkqislbh3d2 zZJ0w82kE+jRoeJtoMgmaSnIk64vU7RrdTEhzPDqNdoNKkJepVrpK7liw8R+Z2N4SKQA U6th1P+TpRPJfkHwutHbSGJHlhSpvHu6PkLrxzx9KGreOpxF6nKQT6ibVYxAXOfig0FU Wnsw== X-Gm-Message-State: AOAM530O4wDXdsjvYsqWJBZr4jAsjkAj9W0VTNP7flGuK6RKE8FdE/pJ 6z2PM2nMyyhnOLHBIBHC5wMkcVnVpzjD X-Google-Smtp-Source: ABdhPJy1Vx4dCLoAejscY+AlE0uvjsIV8mL4rJ+39tNdmbaMB3K37JbaK9DmVM8bGfz4EduxkZW3sw== X-Received: by 2002:a05:6214:c85:b0:441:2b1c:dd46 with SMTP id r5-20020a0562140c8500b004412b1cdd46mr1437161qvr.41.1650584934575; Thu, 21 Apr 2022 16:48:54 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.48.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:48:53 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 2/8] Input/joystick/analog: Convert from seq_buf -> printbuf Date: Thu, 21 Apr 2022 19:48:31 -0400 Message-Id: <20220421234837.3629927-8-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org seq_buf is being deprecated, this converts to printbuf which is similar but heap allocates the string buffer. This means we have to consider memory allocation context & failure: Here we're in device initialization so GFP_KERNEL should be fine, and also as we're in device initialization returning -ENOMEM is fine. Signed-off-by: Kent Overstreet --- drivers/input/joystick/analog.c | 37 ++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/drivers/input/joystick/analog.c b/drivers/input/joystick/analog.c index 3088c5b829..72e1e30d19 100644 --- a/drivers/input/joystick/analog.c +++ b/drivers/input/joystick/analog.c @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include #include @@ -337,26 +337,32 @@ static void analog_calibrate_timer(struct analog_port *port) * analog_name() constructs a name for an analog joystick. */ -static void analog_name(struct analog *analog) +static int analog_name(struct analog *analog) { - struct seq_buf s; + struct printbuf buf = PRINTBUF; + int ret = 0; - 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_BTNS_CHF) * 2 + - hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); + pr_buf(&buf, "Analog %d-axis %d-button", + hweight8(analog->mask & ANALOG_AXES_STD), + hweight8(analog->mask & ANALOG_BTNS_STD) + !!(analog->mask & ANALOG_BTNS_CHF) * 2 + + hweight16(analog->mask & ANALOG_BTNS_GAMEPAD) + !!(analog->mask & ANALOG_HBTN_CHF) * 4); if (analog->mask & ANALOG_HATS_ALL) - seq_buf_printf(&s, " %d-hat", - hweight16(analog->mask & ANALOG_HATS_ALL)); + pr_buf(&buf, " %d-hat", + hweight16(analog->mask & ANALOG_HATS_ALL)); if (analog->mask & ANALOG_HAT_FCS) - seq_buf_printf(&s, " FCS"); + pr_buf(&buf, " FCS"); if (analog->mask & ANALOG_ANY_CHF) - seq_buf_printf(&s, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); + pr_buf(&buf, (analog->mask & ANALOG_SAITEK) ? " Saitek" : " CHF"); - seq_buf_printf(&s, (analog->mask & ANALOG_GAMEPAD) ? " gamepad" : " joystick"); + pr_buf(&buf, (analog->mask & ANALOG_GAMEPAD) ? " gamepad" : " joystick"); + + ret = buf.allocation_failure ? -ENOMEM : 0; + if (!ret) + strlcpy(analog->name, buf.buf, sizeof(analog->name)); + printbuf_exit(&buf); + return ret; } /* @@ -369,7 +375,10 @@ static int analog_init_device(struct analog_port *port, struct analog *analog, i int i, j, t, v, w, x, y, z; int error; - analog_name(analog); + error = analog_name(analog); + if (error) + return error; + snprintf(analog->phys, sizeof(analog->phys), "%s/input%d", port->gameport->phys, index); analog->buttons = (analog->mask & ANALOG_GAMEPAD) ? analog_pad_btn : analog_joy_btn; From patchwork Thu Apr 21 23:48:32 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822580 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 982E5C433FE for ; Thu, 21 Apr 2022 23:49:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442841AbiDUXwO (ORCPT ); Thu, 21 Apr 2022 19:52:14 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442779AbiDUXvs (ORCPT ); Thu, 21 Apr 2022 19:51:48 -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 7565C42A1E; Thu, 21 Apr 2022 16:48:57 -0700 (PDT) Received: by mail-qk1-x72b.google.com with SMTP id j6so4753186qkp.9; Thu, 21 Apr 2022 16:48:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=e+6QqEX2/fgk530CjQfyw22ixS6gH/22/NxatjEsE7U=; b=Piq4cGEnKIYkeK5yEy1v2UexgRA+klnfryaBWZhkBupuYhBIN2XFcsCr/AaH52FE8d 0JEeXqf4Zq7HsG13fmFy4/2mFPqqz7rKZatDWMCYVdnRBHgG6rgfOgrOQHT/GVvIvdUf wsU28fJ4WSETTWK8Qg0O8saCEIIie3SaDaIHYbYAvz6DgcuMPQ3p71RE6tc8leNehciN mRO85fjyes4oVWSJFVlSIAnLK9flxPklVtPhoULVPgaguai70ROKTnCM/ymp+zIfWIfT Sc7Bv4DgOO1Af7Llus43kg4AUlS9Uw0odTji6nK7vtAut6O7Z76r0LJ651UVN/paMo0b 1RhQ== 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=e+6QqEX2/fgk530CjQfyw22ixS6gH/22/NxatjEsE7U=; b=XvSzxHpmnPiz/Izt/odwH9KfS3YkciS4zNMkBwnZbuDiIRnAR1PYNW6Mf5fc4ugGhF JoXZnH4hepo+QMH9ff3wGfAjXiqT/738VEv/tU7NZsKUD+lMdBASReMwzGkpm+0tRToB EPQo1cTU3HWkYh/mYY9ladEjC154WMe/DkZJ99QrANLWHlpuGJVp1MCSE+usjnhyAVs6 hLwXmU+wJhXkJin1Tk3GGyZtaWywKr3PYuKhEHkY62ohc8eq1wxBqucMO4YREPUz9tX+ GgT4HDLUkokx9bWkop1lAoKiy+c9N8S32qn6z6GSqOHOKCOPTGLEQGVyWKUbji+oWjfq wDfw== X-Gm-Message-State: AOAM530JBgetKWHO3h31512mhXQNTZ+Xos53qDE13svUtiLis5oGQT7Y /R+TJKBxhLvSFgn4g0OcY98gZiMDkaqk X-Google-Smtp-Source: ABdhPJxpYT8g1HdDWANIVxroce92VLtnIjLTEtakAXl78RZEeLWPyMTLx9X4IHkCH/A+O9FtQPwCpQ== X-Received: by 2002:a05:620a:17a0:b0:69e:e769:48fd with SMTP id ay32-20020a05620a17a000b0069ee76948fdmr1213264qkb.382.1650584936061; Thu, 21 Apr 2022 16:48:56 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.48.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:48:55 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 3/8] mm/memcontrol.c: Convert to printbuf Date: Thu, 21 Apr 2022 19:48:32 -0400 Message-Id: <20220421234837.3629927-9-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org 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 36e9f38c91..4cb0b7bc1c 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c @@ -61,7 +61,7 @@ #include #include #include -#include +#include #include "internal.h" #include #include @@ -1436,13 +1436,9 @@ static inline unsigned long memcg_page_state_output(struct mem_cgroup *memcg, static char *memory_stat_format(struct mem_cgroup *memcg) { - struct seq_buf s; + struct printbuf buf = PRINTBUF; int i; - 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. @@ -1459,49 +1455,51 @@ static char *memory_stat_format(struct mem_cgroup *memcg) u64 size; size = memcg_page_state_output(memcg, memory_stats[i].idx); - seq_buf_printf(&s, "%s %llu\n", memory_stats[i].name, size); + pr_buf(&buf, "%s %llu\n", memory_stats[i].name, size); if (unlikely(memory_stats[i].idx == NR_SLAB_UNRECLAIMABLE_B)) { size += memcg_page_state_output(memcg, NR_SLAB_RECLAIMABLE_B); - seq_buf_printf(&s, "slab %llu\n", size); + pr_buf(&buf, "slab %llu\n", size); } } /* Accumulated memory events */ - 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)); + pr_buf(&buf, "%s %lu\n", vm_event_name(PGFAULT), + memcg_events(memcg, PGFAULT)); + pr_buf(&buf, "%s %lu\n", vm_event_name(PGMAJFAULT), + memcg_events(memcg, PGMAJFAULT)); + pr_buf(&buf, "%s %lu\n", vm_event_name(PGREFILL), + memcg_events(memcg, PGREFILL)); + pr_buf(&buf, "pgscan %lu\n", + memcg_events(memcg, PGSCAN_KSWAPD) + + memcg_events(memcg, PGSCAN_DIRECT)); + pr_buf(&buf, "pgsteal %lu\n", + memcg_events(memcg, PGSTEAL_KSWAPD) + + memcg_events(memcg, PGSTEAL_DIRECT)); + pr_buf(&buf, "%s %lu\n", vm_event_name(PGACTIVATE), + memcg_events(memcg, PGACTIVATE)); + pr_buf(&buf, "%s %lu\n", vm_event_name(PGDEACTIVATE), + memcg_events(memcg, PGDEACTIVATE)); + pr_buf(&buf, "%s %lu\n", vm_event_name(PGLAZYFREE), + memcg_events(memcg, PGLAZYFREE)); + pr_buf(&buf, "%s %lu\n", vm_event_name(PGLAZYFREED), + memcg_events(memcg, PGLAZYFREED)); #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)); + pr_buf(&buf, "%s %lu\n", vm_event_name(THP_FAULT_ALLOC), + memcg_events(memcg, THP_FAULT_ALLOC)); + pr_buf(&buf, "%s %lu\n", vm_event_name(THP_COLLAPSE_ALLOC), + memcg_events(memcg, THP_COLLAPSE_ALLOC)); #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ - /* 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; + } - return s.buffer; + return buf.buf; } #define K(x) ((x) << (PAGE_SHIFT-10)) From patchwork Thu Apr 21 23:48:33 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822582 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 24965C4332F for ; Thu, 21 Apr 2022 23:50:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1442868AbiDUXwY (ORCPT ); Thu, 21 Apr 2022 19:52:24 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442776AbiDUXvu (ORCPT ); Thu, 21 Apr 2022 19:51:50 -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 222B2434A5; Thu, 21 Apr 2022 16:48:59 -0700 (PDT) Received: by mail-qv1-xf35.google.com with SMTP id hu11so4859464qvb.7; Thu, 21 Apr 2022 16:48:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PF/Z8BQ8fxOBlrER2fv/400ai3CQSf3kzChsoC/3ncM=; b=Fmg9GchsDQjutgHrWM/IG+EZhv+HiZ+dEvnMEDFKb+T+r+Q/Xm1YYliGP71kb6HN+W GLqoDr61dXwsDzPdRECJYcQarmk+T6H4rug3ZFdmtLaQYy7lzYaMsCU6dX3rUj64pGr7 difeOIk+oQYdWGlmXufNianxRUrB5l5qg89ze9Jteco8L9yFCLmSBz6753W5U7GVkTFf KV2WBL3T5cbnVEjKBJAhLxSEDGc8wbP1WK3nKE6ceGRyVxh4RU72LEeojkTBoTQAuVll 0zLDqezyxdzSEYDpBh/5eBMG/x+TQe220iuYVtOgctc18dzhEdeyciNQwMdPaIo0yI2x DdwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PF/Z8BQ8fxOBlrER2fv/400ai3CQSf3kzChsoC/3ncM=; b=P6i+gA/DsL+XmEyamtFY0jBIIrN9d/kl+qiz2uyV9VCwfCe/xNOeG8YgU4n4nTf1Xa JRbxqcuLGqAC1wIrNEU+SW7KmBimKFoCxbCBN37paIJoDmsA3SskzygGTRIxSoT7tQQm 6serWAq3j8c6aCID7x8cr//OLzx88IImOnckVMlkc1dTD6caljaX3GgHK0hcVpcX/A6R xi/Oa4jekRBgIRvbpFFrmB4RY3bleooJAlY9HWbW5hMJdhvI8zNONzHfXULKKrRzqa3p D55xzESMxviBxVBNZ3hil/UmnjfejmeG709wyVbzB2c+XZYHvSZWDQRmnZMy1s9fSHh8 vOsA== X-Gm-Message-State: AOAM533GR4sKfLgLxU1pZavK/8APAiGi3ROe6u2cggbwrJsDdHcmxsPz Jz9qjlWVBMrn0OGPai209rZdhviLkHGb X-Google-Smtp-Source: ABdhPJwDhIK3eHTLsewAwF5FpbZ4NbS8mVZfkNqfhh2q7YLtu3tIrgjsNLqW2nO1uAxRcg8T77R/yw== X-Received: by 2002:ad4:5caa:0:b0:446:54ef:60d4 with SMTP id q10-20020ad45caa000000b0044654ef60d4mr1790926qvh.86.1650584937815; Thu, 21 Apr 2022 16:48:57 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.48.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:48:56 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 4/8] clk: tegra: bpmp: Convert to printbuf Date: Thu, 21 Apr 2022 19:48:33 -0400 Message-Id: <20220421234837.3629927-10-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org 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..77a8c47806 100644 --- a/drivers/clk/tegra/clk-bpmp.c +++ b/drivers/clk/tegra/clk-bpmp.c @@ -5,7 +5,7 @@ #include #include -#include +#include #include #include @@ -360,39 +360,38 @@ static void tegra_bpmp_clk_info_dump(struct tegra_bpmp *bpmp, const struct tegra_bpmp_clk_info *info) { const char *prefix = ""; - struct seq_buf buf; + struct printbuf buf = PRINTBUF; unsigned int i; - char flags[64]; - - seq_buf_init(&buf, flags, sizeof(flags)); if (info->flags) - seq_buf_printf(&buf, "("); + pr_buf(&buf, "("); if (info->flags & TEGRA_BPMP_CLK_HAS_MUX) { - seq_buf_printf(&buf, "%smux", prefix); + pr_buf(&buf, "%smux", prefix); prefix = ", "; } if ((info->flags & TEGRA_BPMP_CLK_HAS_SET_RATE) == 0) { - seq_buf_printf(&buf, "%sfixed", prefix); + pr_buf(&buf, "%sfixed", prefix); prefix = ", "; } if (info->flags & TEGRA_BPMP_CLK_IS_ROOT) { - seq_buf_printf(&buf, "%sroot", prefix); + pr_buf(&buf, "%sroot", prefix); prefix = ", "; } if (info->flags) - seq_buf_printf(&buf, ")"); + pr_buf(&buf, ")"); 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_str(&buf)); dev_printk(level, bpmp->dev, " parents: %u\n", info->num_parents); for (i = 0; i < info->num_parents; i++) dev_printk(level, bpmp->dev, " %03u\n", info->parents[i]); + + printbuf_exit(&buf); } static int tegra_bpmp_probe_clocks(struct tegra_bpmp *bpmp, From patchwork Thu Apr 21 23:48:34 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822581 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 EAA86C433FE for ; Thu, 21 Apr 2022 23:50:40 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230094AbiDUXwX (ORCPT ); Thu, 21 Apr 2022 19:52:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49468 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442809AbiDUXvw (ORCPT ); Thu, 21 Apr 2022 19:51:52 -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 97AE8434B5; Thu, 21 Apr 2022 16:49:00 -0700 (PDT) Received: by mail-qv1-xf33.google.com with SMTP id ke5so2635997qvb.5; Thu, 21 Apr 2022 16:49:00 -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=gx/pEzK/Si3DJxK25M0+mRodztZR2hxnPp00eWVAa1k=; b=Md/LjYEF9f+pRuz8KZH8oR8ODzAl6LE1NdwDO9B7yhhTbHjC1XjY6StBiio3j2Nvo1 JelKkMUZhH6wK9SIieCBlHRjkPiXecMX7lbXfg/XqFWogYyaitQ4MdWK8BXZq7mkhu1O OFnyhM+ibntll36tPPZSueMUXCwouOzvP6eHH1utH55G/gzIVvvomUfh32hDdsmMbf5j ior9XaGlQzyXxpuadInYd2sY51uzIco7yCLiu8jNyncc1IUMQD2y1/lU0BMZz4BOsCG/ YfI4zjIBitflaOo7HONdKt45CVTiopIOyKsTTpjmD6y0c5WL8ulhg5/2E53m0J0N/wOI +Qdw== 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=gx/pEzK/Si3DJxK25M0+mRodztZR2hxnPp00eWVAa1k=; b=SpsmedleUlNsICzdnEvYumm35OBa5oSpxxBCG6LU4eWfN8S43dnrXBYaHIksYEMEsA /X4o6rdX2gPDDmnEoFDV0dBg+AdFSDXACyLFWI0N4F3Ox73rShQCBx+Er+9zsvAHsYfc A+aDTgqGeGLXVoM5MOizIeMvcBhcyrbstOX7fLPBIZAIb4JKLd6Mu/iaDyj4YeEXW+Vo KjK/q/NtODtV0opmODsmLBU3XIiXj28ZgSJQHYlurNfjaC1iJcPyy9ctcQVVrgvJLPr8 dIKyNPUrdFtanfi5Fn7IxHoRkEwrJGuIg9f+oH/zz0MCAm5EyD+4FobyB8mDSnjYTth8 6Xug== X-Gm-Message-State: AOAM530a89CvO2mrP+SMOw2boDCMYmnTAIdImUV4P8GWf1ft5+Hx5lNR 1LaPy1F+AxsoXyz/T7qaO2EhMUo3ytFZ X-Google-Smtp-Source: ABdhPJy1nyPXDBoL0+vXyPBBH/+kX8pkeabBh3Ms+kkb3pWns3FlAR3mANJ7k+SatBCK1YhmRDDm8g== X-Received: by 2002:a05:6214:262c:b0:446:3464:57cd with SMTP id gv12-20020a056214262c00b00446346457cdmr1758402qvb.89.1650584939257; Thu, 21 Apr 2022 16:48:59 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.48.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:48:58 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 5/8] mm: Add a .to_text() method for shrinkers Date: Thu, 21 Apr 2022 19:48:34 -0400 Message-Id: <20220421234837.3629927-11-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This adds a new callback method to shrinkers which they can use to describe anything relevant to memory reclaim about their internal state, for example object dirtyness. This uses the new printbufs to output to heap allocated strings, so that the .to_text() methods can be used both for messages logged to the console, and also sysfs/debugfs. This patch also adds shrinkers_to_text(), which reports on the top 10 shrinkers - by object count - in sorted order, to be used in OOM reporting. Signed-off-by: Kent Overstreet --- include/linux/shrinker.h | 5 +++ mm/vmscan.c | 78 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index 76fbf92b04..b5f411768b 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -2,6 +2,8 @@ #ifndef _LINUX_SHRINKER_H #define _LINUX_SHRINKER_H +struct printbuf; + /* * This struct is used to pass information from page reclaim to the shrinkers. * We consolidate the values for easier extension later. @@ -58,10 +60,12 @@ struct shrink_control { * @flags determine the shrinker abilities, like numa awareness */ struct shrinker { + char name[32]; unsigned long (*count_objects)(struct shrinker *, struct shrink_control *sc); unsigned long (*scan_objects)(struct shrinker *, struct shrink_control *sc); + void (*to_text)(struct printbuf *, struct shrinker *); long batch; /* reclaim batch size, 0 = default */ int seeks; /* seeks to recreate an obj */ @@ -94,4 +98,5 @@ extern int register_shrinker(struct shrinker *shrinker); extern void unregister_shrinker(struct shrinker *shrinker); extern void free_prealloced_shrinker(struct shrinker *shrinker); extern void synchronize_shrinkers(void); +void shrinkers_to_text(struct printbuf *); #endif diff --git a/mm/vmscan.c b/mm/vmscan.c index 59b14e0d69..905bc23800 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -702,6 +703,83 @@ void synchronize_shrinkers(void) } EXPORT_SYMBOL(synchronize_shrinkers); +void shrinker_to_text(struct printbuf *out, struct shrinker *shrinker) +{ + struct shrink_control sc = { .gfp_mask = GFP_KERNEL, }; + + if (shrinker->name[0]) + pr_buf(out, "%s", shrinker->name); + else + pr_buf(out, "%ps:", shrinker->scan_objects); + + pr_buf(out, " objects: %lu", shrinker->count_objects(shrinker, &sc)); + pr_newline(out); + + if (shrinker->to_text) { + pr_indent_push(out, 2); + shrinker->to_text(out, shrinker); + pr_indent_pop(out, 2); + pr_newline(out); + } +} + +/** + * shrinkers_to_text - Report on shrinkers with highest usage + * + * This reports on the top 10 shrinkers, by object counts, in sorted order: + * intended to be used for OOM reporting. + */ +void shrinkers_to_text(struct printbuf *out) +{ + struct shrinker *shrinker; + struct shrinker_by_mem { + struct shrinker *shrinker; + unsigned long mem; + } shrinkers_by_mem[10]; + int i, nr = 0; + + if (!down_read_trylock(&shrinker_rwsem)) { + pr_buf(out, "(couldn't take shrinker lock)"); + return; + } + + list_for_each_entry(shrinker, &shrinker_list, list) { + struct shrink_control sc = { .gfp_mask = GFP_KERNEL, }; + unsigned long mem = shrinker->count_objects(shrinker, &sc); + + if (!mem || mem == SHRINK_STOP || mem == SHRINK_EMPTY) + continue; + + for (i = 0; i < nr; i++) + if (mem < shrinkers_by_mem[i].mem) + break; + + if (nr < ARRAY_SIZE(shrinkers_by_mem)) { + memmove(&shrinkers_by_mem[i + 1], + &shrinkers_by_mem[i], + sizeof(shrinkers_by_mem[0]) * (nr - i)); + nr++; + } else if (i) { + i--; + memmove(&shrinkers_by_mem[0], + &shrinkers_by_mem[1], + sizeof(shrinkers_by_mem[0]) * i); + } else { + continue; + } + + shrinkers_by_mem[i] = (struct shrinker_by_mem) { + .shrinker = shrinker, + .mem = mem, + }; + } + + for (i = nr - 1; i >= 0; --i) + shrinker_to_text(out, shrinkers_by_mem[i].shrinker); + + up_read(&shrinker_rwsem); +} + #define SHRINK_BATCH 128 static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, From patchwork Thu Apr 21 23:48:35 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822584 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 22F95C433EF for ; Thu, 21 Apr 2022 23:50:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443088AbiDUXxb (ORCPT ); Thu, 21 Apr 2022 19:53:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49906 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442779AbiDUXwW (ORCPT ); Thu, 21 Apr 2022 19:52:22 -0400 Received: from mail-qv1-xf2c.google.com (mail-qv1-xf2c.google.com [IPv6:2607:f8b0:4864:20::f2c]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 163C047385; Thu, 21 Apr 2022 16:49:02 -0700 (PDT) Received: by mail-qv1-xf2c.google.com with SMTP id n11so4906889qvl.0; Thu, 21 Apr 2022 16:49:02 -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=FeM5bqJiQrm2rh3JILkdt+BZf3iQXt3DndJ5kJUH6VM=; b=n/KPNGWJXcs0GJJTYwzELGdDRU26YZeN+AFBdrfivcUmDTFgoEKIyrauqulst14dH0 VIawqwx2mO79s0OxciEEIzbn1FvG1bH8bG3uS1fw7LT5ALzrMm7yM+uw93vItLfT2nW0 6vW0ixWFbUjKGZzE54v1t/I3Bb56898l1K1XBAcQabLQzanStxI9UkxPRziU7gkhloaO BPYvgr1vJyyfoY4JXraylWH6PYW9y9v+u6E5dvL1U4gTfbVtPd5b01hz0ZuIgSBkAYal 2vHqlPuenxkKGGJ237DRh/3jonP/A8fdnfy/nV7yUnNdSgA4uOcGoslhIzZ4kevfjAKu LBBA== 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=FeM5bqJiQrm2rh3JILkdt+BZf3iQXt3DndJ5kJUH6VM=; b=nOAPxG8xFKfc88RtTdPQ1SPFgF2adwipG9fL2+cI3+G2jrJ5mLdFyvE5GdxI62CAyD ldLwHngqJUTsDDh8otfdcKrIH6tphDBANDtcgpVNLLaTaMkmC7cbP+3etELttkaQ5/Iz 8E9m2u0f11rn7hZFaIh8xdZG3g2ONbcVizl3vc1UnzhFTew/QH9g22ylLG7VQyxSYsWu s3/wuxoNZk5R1+/9y3rXySVq4HAP+ig0MxmsAXS91/S8vSl3Ny4/i57/9gW6hdkZT1Pd D8kYxwQCwrewL0pIl1nH7g29LHXkMXGcdcDMWUIBZ0fZkossO3sH74G77eq8AwLYL5lu 3uKg== X-Gm-Message-State: AOAM530EKcXeKhcShHjP2rVI9zKP+uEYnwlc1kPd9qDWo6YQ5CsZDqUJ qgarRLmTkHoYPGIf9GesEzJI0neeXczI X-Google-Smtp-Source: ABdhPJwIwwSIi9BX9ueYR8W3xLzPDKzGU08fb3TSCEvxc7eNfeoVsUdKsvEsHwvgXeKxMCM8QFg4Jg== X-Received: by 2002:a05:6214:3006:b0:444:2fa9:9849 with SMTP id ke6-20020a056214300600b004442fa99849mr1462717qvb.101.1650584940771; Thu, 21 Apr 2022 16:49:00 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.48.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:49:00 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 6/8] mm: Count requests to free & nr freed per shrinker Date: Thu, 21 Apr 2022 19:48:35 -0400 Message-Id: <20220421234837.3629927-12-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org The next step in this patch series for improving debugging of shrinker related issues: keep counts of number of objects we request to free vs. actually freed, and prints them in shrinker_to_text(). Shrinkers won't necessarily free all objects requested for a variety of reasons, but if the two counts are wildly different something is likely amiss. Signed-off-by: Kent Overstreet --- include/linux/shrinker.h | 3 +++ mm/vmscan.c | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/include/linux/shrinker.h b/include/linux/shrinker.h index b5f411768b..12967748f9 100644 --- a/include/linux/shrinker.h +++ b/include/linux/shrinker.h @@ -79,6 +79,9 @@ struct shrinker { #endif /* objs pending delete, per node */ atomic_long_t *nr_deferred; + + atomic_long_t objects_requested_to_free; + atomic_long_t objects_freed; }; #define DEFAULT_SEEKS 2 /* A good number if you don't know better. */ diff --git a/mm/vmscan.c b/mm/vmscan.c index 905bc23800..12562546a7 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c @@ -711,16 +711,22 @@ void shrinker_to_text(struct printbuf *out, struct shrinker *shrinker) pr_buf(out, "%s", shrinker->name); else pr_buf(out, "%ps:", shrinker->scan_objects); + pr_newline(out); + pr_indent_push(out, 2); - pr_buf(out, " objects: %lu", shrinker->count_objects(shrinker, &sc)); + pr_buf(out, "objects: %lu", shrinker->count_objects(shrinker, &sc)); + pr_newline(out); + pr_buf(out, "requested to free: %lu", atomic_long_read(&shrinker->objects_requested_to_free)); + pr_newline(out); + pr_buf(out, "objects freed: %lu", atomic_long_read(&shrinker->objects_freed)); pr_newline(out); if (shrinker->to_text) { - pr_indent_push(out, 2); shrinker->to_text(out, shrinker); - pr_indent_pop(out, 2); pr_newline(out); } + + pr_indent_pop(out, 2); } /** @@ -846,12 +852,16 @@ static unsigned long do_shrink_slab(struct shrink_control *shrinkctl, unsigned long ret; unsigned long nr_to_scan = min(batch_size, total_scan); + atomic_long_add(nr_to_scan, &shrinker->objects_requested_to_free); + shrinkctl->nr_to_scan = nr_to_scan; shrinkctl->nr_scanned = nr_to_scan; ret = shrinker->scan_objects(shrinker, shrinkctl); if (ret == SHRINK_STOP) break; + freed += ret; + atomic_long_add(ret, &shrinker->objects_freed); count_vm_events(SLABS_SCANNED, shrinkctl->nr_scanned); total_scan -= shrinkctl->nr_scanned; From patchwork Thu Apr 21 23:48:36 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822583 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 82333C4167B for ; Thu, 21 Apr 2022 23:50:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443086AbiDUXxb (ORCPT ); Thu, 21 Apr 2022 19:53:31 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49904 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442855AbiDUXwW (ORCPT ); Thu, 21 Apr 2022 19:52:22 -0400 Received: from mail-qk1-x731.google.com (mail-qk1-x731.google.com [IPv6:2607:f8b0:4864:20::731]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E76347541; Thu, 21 Apr 2022 16:49:03 -0700 (PDT) Received: by mail-qk1-x731.google.com with SMTP id b68so4762799qkc.4; Thu, 21 Apr 2022 16:49: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=OX+ZZxfUCa6AeznhtMYBa3lbAYkGql05KEYmpApGJvc=; b=fWoFdNFoTzuTeyd37gJBh3UEJqZnL5c7olLDqlVchiUDB4EfzgpzArPgDksaoxFYSV lFcwfvuY2O4d+01Q5Zj7FApRfnsx10MrvqIQjieDrYqKS8oTMogkpDCLe6b+tIvGeoDg oZ25deodeMYYdcb4msCQZ95tNwqLOpZL1GqFWlCJbzyzHA0RXWkB1OWPmvNGxWqOFk0Z NMobe8u2+R7aXU1cBxhn6C/5a3nl/GRTkhDG3IY39MAnvrmCeWGVgd8OH0FEk9JXcTV+ sT/ZRPNX+2nh2YnvFSNMks5fpzsFDvBjYXVsugVKFszq5lRjdggcfrPmLI1vTlpoRedw R7eg== 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=OX+ZZxfUCa6AeznhtMYBa3lbAYkGql05KEYmpApGJvc=; b=nMilll6iPLoM+F+QT3W8u2m/mt9pOQQ+r+uClq6+uxtqAsTZHZsi3mubEJq80i/3rW 92p/R1IxcuNU3NOxPJLFta3QIlZ5FXa0+yW9lfj6Pob7UadwO6veTKjz0ESnboTA7oRz K0cUUazZ8jEAPuMiFqwFwqqtypPDCZAQKFE0Cw+9MRC+5qqAvgESV3rO0OV02zyOvuVf 7OYo3zvhSr2/j7rgAYhCxzohUrpuXhTXzyTuX2Ph8kw6T3R5VPZ2wcv6xQsTAflE4TDY s8pPm0unxCaDvIbQEfpW3qZUrtFlhT8f6+rpoPf4umy2GChXQmnUJm6a1IUuHv/IZR8W VYvg== X-Gm-Message-State: AOAM532Kk/qKbRjROAObwT3eLJ8R7VN8CV0T+ouaAkDKc3i6ZMwyJzMM rpseF8w2ZwpqEb4uiWXBlsUPfsyodICm X-Google-Smtp-Source: ABdhPJy4AfRMSM5fE/ShUTn41jLAMSbQ5zXgowJp+WmfgN33q5UIkYcEB9ug5C7qJVU5PFjSL7Hzbg== X-Received: by 2002:a05:620a:2805:b0:67d:5c7e:c43a with SMTP id f5-20020a05620a280500b0067d5c7ec43amr1216746qkp.84.1650584942298; Thu, 21 Apr 2022 16:49:02 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.49.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:49:01 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 7/8] mm: Move lib/show_mem.c to mm/ Date: Thu, 21 Apr 2022 19:48:36 -0400 Message-Id: <20220421234837.3629927-13-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org show_mem.c is really mm specific, and the next patch in the series is going to require mm/slab.h, so let's move it before doing more work on it. Signed-off-by: Kent Overstreet Acked-by: Michal Hocko --- lib/Makefile | 2 +- mm/Makefile | 2 +- {lib => mm}/show_mem.c | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename {lib => mm}/show_mem.c (100%) diff --git a/lib/Makefile b/lib/Makefile index 31a3904eda..c5041d33d0 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -30,7 +30,7 @@ endif lib-y := ctype.o string.o vsprintf.o cmdline.o \ rbtree.o radix-tree.o timerqueue.o xarray.o \ idr.o extable.o sha1.o irq_regs.o argv_split.o \ - flex_proportions.o ratelimit.o show_mem.o \ + flex_proportions.o ratelimit.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 \ diff --git a/mm/Makefile b/mm/Makefile index 70d4309c9c..97c0be12f3 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -54,7 +54,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ mm_init.o percpu.o slab_common.o \ compaction.o vmacache.o \ interval_tree.o list_lru.o workingset.o \ - debug.o gup.o mmap_lock.o $(mmu-y) + debug.o gup.o mmap_lock.o show_mem.o $(mmu-y) # Give 'page_alloc' its own module-parameter namespace page-alloc-y := page_alloc.o diff --git a/lib/show_mem.c b/mm/show_mem.c similarity index 100% rename from lib/show_mem.c rename to mm/show_mem.c From patchwork Thu Apr 21 23:48:37 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kent Overstreet X-Patchwork-Id: 12822585 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 304A2C43219 for ; Thu, 21 Apr 2022 23:50:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1443091AbiDUXxd (ORCPT ); Thu, 21 Apr 2022 19:53:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:49914 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1442861AbiDUXwW (ORCPT ); Thu, 21 Apr 2022 19:52:22 -0400 Received: from mail-qk1-x734.google.com (mail-qk1-x734.google.com [IPv6:2607:f8b0:4864:20::734]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 363F947AE9; Thu, 21 Apr 2022 16:49:05 -0700 (PDT) Received: by mail-qk1-x734.google.com with SMTP id q75so4758029qke.6; Thu, 21 Apr 2022 16:49:05 -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=aaKcIjNjF3IwQgxs7vyEXb42UUHeDaL+RKW940GYuHE=; b=a0tjhmKMatzGt0SztAxbHSgi9tkuoq0b0Avq27VcC+kWC+951h6K4afxy78BlImIme 8hwewDxQUByXhjBpdf3GRogZFMXghbYddWPYGObWHaKwar6ZutgSnbKNT7F3FZLqk7wN iZppyKJc9qP3jlBDtQPTyi/5r/om31TNT0840qZqtz+vuCG6AlUZg0IcBuGtOpb3ubGg NNKJgJqrfumSUdnk3c04fo5WdiHypYP0u2zJ040DG42b0Ps/eBSB7PE57jCggeofy1rQ bctqg3CeHEwk/dvoUnReNkmfYLTGm+Cqm1k45E9NSblGTm2QEP4vBQwsNvO+VemICgy1 gcCQ== 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=aaKcIjNjF3IwQgxs7vyEXb42UUHeDaL+RKW940GYuHE=; b=dYZl1j8JBv8yxudvoLOWi6OljcuD7nl/yvdxg/qHKI9RY8GDlNmHt9wFbn9Xgw9U3C /xWkVll8r730WR+10+14ABANnANpqhZJ246diEe6DqJl/1c01mg3POSvM1PVwT0/AsyQ 9iMEYw+9vZVEc58zYbFh/qCrRsApn9BTWCmlUlJtWUT/fmpqSR2onKxrtUZSK0+E0UR8 LwUeOfogJTNvGdFbgjm36h64qISwpkwXjYBZh6ZOW5vnbQQUNpGao6i2dEY157m0+rbK NrXaF2ph0XooiBen763ZP6xzify+2Q4EKGRnM2eYSMqIQExAtfATCmyC1T59XoO+oR05 UqBQ== X-Gm-Message-State: AOAM532NdbS+QfEKz26gVlhymAL70KGPTANwuAhsYcfV/+oR+8/35kKE 1hBKT6cE2ugIaZXOSk/zReM6kd7iHL7J X-Google-Smtp-Source: ABdhPJwtXpdd8XMsi8NfAgNi48EgWOzVYdEawLNA8H89/n1HqY3g/ULD/amWov5SbJzrqfz2xmZ8eQ== X-Received: by 2002:a05:620a:bd5:b0:67d:15ed:2fcd with SMTP id s21-20020a05620a0bd500b0067d15ed2fcdmr1185692qki.81.1650584943898; Thu, 21 Apr 2022 16:49:03 -0700 (PDT) Received: from moria.home.lan (c-73-219-103-14.hsd1.vt.comcast.net. [73.219.103.14]) by smtp.gmail.com with ESMTPSA id a1-20020a05622a02c100b002f342ccc1c5sm287372qtx.72.2022.04.21.16.49.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 21 Apr 2022 16:49:03 -0700 (PDT) From: Kent Overstreet To: linux-kernel@vger.kernel.org, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org Cc: Kent Overstreet , hch@lst.de, hannes@cmpxchg.org, akpm@linux-foundation.org, linux-clk@vger.kernel.org, linux-tegra@vger.kernel.org, linux-input@vger.kernel.org, roman.gushchin@linux.dev Subject: [PATCH v2 8/8] mm: Centralize & improve oom reporting in show_mem.c Date: Thu, 21 Apr 2022 19:48:37 -0400 Message-Id: <20220421234837.3629927-14-kent.overstreet@gmail.com> X-Mailer: git-send-email 2.35.2 In-Reply-To: <20220421234837.3629927-1-kent.overstreet@gmail.com> References: <20220421234837.3629927-1-kent.overstreet@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org This patch: - Changes show_mem() to always report on slab usage - Instead of reporting on all slabs, we only report on top 10 slabs, and in sorted order - Also reports on shrinkers, with the new shrinkers_to_text(). Shrinkers need to be included in OOM/allocation failure reporting because they're responsible for memory reclaim - if a shrinker isn't giving up its memory, we need to know which one and why. More OOM reporting can be moved to show_mem.c and improved, this patch is only a start. New example output on OOM/memory allocation failure: 00177 Mem-Info: 00177 active_anon:13706 inactive_anon:32266 isolated_anon:16 00177 active_file:1653 inactive_file:1822 isolated_file:0 00177 unevictable:0 dirty:0 writeback:0 00177 slab_reclaimable:6242 slab_unreclaimable:11168 00177 mapped:3824 shmem:3 pagetables:1266 bounce:0 00177 kernel_misc_reclaimable:0 00177 free:4362 free_pcp:35 free_cma:0 00177 Node 0 active_anon:54824kB inactive_anon:129064kB active_file:6612kB inactive_file:7288kB unevictable:0kB isolated(anon):64kB isolated(file):0kB mapped:15296kB dirty:0kB writeback:0kB shmem:12kB writeback_tmp:0kB kernel_stack:3392kB pagetables:5064kB all_unreclaimable? no 00177 DMA free:2232kB boost:0kB min:88kB low:108kB high:128kB reserved_highatomic:0KB active_anon:2924kB inactive_anon:6596kB active_file:428kB inactive_file:384kB unevictable:0kB writepending:0kB present:15992kB managed:15360kB mlocked:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB 00177 lowmem_reserve[]: 0 426 426 426 00177 DMA32 free:15092kB boost:5836kB min:8432kB low:9080kB high:9728kB reserved_highatomic:0KB active_anon:52196kB inactive_anon:122392kB active_file:6176kB inactive_file:7068kB unevictable:0kB writepending:0kB present:507760kB managed:441816kB mlocked:0kB bounce:0kB free_pcp:72kB local_pcp:0kB free_cma:0kB 00177 lowmem_reserve[]: 0 0 0 0 00177 DMA: 284*4kB (UM) 53*8kB (UM) 21*16kB (U) 11*32kB (U) 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 2248kB 00177 DMA32: 2765*4kB (UME) 375*8kB (UME) 57*16kB (UM) 5*32kB (U) 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 15132kB 00177 4656 total pagecache pages 00177 1031 pages in swap cache 00177 Swap cache stats: add 6572399, delete 6572173, find 488603/3286476 00177 Free swap = 509112kB 00177 Total swap = 2097148kB 00177 130938 pages RAM 00177 0 pages HighMem/MovableOnly 00177 16644 pages reserved 00177 Unreclaimable slab info: 00177 9p-fcall-cache total: 8.25 MiB active: 8.25 MiB 00177 kernfs_node_cache total: 2.15 MiB active: 2.15 MiB 00177 kmalloc-64 total: 2.08 MiB active: 2.07 MiB 00177 task_struct total: 1.95 MiB active: 1.95 MiB 00177 kmalloc-4k total: 1.50 MiB active: 1.50 MiB 00177 signal_cache total: 1.34 MiB active: 1.34 MiB 00177 kmalloc-2k total: 1.16 MiB active: 1.16 MiB 00177 bch_inode_info total: 1.02 MiB active: 922 KiB 00177 perf_event total: 1.02 MiB active: 1.02 MiB 00177 biovec-max total: 992 KiB active: 960 KiB 00177 Shrinkers: 00177 super_cache_scan: objects: 127 00177 super_cache_scan: objects: 106 00177 jbd2_journal_shrink_scan: objects: 32 00177 ext4_es_scan: objects: 32 00177 bch2_btree_cache_scan: objects: 8 00177 nr nodes: 24 00177 nr dirty: 0 00177 cannibalize lock: 0000000000000000 00177 00177 super_cache_scan: objects: 8 00177 super_cache_scan: objects: 1 Signed-off-by: Kent Overstreet --- mm/oom_kill.c | 23 --------------------- mm/show_mem.c | 14 +++++++++++++ mm/slab.h | 6 ++++-- mm/slab_common.c | 53 ++++++++++++++++++++++++++++++++++++++++-------- 4 files changed, 63 insertions(+), 33 deletions(-) diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 832fb33037..659c7d6376 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c @@ -171,27 +171,6 @@ static bool oom_unkillable_task(struct task_struct *p) return false; } -/* - * Check whether unreclaimable slab amount is greater than - * all user memory(LRU pages). - * dump_unreclaimable_slab() could help in the case that - * oom due to too much unreclaimable slab used by kernel. -*/ -static bool should_dump_unreclaim_slab(void) -{ - unsigned long nr_lru; - - nr_lru = global_node_page_state(NR_ACTIVE_ANON) + - global_node_page_state(NR_INACTIVE_ANON) + - global_node_page_state(NR_ACTIVE_FILE) + - global_node_page_state(NR_INACTIVE_FILE) + - global_node_page_state(NR_ISOLATED_ANON) + - global_node_page_state(NR_ISOLATED_FILE) + - global_node_page_state(NR_UNEVICTABLE); - - return (global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B) > nr_lru); -} - /** * oom_badness - heuristic function to determine which candidate task to kill * @p: task struct of which task we should calculate @@ -465,8 +444,6 @@ static void dump_header(struct oom_control *oc, struct task_struct *p) mem_cgroup_print_oom_meminfo(oc->memcg); else { show_mem(SHOW_MEM_FILTER_NODES, oc->nodemask); - if (should_dump_unreclaim_slab()) - dump_unreclaimable_slab(); } if (sysctl_oom_dump_tasks) dump_tasks(oc); diff --git a/mm/show_mem.c b/mm/show_mem.c index 1c26c14ffb..24b662f64d 100644 --- a/mm/show_mem.c +++ b/mm/show_mem.c @@ -7,11 +7,15 @@ #include #include +#include + +#include "slab.h" void show_mem(unsigned int filter, nodemask_t *nodemask) { pg_data_t *pgdat; unsigned long total = 0, reserved = 0, highmem = 0; + struct printbuf buf = PRINTBUF; printk("Mem-Info:\n"); show_free_areas(filter, nodemask); @@ -41,4 +45,14 @@ void show_mem(unsigned int filter, nodemask_t *nodemask) #ifdef CONFIG_MEMORY_FAILURE printk("%lu pages hwpoisoned\n", atomic_long_read(&num_poisoned_pages)); #endif + + pr_info("Unreclaimable slab info:\n"); + dump_unreclaimable_slab(&buf); + printk("%s", printbuf_str(&buf)); + printbuf_reset(&buf); + + printk("Shrinkers:\n"); + shrinkers_to_text(&buf); + printk("%s", printbuf_str(&buf)); + printbuf_exit(&buf); } diff --git a/mm/slab.h b/mm/slab.h index c7f2abc2b1..abefbf7674 100644 --- a/mm/slab.h +++ b/mm/slab.h @@ -788,10 +788,12 @@ static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node) #endif +struct printbuf; + #if defined(CONFIG_SLAB) || defined(CONFIG_SLUB_DEBUG) -void dump_unreclaimable_slab(void); +void dump_unreclaimable_slab(struct printbuf *); #else -static inline void dump_unreclaimable_slab(void) +static inline void dump_unreclaimable_slab(struct printbuf *out) { } #endif diff --git a/mm/slab_common.c b/mm/slab_common.c index 23f2ab0713..1209480797 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c @@ -24,6 +24,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -1084,10 +1085,15 @@ static int slab_show(struct seq_file *m, void *p) return 0; } -void dump_unreclaimable_slab(void) +void dump_unreclaimable_slab(struct printbuf *out) { struct kmem_cache *s; struct slabinfo sinfo; + struct slab_by_mem { + struct kmem_cache *s; + size_t total, active; + } slabs_by_mem[10], n; + int i, nr = 0; /* * Here acquiring slab_mutex is risky since we don't prefer to get @@ -1097,12 +1103,11 @@ void dump_unreclaimable_slab(void) * without acquiring the mutex. */ if (!mutex_trylock(&slab_mutex)) { - pr_warn("excessive unreclaimable slab but cannot dump stats\n"); + pr_buf(out, "excessive unreclaimable slab but cannot dump stats\n"); return; } - pr_info("Unreclaimable slab info:\n"); - pr_info("Name Used Total\n"); + printbuf_atomic_inc(out); list_for_each_entry(s, &slab_caches, list) { if (s->flags & SLAB_RECLAIM_ACCOUNT) @@ -1110,11 +1115,43 @@ void dump_unreclaimable_slab(void) get_slabinfo(s, &sinfo); - if (sinfo.num_objs > 0) - pr_info("%-17s %10luKB %10luKB\n", s->name, - (sinfo.active_objs * s->size) / 1024, - (sinfo.num_objs * s->size) / 1024); + if (!sinfo.num_objs) + continue; + + n.s = s; + n.total = sinfo.num_objs * s->size; + n.active = sinfo.active_objs * s->size; + + for (i = 0; i < nr; i++) + if (n.total < slabs_by_mem[i].total) + break; + + if (nr < ARRAY_SIZE(slabs_by_mem)) { + memmove(&slabs_by_mem[i + 1], + &slabs_by_mem[i], + sizeof(slabs_by_mem[0]) * (nr - i)); + nr++; + } else if (i) { + i--; + memmove(&slabs_by_mem[0], + &slabs_by_mem[1], + sizeof(slabs_by_mem[0]) * i); + } else { + continue; + } + + slabs_by_mem[i] = n; + } + + for (i = nr - 1; i >= 0; --i) { + pr_buf(out, "%-17s total: ", slabs_by_mem[i].s->name); + pr_human_readable_u64(out, slabs_by_mem[i].total); + pr_buf(out, " active: "); + pr_human_readable_u64(out, slabs_by_mem[i].active); + pr_newline(out); } + + printbuf_atomic_dec(out); mutex_unlock(&slab_mutex); }