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 | */ |
@@ -3550,10 +3559,23 @@ static inline void __cache_free(struct kmem_cache *cachep, void *objp) | |||
3550 | */ | 3559 | */ |
3551 | void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) | 3560 | void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) |
3552 | { | 3561 | { |
3553 | return __cache_alloc(cachep, flags, __builtin_return_address(0)); | 3562 | void *ret = __cache_alloc(cachep, flags, __builtin_return_address(0)); |
3563 | |||
3564 | kmemtrace_mark_alloc(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret, | ||
3565 | obj_size(cachep), cachep->buffer_size, flags); | ||
3566 | |||
3567 | return ret; | ||
3554 | } | 3568 | } |
3555 | EXPORT_SYMBOL(kmem_cache_alloc); | 3569 | EXPORT_SYMBOL(kmem_cache_alloc); |
3556 | 3570 | ||
3571 | #ifdef CONFIG_KMEMTRACE | ||
3572 | void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) | ||
3573 | { | ||
3574 | return __cache_alloc(cachep, flags, __builtin_return_address(0)); | ||
3575 | } | ||
3576 | EXPORT_SYMBOL(kmem_cache_alloc_notrace); | ||
3577 | #endif | ||
3578 | |||
3557 | /** | 3579 | /** |
3558 | * kmem_ptr_validate - check if an untrusted pointer might be a slab entry. | 3580 | * kmem_ptr_validate - check if an untrusted pointer might be a slab entry. |
3559 | * @cachep: the cache we're checking against | 3581 | * @cachep: the cache we're checking against |
@@ -3598,23 +3620,47 @@ out: | |||
3598 | #ifdef CONFIG_NUMA | 3620 | #ifdef CONFIG_NUMA |
3599 | void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) | 3621 | void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) |
3600 | { | 3622 | { |
3601 | return __cache_alloc_node(cachep, flags, nodeid, | 3623 | void *ret = __cache_alloc_node(cachep, flags, nodeid, |
3602 | __builtin_return_address(0)); | 3624 | __builtin_return_address(0)); |
3625 | |||
3626 | kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_CACHE, _RET_IP_, ret, | ||
3627 | obj_size(cachep), cachep->buffer_size, | ||
3628 | flags, nodeid); | ||
3629 | |||
3630 | return ret; | ||
3603 | } | 3631 | } |
3604 | EXPORT_SYMBOL(kmem_cache_alloc_node); | 3632 | EXPORT_SYMBOL(kmem_cache_alloc_node); |
3605 | 3633 | ||
3634 | #ifdef CONFIG_KMEMTRACE | ||
3635 | void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, | ||
3636 | gfp_t flags, | ||
3637 | int nodeid) | ||
3638 | { | ||
3639 | return __cache_alloc_node(cachep, flags, nodeid, | ||
3640 | __builtin_return_address(0)); | ||
3641 | } | ||
3642 | EXPORT_SYMBOL(kmem_cache_alloc_node_notrace); | ||
3643 | #endif | ||
3644 | |||
3606 | static __always_inline void * | 3645 | static __always_inline void * |
3607 | __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) | 3646 | __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) |
3608 | { | 3647 | { |
3609 | struct kmem_cache *cachep; | 3648 | struct kmem_cache *cachep; |
3649 | void *ret; | ||
3610 | 3650 | ||
3611 | cachep = kmem_find_general_cachep(size, flags); | 3651 | cachep = kmem_find_general_cachep(size, flags); |
3612 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) | 3652 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) |
3613 | return cachep; | 3653 | return cachep; |
3614 | return kmem_cache_alloc_node(cachep, flags, node); | 3654 | ret = kmem_cache_alloc_node_notrace(cachep, flags, node); |
3655 | |||
3656 | kmemtrace_mark_alloc_node(KMEMTRACE_TYPE_KMALLOC, | ||
3657 | (unsigned long) caller, ret, | ||
3658 | size, cachep->buffer_size, flags, node); | ||
3659 | |||
3660 | return ret; | ||
3615 | } | 3661 | } |
3616 | 3662 | ||
3617 | #ifdef CONFIG_DEBUG_SLAB | 3663 | #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE) |
3618 | void *__kmalloc_node(size_t size, gfp_t flags, int node) | 3664 | void *__kmalloc_node(size_t size, gfp_t flags, int node) |
3619 | { | 3665 | { |
3620 | return __do_kmalloc_node(size, flags, node, | 3666 | return __do_kmalloc_node(size, flags, node, |
@@ -3647,6 +3693,7 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags, | |||
3647 | void *caller) | 3693 | void *caller) |
3648 | { | 3694 | { |
3649 | struct kmem_cache *cachep; | 3695 | struct kmem_cache *cachep; |
3696 | void *ret; | ||
3650 | 3697 | ||
3651 | /* If you want to save a few bytes .text space: replace | 3698 | /* If you want to save a few bytes .text space: replace |
3652 | * __ with kmem_. | 3699 | * __ with kmem_. |
@@ -3656,11 +3703,17 @@ static __always_inline void *__do_kmalloc(size_t size, gfp_t flags, | |||
3656 | cachep = __find_general_cachep(size, flags); | 3703 | cachep = __find_general_cachep(size, flags); |
3657 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) | 3704 | if (unlikely(ZERO_OR_NULL_PTR(cachep))) |
3658 | return cachep; | 3705 | return cachep; |
3659 | return __cache_alloc(cachep, flags, caller); | 3706 | ret = __cache_alloc(cachep, flags, caller); |
3707 | |||
3708 | kmemtrace_mark_alloc(KMEMTRACE_TYPE_KMALLOC, | ||
3709 | (unsigned long) caller, ret, | ||
3710 | size, cachep->buffer_size, flags); | ||
3711 | |||
3712 | return ret; | ||
3660 | } | 3713 | } |
3661 | 3714 | ||
3662 | 3715 | ||
3663 | #ifdef CONFIG_DEBUG_SLAB | 3716 | #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_KMEMTRACE) |
3664 | void *__kmalloc(size_t size, gfp_t flags) | 3717 | void *__kmalloc(size_t size, gfp_t flags) |
3665 | { | 3718 | { |
3666 | return __do_kmalloc(size, flags, __builtin_return_address(0)); | 3719 | return __do_kmalloc(size, flags, __builtin_return_address(0)); |
@@ -3699,6 +3752,8 @@ void kmem_cache_free(struct kmem_cache *cachep, void *objp) | |||
3699 | debug_check_no_obj_freed(objp, obj_size(cachep)); | 3752 | debug_check_no_obj_freed(objp, obj_size(cachep)); |
3700 | __cache_free(cachep, objp); | 3753 | __cache_free(cachep, objp); |
3701 | local_irq_restore(flags); | 3754 | local_irq_restore(flags); |
3755 | |||
3756 | kmemtrace_mark_free(KMEMTRACE_TYPE_CACHE, _RET_IP_, objp); | ||
3702 | } | 3757 | } |
3703 | EXPORT_SYMBOL(kmem_cache_free); | 3758 | EXPORT_SYMBOL(kmem_cache_free); |
3704 | 3759 | ||
@@ -3725,6 +3780,8 @@ void kfree(const void *objp) | |||
3725 | debug_check_no_obj_freed(objp, obj_size(c)); | 3780 | debug_check_no_obj_freed(objp, obj_size(c)); |
3726 | __cache_free(c, (void *)objp); | 3781 | __cache_free(c, (void *)objp); |
3727 | local_irq_restore(flags); | 3782 | local_irq_restore(flags); |
3783 | |||
3784 | kmemtrace_mark_free(KMEMTRACE_TYPE_KMALLOC, _RET_IP_, objp); | ||
3728 | } | 3785 | } |
3729 | EXPORT_SYMBOL(kfree); | 3786 | EXPORT_SYMBOL(kfree); |
3730 | 3787 | ||