diff options
author | Ben Greear <greearb@candelatech.com> | 2011-07-07 20:36:37 +0200 |
---|---|---|
committer | Pekka Enberg <penberg@kernel.org> | 2011-07-07 21:17:08 +0200 |
commit | d18a90dd85f8243ed20cdadb6d8a37d595df456d (patch) | |
tree | 35830bc434bfdb18605ff493b0a1406c3dcf8ac0 /mm/slub.c | |
parent | slub: Enable backtrace for create/delete points (diff) | |
download | linux-d18a90dd85f8243ed20cdadb6d8a37d595df456d.tar.xz linux-d18a90dd85f8243ed20cdadb6d8a37d595df456d.zip |
slub: Add method to verify memory is not freed
This is for tracking down suspect memory usage.
Acked-by: Christoph Lameter <cl@linux.com>
Signed-off-by: Ben Greear <greearb@candelatech.com>
Signed-off-by: Pekka Enberg <penberg@kernel.org>
Diffstat (limited to 'mm/slub.c')
-rw-r--r-- | mm/slub.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/mm/slub.c b/mm/slub.c index c9050995bc87..0e4f4f8245bc 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -2964,6 +2964,42 @@ size_t ksize(const void *object) } EXPORT_SYMBOL(ksize); +#ifdef CONFIG_SLUB_DEBUG +bool verify_mem_not_deleted(const void *x) +{ + struct page *page; + void *object = (void *)x; + unsigned long flags; + bool rv; + + if (unlikely(ZERO_OR_NULL_PTR(x))) + return false; + + local_irq_save(flags); + + page = virt_to_head_page(x); + if (unlikely(!PageSlab(page))) { + /* maybe it was from stack? */ + rv = true; + goto out_unlock; + } + + slab_lock(page); + if (on_freelist(page->slab, page, object)) { + object_err(page->slab, page, object, "Object is on free-list"); + rv = false; + } else { + rv = true; + } + slab_unlock(page); + +out_unlock: + local_irq_restore(flags); + return rv; +} +EXPORT_SYMBOL(verify_mem_not_deleted); +#endif + void kfree(const void *x) { struct page *page; |