From: Suren Baghdasaryan <[email protected]>
To: [email protected]
Cc: [email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected], [email protected],
[email protected], [email protected],
[email protected], [email protected],
[email protected], [email protected],
[email protected], [email protected]
Subject: [RFC PATCH 28/30] Improved symbolic error names
Date: Tue, 30 Aug 2022 14:49:17 -0700 [thread overview]
Message-ID: <[email protected]> (raw)
In-Reply-To: <[email protected]>
From: Kent Overstreet <[email protected]>
This patch adds per-error-site error codes, with error strings that
include their file and line number.
To use, change code that returns an error, e.g.
return -ENOMEM;
to
return -ERR(ENOMEM);
Then, errname() will return a string that includes the file and line
number of the ERR() call, for example
printk("Got error %s!\n", errname(err));
will result in
Got error ENOMEM at foo.c:1234
To convert back to the original error code (before returning it to
outside code that does not understand dynamic error codes), use
return error_class(err);
To test if an error is of some type, replace
if (err == -ENOMEM)
with
if (error_matches(err, ENOMEM))
Implementation notes:
Error codes are allocated dynamically on module load and deallocated on
module unload. On memory allocation failure (i.e. the data structures
for indexing error strings and error parents), ERR() will fall back to
returning the error code that it was passed.
MAX_ERRNO has been raised from 4096 to 1 million, which should be
sufficient given the number of lines of code and the fraction that throw
errors in the kernel codebase.
This has implications for ERR_PTR(), since the range of the address
space reserved for errors is unavailable for other purposes. Since
ERR_PTR() ptrs are at the top of the address space there should not be
any major difficulties.
Signed-off-by: Kent Overstreet <[email protected]>
---
include/asm-generic/codetag.lds.h | 3 +-
include/linux/err.h | 2 +-
include/linux/errname.h | 50 +++++++++++++++
lib/errname.c | 103 ++++++++++++++++++++++++++++++
4 files changed, 156 insertions(+), 2 deletions(-)
diff --git a/include/asm-generic/codetag.lds.h b/include/asm-generic/codetag.lds.h
index d799f4aced82..b087cf1874a9 100644
--- a/include/asm-generic/codetag.lds.h
+++ b/include/asm-generic/codetag.lds.h
@@ -11,6 +11,7 @@
#define CODETAG_SECTIONS() \
SECTION_WITH_BOUNDARIES(alloc_tags) \
SECTION_WITH_BOUNDARIES(dynamic_fault_tags) \
- SECTION_WITH_BOUNDARIES(time_stats_tags)
+ SECTION_WITH_BOUNDARIES(time_stats_tags) \
+ SECTION_WITH_BOUNDARIES(error_code_tags)
#endif /* __ASM_GENERIC_CODETAG_LDS_H */
diff --git a/include/linux/err.h b/include/linux/err.h
index a139c64aef2a..1d8d6c46ab9c 100644
--- a/include/linux/err.h
+++ b/include/linux/err.h
@@ -15,7 +15,7 @@
* This should be a per-architecture thing, to allow different
* error and pointer decisions.
*/
-#define MAX_ERRNO 4095
+#define MAX_ERRNO ((1 << 20) - 1)
#ifndef __ASSEMBLY__
diff --git a/include/linux/errname.h b/include/linux/errname.h
index e8576ad90cb7..dd39fe7120bb 100644
--- a/include/linux/errname.h
+++ b/include/linux/errname.h
@@ -5,12 +5,62 @@
#include <linux/stddef.h>
#ifdef CONFIG_SYMBOLIC_ERRNAME
+
const char *errname(int err);
+
+#include <linux/codetag.h>
+
+struct codetag_error_code {
+ const char *str;
+ int err;
+};
+
+/**
+ * ERR - return an error code that records the error site
+ *
+ * E.g., instead of
+ * return -ENOMEM;
+ * Use
+ * return -ERR(ENOMEM);
+ *
+ * Then, when a caller prints out the error with errname(), the error string
+ * will include the file and line number.
+ */
+#define ERR(_err) \
+({ \
+ static struct codetag_error_code \
+ __used \
+ __section("error_code_tags") \
+ __aligned(8) e = { \
+ .str = #_err " at " __FILE__ ":" __stringify(__LINE__),\
+ .err = _err, \
+ }; \
+ \
+ e.err; \
+})
+
+int error_class(int err);
+bool error_matches(int err, int class);
+
#else
+
+static inline int error_class(int err)
+{
+ return err;
+}
+
+static inline bool error_matches(int err, int class)
+{
+ return err == class;
+}
+
+#define ERR(_err) _err
+
static inline const char *errname(int err)
{
return NULL;
}
+
#endif
#endif /* _LINUX_ERRNAME_H */
diff --git a/lib/errname.c b/lib/errname.c
index 05cbf731545f..2db8f5301ba0 100644
--- a/lib/errname.c
+++ b/lib/errname.c
@@ -1,9 +1,20 @@
// SPDX-License-Identifier: GPL-2.0
#include <linux/build_bug.h>
+#include <linux/codetag.h>
#include <linux/errno.h>
#include <linux/errname.h>
+#include <linux/idr.h>
#include <linux/kernel.h>
#include <linux/math.h>
+#include <linux/module.h>
+#include <linux/xarray.h>
+
+#define DYNAMIC_ERRCODE_START 4096
+
+static DEFINE_IDR(dynamic_error_strings);
+static DEFINE_XARRAY(error_classes);
+
+static struct codetag_type *cttype;
/*
* Ensure these tables do not accidentally become gigantic if some
@@ -200,6 +211,9 @@ static const char *names_512[] = {
static const char *__errname(unsigned err)
{
+ if (err >= DYNAMIC_ERRCODE_START)
+ return idr_find(&dynamic_error_strings, err);
+
if (err < ARRAY_SIZE(names_0))
return names_0[err];
if (err >= 512 && err - 512 < ARRAY_SIZE(names_512))
@@ -222,3 +236,92 @@ const char *errname(int err)
return err > 0 ? name + 1 : name;
}
+
+/**
+ * error_class - return standard/parent error (of a dynamic error code)
+ *
+ * When using dynamic error codes returned by ERR(), error_class() will return
+ * the original errorcode that was passed to ERR().
+ */
+int error_class(int err)
+{
+ int class = abs(err);
+
+ if (class > DYNAMIC_ERRCODE_START)
+ class = (unsigned long) xa_load(&error_classes,
+ class - DYNAMIC_ERRCODE_START);
+ if (err < 0)
+ class = -class;
+ return class;
+}
+EXPORT_SYMBOL(error_class);
+
+/**
+ * error_matches - test if error is of some type
+ *
+ * When using dynamic error codes, instead of checking for errors with e.g.
+ * if (err == -ENOMEM)
+ * Instead use
+ * if (error_matches(err, ENOMEM))
+ */
+bool error_matches(int err, int class)
+{
+ err = abs(err);
+ class = abs(class);
+
+ BUG_ON(err >= MAX_ERRNO);
+ BUG_ON(class >= MAX_ERRNO);
+
+ if (err != class)
+ err = error_class(err);
+
+ return err == class;
+}
+EXPORT_SYMBOL(error_matches);
+
+static void errcode_module_load(struct codetag_type *cttype, struct codetag_module *mod)
+{
+ struct codetag_error_code *i, *start = (void *) mod->range.start;
+ struct codetag_error_code *end = (void *) mod->range.stop;
+
+ for (i = start; i != end; i++) {
+ int err = idr_alloc(&dynamic_error_strings,
+ (char *) i->str,
+ DYNAMIC_ERRCODE_START,
+ MAX_ERRNO,
+ GFP_KERNEL);
+ if (err < 0)
+ continue;
+
+ xa_store(&error_classes,
+ err - DYNAMIC_ERRCODE_START,
+ (void *)(unsigned long) abs(i->err),
+ GFP_KERNEL);
+
+ i->err = i->err < 0 ? -err : err;
+ }
+}
+
+static void errcode_module_unload(struct codetag_type *cttype, struct codetag_module *mod)
+{
+ struct codetag_error_code *i, *start = (void *) mod->range.start;
+ struct codetag_error_code *end = (void *) mod->range.stop;
+
+ for (i = start; i != end; i++)
+ idr_remove(&dynamic_error_strings, abs(i->err));
+}
+
+static int __init errname_init(void)
+{
+ const struct codetag_type_desc desc = {
+ .section = "error_code_tags",
+ .tag_size = sizeof(struct codetag_error_code),
+ .module_load = errcode_module_load,
+ .module_unload = errcode_module_unload,
+ };
+
+ cttype = codetag_register_type(&desc);
+
+ return PTR_ERR_OR_ZERO(cttype);
+}
+module_init(errname_init);
--
2.37.2.672.g94769d06f0-goog
next prev parent reply other threads:[~2022-08-30 21:54 UTC|newest]
Thread overview: 138+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-08-30 21:48 [RFC PATCH 00/30] Code tagging framework and applications Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 01/30] kernel/module: move find_kallsyms_symbol_value declaration Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 02/30] lib/string_helpers: Drop space in string_get_size's output Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 03/30] Lazy percpu counters Suren Baghdasaryan
2022-08-31 10:02 ` Mel Gorman
2022-08-31 15:37 ` Suren Baghdasaryan
2022-08-31 16:20 ` Kent Overstreet
2022-09-01 6:51 ` Peter Zijlstra
2022-09-01 14:32 ` Kent Overstreet
2022-09-01 14:48 ` Steven Rostedt
2022-09-01 15:43 ` Kent Overstreet
2022-09-01 18:59 ` Peter Zijlstra
2022-08-30 21:48 ` [RFC PATCH 04/30] scripts/kallysms: Always include __start and __stop symbols Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 05/30] lib: code tagging framework Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 06/30] lib: code tagging module support Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 07/30] lib: add support for allocation tagging Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 08/30] lib: introduce page " Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 09/30] change alloc_pages name in dma_map_ops to avoid name conflicts Suren Baghdasaryan
2022-08-30 21:48 ` [RFC PATCH 10/30] mm: enable page allocation tagging for __get_free_pages and alloc_pages Suren Baghdasaryan
2022-08-31 10:11 ` Mel Gorman
2022-08-31 15:45 ` Suren Baghdasaryan
2022-08-31 15:52 ` Suren Baghdasaryan
2022-08-31 17:46 ` Kent Overstreet
2022-09-01 1:07 ` Suren Baghdasaryan
2022-09-01 7:41 ` Peter Zijlstra
2022-08-30 21:49 ` [RFC PATCH 11/30] mm: introduce slabobj_ext to support slab object extensions Suren Baghdasaryan
2022-09-01 23:35 ` Roman Gushchin
2022-09-02 0:23 ` Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 12/30] mm: introduce __GFP_NO_OBJ_EXT flag to selectively prevent slabobj_ext creation Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 13/30] mm/slab: introduce SLAB_NO_OBJ_EXT to avoid obj_ext creation Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 14/30] mm: prevent slabobj_ext allocations for slabobj_ext and kmem_cache objects Suren Baghdasaryan
2022-09-01 23:40 ` Roman Gushchin
2022-09-02 0:24 ` Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 15/30] lib: introduce slab allocation tagging Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 16/30] mm: enable slab allocation tagging for kmalloc and friends Suren Baghdasaryan
2022-09-01 23:50 ` Roman Gushchin
2022-08-30 21:49 ` [RFC PATCH 17/30] lib/string.c: strsep_no_empty() Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 18/30] codetag: add codetag query helper functions Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 19/30] move stack capture functionality into a separate function for reuse Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 20/30] lib: introduce support for storing code tag context Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 21/30] lib: implement context capture support for page and slab allocators Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 22/30] Code tagging based fault injection Suren Baghdasaryan
2022-08-31 1:51 ` Randy Dunlap
2022-08-31 15:56 ` Suren Baghdasaryan
2022-08-31 10:37 ` Dmitry Vyukov
2022-08-31 15:51 ` Suren Baghdasaryan
2022-08-31 17:30 ` Kent Overstreet
2022-09-01 8:43 ` Dmitry Vyukov
2022-08-30 21:49 ` [RFC PATCH 23/30] timekeeping: Add a missing include Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 24/30] wait: Clean up waitqueue_entry initialization Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 25/30] lib/time_stats: New library for statistics on events Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 26/30] bcache: Convert to lib/time_stats Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 27/30] Code tagging based latency tracking Suren Baghdasaryan
2022-08-31 1:53 ` Randy Dunlap
2022-08-31 15:55 ` Suren Baghdasaryan
2022-09-01 7:11 ` Peter Zijlstra
2022-09-01 14:43 ` Kent Overstreet
2022-09-01 21:38 ` Steven Rostedt
2022-09-01 21:46 ` Steven Rostedt
2022-09-01 21:54 ` Kent Overstreet
2022-09-01 22:34 ` Steven Rostedt
2022-09-01 22:55 ` Kent Overstreet
2022-09-02 0:23 ` Steven Rostedt
2022-09-02 1:35 ` Kent Overstreet
2022-09-02 1:59 ` Steven Rostedt
2022-08-30 21:49 ` Suren Baghdasaryan [this message]
2022-09-01 23:19 ` [RFC PATCH 28/30] Improved symbolic error names Joe Perches
2022-09-01 23:26 ` Kent Overstreet
2022-08-30 21:49 ` [RFC PATCH 29/30] dyndbg: Convert to code tagging Suren Baghdasaryan
2022-08-30 21:49 ` [RFC PATCH 30/30] MAINTAINERS: Add entries for code tagging & related Suren Baghdasaryan
2022-08-31 7:38 ` [RFC PATCH 00/30] Code tagging framework and applications Peter Zijlstra
2022-08-31 8:42 ` Kent Overstreet
2022-08-31 10:19 ` Mel Gorman
2022-08-31 10:47 ` Michal Hocko
2022-08-31 15:28 ` Suren Baghdasaryan
2022-08-31 16:48 ` Suren Baghdasaryan
2022-08-31 19:01 ` Kent Overstreet
2022-08-31 20:56 ` Yosry Ahmed
2022-08-31 21:38 ` Suren Baghdasaryan
2022-09-01 22:27 ` Roman Gushchin
2022-09-01 22:37 ` Kent Overstreet
2022-09-01 22:53 ` Roman Gushchin
2022-09-01 23:36 ` Suren Baghdasaryan
2022-09-02 0:17 ` Kent Overstreet
2022-09-02 1:04 ` Roman Gushchin
2022-09-02 1:16 ` Kent Overstreet
2022-09-02 12:02 ` Jens Axboe
2022-09-02 19:48 ` Kent Overstreet
2022-09-02 19:53 ` Jens Axboe
2022-09-02 20:05 ` Kent Overstreet
2022-09-02 20:23 ` Jens Axboe
2022-09-01 7:18 ` Michal Hocko
2022-09-01 15:33 ` Suren Baghdasaryan
2022-09-01 19:15 ` Michal Hocko
2022-09-01 19:39 ` Suren Baghdasaryan
2022-09-01 20:15 ` Kent Overstreet
2022-09-05 8:49 ` Michal Hocko
2022-09-05 23:46 ` Kent Overstreet
2022-09-06 7:23 ` Michal Hocko
2022-09-06 18:20 ` Kent Overstreet
2022-09-07 11:00 ` Michal Hocko
2022-09-07 13:04 ` Kent Overstreet
2022-09-07 13:45 ` Steven Rostedt
2022-09-08 6:35 ` Kent Overstreet
2022-09-08 6:49 ` Suren Baghdasaryan
2022-09-08 7:07 ` Kent Overstreet
2022-09-08 7:12 ` Michal Hocko
2022-09-08 7:29 ` Kent Overstreet
2022-09-08 7:47 ` Michal Hocko
2022-09-05 1:32 ` Suren Baghdasaryan
2022-09-05 8:12 ` Michal Hocko
2022-09-05 8:58 ` Marco Elver
2022-09-05 18:07 ` Suren Baghdasaryan
2022-09-05 18:03 ` Suren Baghdasaryan
2022-09-06 8:01 ` Michal Hocko
2022-09-06 15:35 ` Suren Baghdasaryan
2022-09-05 15:07 ` Steven Rostedt
2022-09-05 18:08 ` Suren Baghdasaryan
2022-09-05 20:42 ` Kent Overstreet
2022-09-05 22:16 ` Steven Rostedt
2022-09-05 23:50 ` Kent Overstreet
2022-09-01 8:05 ` David Hildenbrand
2022-09-01 14:23 ` Kent Overstreet
2022-09-01 15:07 ` David Hildenbrand
2022-09-01 15:39 ` Suren Baghdasaryan
2022-09-01 15:48 ` Kent Overstreet
2022-08-31 15:59 ` Kent Overstreet
2022-09-01 7:05 ` Peter Zijlstra
2022-09-01 7:36 ` Daniel Bristot de Oliveira
2022-09-01 7:42 ` Peter Zijlstra
2022-09-01 11:05 ` Mel Gorman
2022-09-01 16:31 ` Kent Overstreet
2022-09-01 7:00 ` Peter Zijlstra
2022-09-01 14:29 ` Kent Overstreet
2022-09-05 18:44 ` Nadav Amit
2022-09-05 19:16 ` Steven Rostedt
2022-09-01 4:52 ` Oscar Salvador
2022-09-01 5:05 ` Suren Baghdasaryan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
[email protected] \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox