aboutsummaryrefslogtreecommitdiffstats
path: root/mm/slub.c
diff options
context:
space:
mode:
Diffstat (limited to 'mm/slub.c')
-rw-r--r--mm/slub.c94
1 files changed, 59 insertions, 35 deletions
diff --git a/mm/slub.c b/mm/slub.c
index 744d29b43bf6..9cde663bbb10 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -160,7 +160,7 @@ static inline bool kmem_cache_has_cpu_partial(struct kmem_cache *s)
160 */ 160 */
161#define MAX_PARTIAL 10 161#define MAX_PARTIAL 10
162 162
163#define DEBUG_DEFAULT_FLAGS (SLAB_DEBUG_FREE | SLAB_RED_ZONE | \ 163#define DEBUG_DEFAULT_FLAGS (SLAB_CONSISTENCY_CHECKS | SLAB_RED_ZONE | \
164 SLAB_POISON | SLAB_STORE_USER) 164 SLAB_POISON | SLAB_STORE_USER)
165 165
166/* 166/*
@@ -1007,20 +1007,32 @@ static void setup_object_debug(struct kmem_cache *s, struct page *page,
1007 init_tracking(s, object); 1007 init_tracking(s, object);
1008} 1008}
1009 1009
1010static noinline int alloc_debug_processing(struct kmem_cache *s, 1010static inline int alloc_consistency_checks(struct kmem_cache *s,
1011 struct page *page, 1011 struct page *page,
1012 void *object, unsigned long addr) 1012 void *object, unsigned long addr)
1013{ 1013{
1014 if (!check_slab(s, page)) 1014 if (!check_slab(s, page))
1015 goto bad; 1015 return 0;
1016 1016
1017 if (!check_valid_pointer(s, page, object)) { 1017 if (!check_valid_pointer(s, page, object)) {
1018 object_err(s, page, object, "Freelist Pointer check fails"); 1018 object_err(s, page, object, "Freelist Pointer check fails");
1019 goto bad; 1019 return 0;
1020 } 1020 }
1021 1021
1022 if (!check_object(s, page, object, SLUB_RED_INACTIVE)) 1022 if (!check_object(s, page, object, SLUB_RED_INACTIVE))
1023 goto bad; 1023 return 0;
1024
1025 return 1;
1026}
1027
1028static noinline int alloc_debug_processing(struct kmem_cache *s,
1029 struct page *page,
1030 void *object, unsigned long addr)
1031{
1032 if (s->flags & SLAB_CONSISTENCY_CHECKS) {
1033 if (!alloc_consistency_checks(s, page, object, addr))
1034 goto bad;
1035 }
1024 1036
1025 /* Success perform special debug activities for allocs */ 1037 /* Success perform special debug activities for allocs */
1026 if (s->flags & SLAB_STORE_USER) 1038 if (s->flags & SLAB_STORE_USER)
@@ -1043,39 +1055,21 @@ bad:
1043 return 0; 1055 return 0;
1044} 1056}
1045 1057
1046/* Supports checking bulk free of a constructed freelist */ 1058static inline int free_consistency_checks(struct kmem_cache *s,
1047static noinline int free_debug_processing( 1059 struct page *page, void *object, unsigned long addr)
1048 struct kmem_cache *s, struct page *page,
1049 void *head, void *tail, int bulk_cnt,
1050 unsigned long addr)
1051{ 1060{
1052 struct kmem_cache_node *n = get_node(s, page_to_nid(page));
1053 void *object = head;
1054 int cnt = 0;
1055 unsigned long uninitialized_var(flags);
1056 int ret = 0;
1057
1058 spin_lock_irqsave(&n->list_lock, flags);
1059 slab_lock(page);
1060
1061 if (!check_slab(s, page))
1062 goto out;
1063
1064next_object:
1065 cnt++;
1066
1067 if (!check_valid_pointer(s, page, object)) { 1061 if (!check_valid_pointer(s, page, object)) {
1068 slab_err(s, page, "Invalid object pointer 0x%p", object); 1062 slab_err(s, page, "Invalid object pointer 0x%p", object);
1069 goto out; 1063 return 0;
1070 } 1064 }
1071 1065
1072 if (on_freelist(s, page, object)) { 1066 if (on_freelist(s, page, object)) {
1073 object_err(s, page, object, "Object already free"); 1067 object_err(s, page, object, "Object already free");
1074 goto out; 1068 return 0;
1075 } 1069 }
1076 1070
1077 if (!check_object(s, page, object, SLUB_RED_ACTIVE)) 1071 if (!check_object(s, page, object, SLUB_RED_ACTIVE))
1078 goto out; 1072 return 0;
1079 1073
1080 if (unlikely(s != page->slab_cache)) { 1074 if (unlikely(s != page->slab_cache)) {
1081 if (!PageSlab(page)) { 1075 if (!PageSlab(page)) {
@@ -1088,7 +1082,37 @@ next_object:
1088 } else 1082 } else
1089 object_err(s, page, object, 1083 object_err(s, page, object,
1090 "page slab pointer corrupt."); 1084 "page slab pointer corrupt.");
1091 goto out; 1085 return 0;
1086 }
1087 return 1;
1088}
1089
1090/* Supports checking bulk free of a constructed freelist */
1091static noinline int free_debug_processing(
1092 struct kmem_cache *s, struct page *page,
1093 void *head, void *tail, int bulk_cnt,
1094 unsigned long addr)
1095{
1096 struct kmem_cache_node *n = get_node(s, page_to_nid(page));
1097 void *object = head;
1098 int cnt = 0;
1099 unsigned long uninitialized_var(flags);
1100 int ret = 0;
1101
1102 spin_lock_irqsave(&n->list_lock, flags);
1103 slab_lock(page);
1104
1105 if (s->flags & SLAB_CONSISTENCY_CHECKS) {
1106 if (!check_slab(s, page))
1107 goto out;
1108 }
1109
1110next_object:
1111 cnt++;
1112
1113 if (s->flags & SLAB_CONSISTENCY_CHECKS) {
1114 if (!free_consistency_checks(s, page, object, addr))
1115 goto out;
1092 } 1116 }
1093 1117
1094 if (s->flags & SLAB_STORE_USER) 1118 if (s->flags & SLAB_STORE_USER)
@@ -1145,7 +1169,7 @@ static int __init setup_slub_debug(char *str)
1145 for (; *str && *str != ','; str++) { 1169 for (; *str && *str != ','; str++) {
1146 switch (tolower(*str)) { 1170 switch (tolower(*str)) {
1147 case 'f': 1171 case 'f':
1148 slub_debug |= SLAB_DEBUG_FREE; 1172 slub_debug |= SLAB_CONSISTENCY_CHECKS;
1149 break; 1173 break;
1150 case 'z': 1174 case 'z':
1151 slub_debug |= SLAB_RED_ZONE; 1175 slub_debug |= SLAB_RED_ZONE;
@@ -1449,7 +1473,7 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
1449 int order = compound_order(page); 1473 int order = compound_order(page);
1450 int pages = 1 << order; 1474 int pages = 1 << order;
1451 1475
1452 if (kmem_cache_debug(s)) { 1476 if (s->flags & SLAB_CONSISTENCY_CHECKS) {
1453 void *p; 1477 void *p;
1454 1478
1455 slab_pad_check(s, page); 1479 slab_pad_check(s, page);
@@ -4769,16 +4793,16 @@ SLAB_ATTR_RO(total_objects);
4769 4793
4770static ssize_t sanity_checks_show(struct kmem_cache *s, char *buf) 4794static ssize_t sanity_checks_show(struct kmem_cache *s, char *buf)
4771{ 4795{
4772 return sprintf(buf, "%d\n", !!(s->flags & SLAB_DEBUG_FREE)); 4796 return sprintf(buf, "%d\n", !!(s->flags & SLAB_CONSISTENCY_CHECKS));
4773} 4797}
4774 4798
4775static ssize_t sanity_checks_store(struct kmem_cache *s, 4799static ssize_t sanity_checks_store(struct kmem_cache *s,
4776 const char *buf, size_t length) 4800 const char *buf, size_t length)
4777{ 4801{
4778 s->flags &= ~SLAB_DEBUG_FREE; 4802 s->flags &= ~SLAB_CONSISTENCY_CHECKS;
4779 if (buf[0] == '1') { 4803 if (buf[0] == '1') {
4780 s->flags &= ~__CMPXCHG_DOUBLE; 4804 s->flags &= ~__CMPXCHG_DOUBLE;
4781 s->flags |= SLAB_DEBUG_FREE; 4805 s->flags |= SLAB_CONSISTENCY_CHECKS;
4782 } 4806 }
4783 return length; 4807 return length;
4784} 4808}
@@ -5313,7 +5337,7 @@ static char *create_unique_id(struct kmem_cache *s)
5313 *p++ = 'd'; 5337 *p++ = 'd';
5314 if (s->flags & SLAB_RECLAIM_ACCOUNT) 5338 if (s->flags & SLAB_RECLAIM_ACCOUNT)
5315 *p++ = 'a'; 5339 *p++ = 'a';
5316 if (s->flags & SLAB_DEBUG_FREE) 5340 if (s->flags & SLAB_CONSISTENCY_CHECKS)
5317 *p++ = 'F'; 5341 *p++ = 'F';
5318 if (!(s->flags & SLAB_NOTRACK)) 5342 if (!(s->flags & SLAB_NOTRACK))
5319 *p++ = 't'; 5343 *p++ = 't';