diff options
Diffstat (limited to 'mm/slab.c')
-rw-r--r-- | mm/slab.c | 71 |
1 files changed, 64 insertions, 7 deletions
@@ -102,6 +102,7 @@ | |||
102 | #include <linux/cpu.h> | 102 | #include <linux/cpu.h> |
103 | #include <linux/sysctl.h> | 103 | #include <linux/sysctl.h> |
104 | #include <linux/module.h> | 104 | #include <linux/module.h> |
105 | #include <trace/kmemtrace.h> | ||
105 | #include <linux/rcupdate.h> | 106 | #include <linux/rcupdate.h> |
106 | #include <linux/string.h> | 107 | #include <linux/string.h> |
107 | #include <linux/uaccess.h> | 108 | #include <linux/uaccess.h> |
@@ -568,6 +569,14 @@ static void **dbg_userword(struct kmem_cache *cachep, void *objp) | |||
568 | 569 | ||
569 | #endif | 570 | #endif |
570 | 571 | ||
572 | #ifdef CONFIG_KMEMTRACE | ||
573 | size_t slab_buffer_size(struct kmem_cache *cachep) | ||
574 | { | ||
575 | return cachep->buffer_size; | ||
576 | } | ||
577 | EXPORT_SYMBOL(slab_buffer_size); | ||
578 | #endif | ||
579 | |||
571 | /* | 580 | /* |
572 | * Do not go above this order unless 0 objects fit into the slab. | 581 | * Do not go above this order unless 0 objects fit into the slab. |
573 | */ | 582 | */ |
@@ -3554,10 +3563,23 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp) | |||
3554 | */ | 3563 | */ |
3555 | void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) | 3564 | void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) |
3556 | { | 3565 | { |
3557 | return __cache_alloc(cachep, flags, __builtin_return_address(0)); | 3566 | void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0)); |
3567 | |||
3568 | kmemtrace_mark_alloc(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret, | ||
3569 | obj_size(cachep), cachep->buffer_size, flags); | ||
3570 | |||
3571 | return ret; | ||
3558 | } | 3572 | } |
3559 | EXPORT_SYMBOL(kmem_cache_alloc); | 3573 | EXPORT_SYMBOL(kmem_cache_alloc); |
3560 | 3574 | ||
3575 | #ifdef CONFIG_KMEMTRACE | ||
3576 | void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) | ||
3577 | { | ||
3578 | return __cache_alloc(cachep, flags, __builtin_return_address(0)); | ||
3579 | } | ||
3580 | EXPORT_SYMBOL(kmem_cache_alloc_notrace); | ||
3581 | #endif | ||
3582 | |||
3561 | /** | 3583 | /** |
3562 | * kmem_ptr_validate - check if an untrusted pointer might be a slab entry. | 3584 | * kmem_ptr_validate - check if an untrusted pointer might be a slab entry. |
3563 | * @cachep: the cache we're checking against | 3585 | * @cachep: the cache we're checking against |
@@ -3602,23 +3624,47 @@ out: | |||
3602 | #ifdef CONFIG_NUMA | 3624 | #ifdef CONFIG_NUMA |
3603 | void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) | 3625 | void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) |
3604 | { | 3626 | { |
3605 | return __cache_alloc_node(cachep, flags, nodeid, | 3627 | void *ret = __cache_alloc_node(cachep, flags, nodeid, |
3606 | __builtin_return_address(0)); | 3628 | __builtin_return_address(0)); |
3629 | |||
3630 | kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret, | ||
3631 | obj_size(cachep), cachep->buffer_size, | ||
3632 | flags, nodeid); | ||
3633 | |||
3634 | return ret; | ||
3607 | } | 3635 | } |
3608 | EXPORT_SYMBOL(kmem_cache_alloc_node); | 3636 | EXPORT_SYMBOL(kmem_cache_alloc_node); |
3609 | 3637 | ||
3638 | #ifdef CONFIG_KMEMTRACE | ||
3639 | void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, | ||
3640 | gfp_t flags, | ||
3641 | int nodeid) | ||
3642 | { | ||
3643 | return __cache_alloc_node(cachep, flags, nodeid, | ||
3644 | __builtin_return_address(0)); | ||
3645 | } | ||
3646 | EXPORT_SYMBOL(kmem_cache_alloc_node_notrace); | ||
3647 | #endif | ||
3648 | |||
3610 | static __always_inline void * | 3649 | static __always_inline void * |
3611 | __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) | 3650 | __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) |
3612 | { | 3651 | { |
3613 | struct kmem_cache *cachep; | 3652 | struct kmem_cache *cachep; |
3653 | void *ret; | ||
3614 | 3654 | ||
3615 | cachep = kmem_find_general_cachep(size, flags); | 3655 | cachep = kmem_find_general_cachep(size, flags); |
3616 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) | 3656 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) |
3617 | return cachep; | 3657 | return cachep; |
3618 | return kmem_cache_alloc_node(cachep, flags, node); | 3658 | ret = kmem_cache_alloc_node_notrace(cachep, flags, node); |
3659 | |||
3660 | kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, | ||
3661 | (unsigned long) caller, ret, | ||
3662 | size, cachep->buffer_size, flags, node); | ||
3663 | |||
3664 | return ret; | ||
3619 | } | 3665 | } |
3620 | 3666 | ||
3621 | #ifdef CONFIG_DEBUG_SLAB | 3667 | #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE) |
3622 | void *__kmalloc_node(size_t size, gfp_t flags, int node) | 3668 | void *__kmalloc_node(size_t size, gfp_t flags, int node) |
3623 | { | 3669 | { |
3624 | return __do_kmalloc_node(size, flags, node, | 3670 | return __do_kmalloc_node(size, flags, node, |
@@ -3651,6 +3697,7 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags, | |||
3651 | void *caller) | 3697 | void *caller) |
3652 | { | 3698 | { |
3653 | struct kmem_cache *cachep; | 3699 | struct kmem_cache *cachep; |
3700 | void *ret; | ||
3654 | 3701 | ||
3655 | /* If you want to save a few bytes .text space: replace | 3702 | /* If you want to save a few bytes .text space: replace |
3656 | * __ with kmem_. | 3703 | * __ with kmem_. |
@@ -3660,11 +3707,17 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags, | |||
3660 | cachep = __find_general_cachep(size, flags); | 3707 | cachep = __find_general_cachep(size, flags); |
3661 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) | 3708 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) |
3662 | return cachep; | 3709 | return cachep; |
3663 | return __cache_alloc(cachep, flags, caller); | 3710 | ret = __cache_alloc(cachep, flags, caller); |
3711 | |||
3712 | kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, | ||
3713 | (unsigned long) caller, ret, | ||
3714 | size, cachep->buffer_size, flags); | ||
3715 | |||
3716 | return ret; | ||
3664 | } | 3717 | } |
3665 | 3718 | ||
3666 | 3719 | ||
3667 | #ifdef CONFIG_DEBUG_SLAB | 3720 | #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE) |
3668 | void *__kmalloc(size_t size, gfp_t flags) | 3721 | void *__kmalloc(size_t size, gfp_t flags) |
3669 | { | 3722 | { |
3670 | return __do_kmalloc(size, flags, __builtin_return_address(0)); | 3723 | return __do_kmalloc(size, flags, __builtin_return_address(0)); |
@@ -3703,6 +3756,8 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp) | |||
3703 | debug_check_no_obj_freed(objp, obj_size(cachep)); | 3756 | debug_check_no_obj_freed(objp, obj_size(cachep)); |
3704 | __cache_free(cachep, objp); | 3757 | __cache_free(cachep, objp); |
3705 | local_irq_restore(flags); | 3758 | local_irq_restore(flags); |
3759 | |||
3760 | kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, objp); | ||
3706 | } | 3761 | } |
3707 | EXPORT_SYMBOL(kmem_cache_free); | 3762 | EXPORT_SYMBOL(kmem_cache_free); |
3708 | 3763 | ||
@@ -3729,6 +3784,8 @@ void kfree(const void *objp) | |||
3729 | debug_check_no_obj_freed(objp, obj_size(c)); | 3784 | debug_check_no_obj_freed(objp, obj_size(c)); |
3730 | __cache_free(c, (void *)objp); | 3785 | __cache_free(c, (void *)objp); |
3731 | local_irq_restore(flags); | 3786 | local_irq_restore(flags); |
3787 | |||
3788 | kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, objp); | ||
3732 | } | 3789 | } |
3733 | EXPORT_SYMBOL(kfree); | 3790 | EXPORT_SYMBOL(kfree); |
3734 | 3791 | ||