From: paulmck@kernel.org
To: rcu@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, kernel-team@fb.com,
mingo@kernel.org, jiangshanlai@gmail.com,
akpm@linux-foundation.org, mathieu.desnoyers@efficios.com,
josh@joshtriplett.org, tglx@linutronix.de, peterz@infradead.org,
rostedt@goodmis.org, dhowells@redhat.com, edumazet@google.com,
fweisbec@gmail.com, oleg@redhat.com, joel@joelfernandes.org,
"Paul E. McKenney" <paulmck@kernel.org>,
Christoph Lameter <cl@linux.com>,
Pekka Enberg <penberg@kernel.org>,
David Rientjes <rientjes@google.com>,
Joonsoo Kim <iamjoonsoo.kim@lge.com>,
linux-mm@kvack.org
Subject: [PATCH sl-b 2/6] mm: Add kmem_last_alloc_errstring() to provide more kmem_last_alloc() info
Date: Fri, 4 Dec 2020 16:40:53 -0800 [thread overview]
Message-ID: <20201205004057.32199-2-paulmck@kernel.org> (raw)
In-Reply-To: <20201205004022.GA31166@paulmck-ThinkPad-P72>
From: "Paul E. McKenney" <paulmck@kernel.org>
NULL pointers can be useful, but the NULL pointers from kmem_last_alloc()
might be caused by any number of things: A not-to-a-slab pointer,
failure to enable all the needed debugging, and bogus slob block-address
computations. This commit therefore introduces error codes to the
kmem_last_alloc() function using the ERR_PTR() facility, and also
introduces kmem_last_alloc_errstring(), which translates the error codes
into strings.
Cc: Christoph Lameter <cl@linux.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: David Rientjes <rientjes@google.com>
Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: <linux-mm@kvack.org>
Reported-by: Andrii Nakryiko <andrii@kernel.org>
Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
---
include/linux/slab.h | 10 ++++++++++
mm/slab.c | 2 +-
mm/slab_common.c | 28 ++++++++++++++++++++++++++--
mm/slob.c | 2 +-
mm/slub.c | 4 ++--
5 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/include/linux/slab.h b/include/linux/slab.h
index 06dd56b..031e630 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -133,6 +133,15 @@
#define ZERO_OR_NULL_PTR(x) ((unsigned long)(x) <= \
(unsigned long)ZERO_SIZE_PTR)
+/*
+ * kmem_last_alloc error codes.
+ */
+#define KMEM_LA_NO_PAGE 1 /* No page structure for pointer. */
+#define KMEM_LA_NO_SLAB 2 /* Pointer not from slab allocator. */
+#define KMEM_LA_SLOB 3 /* No debugging info for slob. */
+#define KMEM_LA_NO_DEBUG 4 /* Debugging not enabled for slab/slub. */
+#define KMEM_LA_INCONSISTENT 5 /* Bogus block within slub page. */
+
#include <linux/kasan.h>
struct mem_cgroup;
@@ -188,6 +197,7 @@ size_t __ksize(const void *);
size_t ksize(const void *);
void *kmem_cache_last_alloc(struct kmem_cache *s, void *object);
void *kmem_last_alloc(void *object);
+const char *kmem_last_alloc_errstring(void *lastalloc);
#ifdef CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR
void __check_heap_object(const void *ptr, unsigned long n, struct page *page,
diff --git a/mm/slab.c b/mm/slab.c
index 2ab93b8..1f3b263 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -3610,7 +3610,7 @@ void *kmem_cache_last_alloc(struct kmem_cache *cachep, void *object)
struct page *page;
if (!(cachep->flags & SLAB_STORE_USER))
- return NULL;
+ return ERR_PTR(-KMEM_LA_NO_DEBUG);
objp = object - obj_offset(cachep);
page = virt_to_head_page(objp);
objnr = obj_to_index(cachep, page, objp);
diff --git a/mm/slab_common.c b/mm/slab_common.c
index 3f647982..8430a14 100644
--- a/mm/slab_common.c
+++ b/mm/slab_common.c
@@ -537,6 +537,30 @@ bool slab_is_available(void)
}
/*
+ * If the pointer corresponds to a kmem_last_alloc() error, return
+ * a pointer to the corresponding string, otherwise NULL.
+ */
+const char *kmem_last_alloc_errstring(void *lastalloc)
+{
+ long klaerrno;
+ static const char * const es[] = {
+ "local memory", /* KMEM_LA_NO_PAGE - 1 */
+ "non-slab memory", /* KMEM_LA_NO_SLAB - 1 */
+ "slob doesn't do debug", /* KMEM_LA_SLOB - 1 */
+ "debugging disabled", /* KMEM_LA_NO_DEBUG - 1 */
+ "bogus slub block", /* KMEM_LA_INCONSISTENT - 1 */
+ };
+
+ if (!IS_ERR(lastalloc))
+ return NULL;
+ klaerrno = -PTR_ERR(lastalloc) - 1;
+ if (WARN_ON_ONCE(klaerrno >= ARRAY_SIZE(es)))
+ return "kmem_last_alloc error out of range";
+ return es[klaerrno];
+}
+EXPORT_SYMBOL_GPL(kmem_last_alloc_errstring);
+
+/*
* If the pointer references a slab-allocated object and if sufficient
* debugging is enabled, return the returrn address for the corresponding
* allocation. Otherwise, return NULL. Note that passing random pointers
@@ -548,10 +572,10 @@ void *kmem_last_alloc(void *object)
struct page *page;
if (!virt_addr_valid(object))
- return NULL;
+ return ERR_PTR(-KMEM_LA_NO_PAGE);
page = virt_to_head_page(object);
if (!PageSlab(page))
- return NULL;
+ return ERR_PTR(-KMEM_LA_NO_SLAB);
return kmem_cache_last_alloc(page->slab_cache, object);
}
EXPORT_SYMBOL_GPL(kmem_last_alloc);
diff --git a/mm/slob.c b/mm/slob.c
index c1f8ed7..e7d6b90 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -463,7 +463,7 @@ static void slob_free(void *block, int size)
void *kmem_cache_last_alloc(struct kmem_cache *s, void *object)
{
- return NULL;
+ return ERR_PTR(-KMEM_LA_SLOB);
}
/*
diff --git a/mm/slub.c b/mm/slub.c
index 8ed3ba2..3ddf16a 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -3928,7 +3928,7 @@ void *kmem_cache_last_alloc(struct kmem_cache *s, void *object)
struct track *trackp;
if (!(s->flags & SLAB_STORE_USER))
- return NULL;
+ return ERR_PTR(-KMEM_LA_NO_DEBUG);
page = virt_to_head_page(object);
base = page_address(page);
objp = kasan_reset_tag(object);
@@ -3936,7 +3936,7 @@ void *kmem_cache_last_alloc(struct kmem_cache *s, void *object)
objnr = obj_to_index(s, page, objp);
objp = base + s->size * objnr;
if (objp < base || objp >= base + page->objects * s->size || (objp - base) % s->size)
- return NULL;
+ return ERR_PTR(-KMEM_LA_INCONSISTENT);
trackp = get_track(s, objp, TRACK_ALLOC);
return (void *)trackp->addr;
#else
--
2.9.5
next prev parent reply other threads:[~2020-12-05 0:41 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-12-05 0:40 [PATCH RFC sl-b] Export return addresses for better diagnostics Paul E. McKenney
2020-12-05 0:40 ` [PATCH sl-b 1/6] mm: Add kmem_last_alloc() to return last allocation for memory block paulmck
2020-12-07 9:02 ` Joonsoo Kim
2020-12-07 17:25 ` Paul E. McKenney
2020-12-08 8:57 ` Joonsoo Kim
2020-12-08 15:17 ` Paul E. McKenney
2020-12-05 0:40 ` paulmck [this message]
2020-12-05 0:40 ` [PATCH sl-b 3/6] rcu: Make call_rcu() print allocation address of double-freed callback paulmck
2020-12-05 0:40 ` [PATCH sl-b 4/6] mm: Create kmem_last_alloc_stack() to provide stack trace in slub paulmck
2020-12-05 0:40 ` [PATCH sl-b 5/6] percpu_ref: Print allocator upon reference-count underflow paulmck
2020-12-05 0:40 ` [PATCH sl-b 6/6] percpu_ref: Print stack trace " paulmck
2020-12-09 1:11 ` [PATCH RFC v2 sl-b] Export return addresses etc. for better diagnostics Paul E. McKenney
2020-12-09 1:12 ` [PATCH v2 sl-b 1/5] mm: Add mem_dump_obj() to print source of memory block paulmck
2020-12-09 5:36 ` kernel test robot
2020-12-09 16:51 ` Paul E. McKenney
2020-12-09 8:17 ` Christoph Hellwig
2020-12-09 14:57 ` Paul E. McKenney
2020-12-09 17:53 ` Christoph Hellwig
2020-12-09 17:59 ` Paul E. McKenney
2020-12-09 17:28 ` Vlastimil Babka
2020-12-09 23:04 ` Paul E. McKenney
2020-12-10 10:48 ` Vlastimil Babka
2020-12-10 19:56 ` Paul E. McKenney
2020-12-10 12:04 ` Joonsoo Kim
2020-12-10 23:41 ` Paul E. McKenney
2020-12-09 1:13 ` [PATCH v2 sl-b 2/5] mm: Make mem_dump_obj() handle NULL and zero-sized pointers paulmck
2020-12-09 17:48 ` Vlastimil Babka
2020-12-10 3:25 ` Paul E. McKenney
2020-12-09 1:13 ` [PATCH v2 sl-b 3/5] mm: Make mem_dump_obj() handle vmalloc() memory paulmck
2020-12-09 17:51 ` Vlastimil Babka
2020-12-09 19:39 ` Uladzislau Rezki
2020-12-09 23:23 ` Paul E. McKenney
2020-12-10 10:49 ` Vlastimil Babka
2020-12-09 19:36 ` Uladzislau Rezki
2020-12-09 19:42 ` Paul E. McKenney
2020-12-09 20:04 ` Uladzislau Rezki
2020-12-09 1:13 ` [PATCH v2 sl-b 4/5] rcu: Make call_rcu() print mem_dump_obj() info for double-freed callback paulmck
2020-12-09 1:13 ` [PATCH v2 sl-b 5/5] percpu_ref: Dump mem_dump_obj() info upon reference-count underflow paulmck
2020-12-11 1:19 ` [PATCH RFC v2 sl-b] Export return addresses etc. for better diagnostics Paul E. McKenney
2020-12-11 1:19 ` [PATCH v3 sl-b 1/6] mm: Add mem_dump_obj() to print source of memory block paulmck
2020-12-11 2:22 ` Joonsoo Kim
2020-12-11 3:33 ` Paul E. McKenney
2020-12-11 3:42 ` Paul E. McKenney
2020-12-11 6:58 ` Joonsoo Kim
2020-12-11 16:59 ` Paul E. McKenney
2020-12-11 6:54 ` Joonsoo Kim
2020-12-11 1:19 ` [PATCH v3 sl-b 2/6] mm: Make mem_dump_obj() handle NULL and zero-sized pointers paulmck
2020-12-11 1:20 ` [PATCH v3 sl-b 3/6] mm: Make mem_dump_obj() handle vmalloc() memory paulmck
2020-12-11 1:20 ` [PATCH v3 sl-b 4/6] mm: Make mem_obj_dump() vmalloc() dumps include start and length paulmck
2020-12-11 1:20 ` [PATCH v3 sl-b 5/6] rcu: Make call_rcu() print mem_dump_obj() info for double-freed callback paulmck
2020-12-11 1:20 ` [PATCH v3 sl-b 6/6] percpu_ref: Dump mem_dump_obj() info upon reference-count underflow paulmck
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 \
--in-reply-to=20201205004057.32199-2-paulmck@kernel.org \
--to=paulmck@kernel.org \
--cc=akpm@linux-foundation.org \
--cc=cl@linux.com \
--cc=dhowells@redhat.com \
--cc=edumazet@google.com \
--cc=fweisbec@gmail.com \
--cc=iamjoonsoo.kim@lge.com \
--cc=jiangshanlai@gmail.com \
--cc=joel@joelfernandes.org \
--cc=josh@joshtriplett.org \
--cc=kernel-team@fb.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=mathieu.desnoyers@efficios.com \
--cc=mingo@kernel.org \
--cc=oleg@redhat.com \
--cc=penberg@kernel.org \
--cc=peterz@infradead.org \
--cc=rcu@vger.kernel.org \
--cc=rientjes@google.com \
--cc=rostedt@goodmis.org \
--cc=tglx@linutronix.de \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.