@@ -183,9 +183,6 @@ static bool pfmemalloc_active __read_mostly;
183
183
*/
184
184
185
185
typedef unsigned int kmem_bufctl_t ;
186
- #define BUFCTL_END (((kmem_bufctl_t)(~0U))-0)
187
- #define BUFCTL_FREE (((kmem_bufctl_t)(~0U))-1)
188
- #define BUFCTL_ACTIVE (((kmem_bufctl_t)(~0U))-2)
189
186
#define SLAB_LIMIT (((kmem_bufctl_t)(~0U))-3)
190
187
191
188
/*
@@ -2653,9 +2650,8 @@ static void cache_init_objs(struct kmem_cache *cachep,
2653
2650
if (cachep -> ctor )
2654
2651
cachep -> ctor (objp );
2655
2652
#endif
2656
- slab_bufctl (slabp )[i ] = i + 1 ;
2653
+ slab_bufctl (slabp )[i ] = i ;
2657
2654
}
2658
- slab_bufctl (slabp )[i - 1 ] = BUFCTL_END ;
2659
2655
}
2660
2656
2661
2657
static void kmem_flagcheck (struct kmem_cache * cachep , gfp_t flags )
@@ -2671,16 +2667,14 @@ static void kmem_flagcheck(struct kmem_cache *cachep, gfp_t flags)
2671
2667
static void * slab_get_obj (struct kmem_cache * cachep , struct slab * slabp ,
2672
2668
int nodeid )
2673
2669
{
2674
- void * objp = index_to_obj (cachep , slabp , slabp -> free );
2675
- kmem_bufctl_t next ;
2670
+ void * objp ;
2676
2671
2677
2672
slabp -> inuse ++ ;
2678
- next = slab_bufctl (slabp )[slabp -> free ];
2673
+ objp = index_to_obj ( cachep , slabp , slab_bufctl (slabp )[slabp -> free ]) ;
2679
2674
#if DEBUG
2680
- slab_bufctl (slabp )[slabp -> free ] = BUFCTL_FREE ;
2681
2675
WARN_ON (page_to_nid (virt_to_page (objp )) != nodeid );
2682
2676
#endif
2683
- slabp -> free = next ;
2677
+ slabp -> free ++ ;
2684
2678
2685
2679
return objp ;
2686
2680
}
@@ -2689,19 +2683,23 @@ static void slab_put_obj(struct kmem_cache *cachep, struct slab *slabp,
2689
2683
void * objp , int nodeid )
2690
2684
{
2691
2685
unsigned int objnr = obj_to_index (cachep , slabp , objp );
2692
-
2693
2686
#if DEBUG
2687
+ kmem_bufctl_t i ;
2688
+
2694
2689
/* Verify that the slab belongs to the intended node */
2695
2690
WARN_ON (page_to_nid (virt_to_page (objp )) != nodeid );
2696
2691
2697
- if (slab_bufctl (slabp )[objnr ] + 1 <= SLAB_LIMIT + 1 ) {
2698
- printk (KERN_ERR "slab: double free detected in cache "
2699
- "'%s', objp %p\n" , cachep -> name , objp );
2700
- BUG ();
2692
+ /* Verify double free bug */
2693
+ for (i = slabp -> free ; i < cachep -> num ; i ++ ) {
2694
+ if (slab_bufctl (slabp )[i ] == objnr ) {
2695
+ printk (KERN_ERR "slab: double free detected in cache "
2696
+ "'%s', objp %p\n" , cachep -> name , objp );
2697
+ BUG ();
2698
+ }
2701
2699
}
2702
2700
#endif
2703
- slab_bufctl ( slabp )[ objnr ] = slabp -> free ;
2704
- slabp -> free = objnr ;
2701
+ slabp -> free -- ;
2702
+ slab_bufctl ( slabp )[ slabp -> free ] = objnr ;
2705
2703
slabp -> inuse -- ;
2706
2704
}
2707
2705
@@ -2862,9 +2860,6 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
2862
2860
BUG_ON (objnr >= cachep -> num );
2863
2861
BUG_ON (objp != index_to_obj (cachep , slabp , objnr ));
2864
2862
2865
- #ifdef CONFIG_DEBUG_SLAB_LEAK
2866
- slab_bufctl (slabp )[objnr ] = BUFCTL_FREE ;
2867
- #endif
2868
2863
if (cachep -> flags & SLAB_POISON ) {
2869
2864
#ifdef CONFIG_DEBUG_PAGEALLOC
2870
2865
if ((cachep -> size % PAGE_SIZE )== 0 && OFF_SLAB (cachep )) {
@@ -2881,33 +2876,9 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp,
2881
2876
return objp ;
2882
2877
}
2883
2878
2884
- static void check_slabp (struct kmem_cache * cachep , struct slab * slabp )
2885
- {
2886
- kmem_bufctl_t i ;
2887
- int entries = 0 ;
2888
-
2889
- /* Check slab's freelist to see if this obj is there. */
2890
- for (i = slabp -> free ; i != BUFCTL_END ; i = slab_bufctl (slabp )[i ]) {
2891
- entries ++ ;
2892
- if (entries > cachep -> num || i >= cachep -> num )
2893
- goto bad ;
2894
- }
2895
- if (entries != cachep -> num - slabp -> inuse ) {
2896
- bad :
2897
- printk (KERN_ERR "slab: Internal list corruption detected in "
2898
- "cache '%s'(%d), slabp %p(%d). Tainted(%s). Hexdump:\n" ,
2899
- cachep -> name , cachep -> num , slabp , slabp -> inuse ,
2900
- print_tainted ());
2901
- print_hex_dump (KERN_ERR , "" , DUMP_PREFIX_OFFSET , 16 , 1 , slabp ,
2902
- sizeof (* slabp ) + cachep -> num * sizeof (kmem_bufctl_t ),
2903
- 1 );
2904
- BUG ();
2905
- }
2906
- }
2907
2879
#else
2908
2880
#define kfree_debugcheck (x ) do { } while(0)
2909
2881
#define cache_free_debugcheck (x ,objp ,z ) (objp)
2910
- #define check_slabp (x ,y ) do { } while(0)
2911
2882
#endif
2912
2883
2913
2884
static void * cache_alloc_refill (struct kmem_cache * cachep , gfp_t flags ,
@@ -2957,7 +2928,6 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags,
2957
2928
}
2958
2929
2959
2930
slabp = list_entry (entry , struct slab , list );
2960
- check_slabp (cachep , slabp );
2961
2931
check_spinlock_acquired (cachep );
2962
2932
2963
2933
/*
@@ -2975,11 +2945,10 @@ static void *cache_alloc_refill(struct kmem_cache *cachep, gfp_t flags,
2975
2945
ac_put_obj (cachep , ac , slab_get_obj (cachep , slabp ,
2976
2946
node ));
2977
2947
}
2978
- check_slabp (cachep , slabp );
2979
2948
2980
2949
/* move slabp to correct slabp list: */
2981
2950
list_del (& slabp -> list );
2982
- if (slabp -> free == BUFCTL_END )
2951
+ if (slabp -> free == cachep -> num )
2983
2952
list_add (& slabp -> list , & n -> slabs_full );
2984
2953
else
2985
2954
list_add (& slabp -> list , & n -> slabs_partial );
@@ -3054,16 +3023,6 @@ static void *cache_alloc_debugcheck_after(struct kmem_cache *cachep,
3054
3023
* dbg_redzone1 (cachep , objp ) = RED_ACTIVE ;
3055
3024
* dbg_redzone2 (cachep , objp ) = RED_ACTIVE ;
3056
3025
}
3057
- #ifdef CONFIG_DEBUG_SLAB_LEAK
3058
- {
3059
- struct slab * slabp ;
3060
- unsigned objnr ;
3061
-
3062
- slabp = virt_to_slab (objp );
3063
- objnr = (unsigned )(objp - slabp -> s_mem ) / cachep -> size ;
3064
- slab_bufctl (slabp )[objnr ] = BUFCTL_ACTIVE ;
3065
- }
3066
- #endif
3067
3026
objp += obj_offset (cachep );
3068
3027
if (cachep -> ctor && cachep -> flags & SLAB_POISON )
3069
3028
cachep -> ctor (objp );
@@ -3269,7 +3228,6 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
3269
3228
3270
3229
slabp = list_entry (entry , struct slab , list );
3271
3230
check_spinlock_acquired_node (cachep , nodeid );
3272
- check_slabp (cachep , slabp );
3273
3231
3274
3232
STATS_INC_NODEALLOCS (cachep );
3275
3233
STATS_INC_ACTIVE (cachep );
@@ -3278,12 +3236,11 @@ static void *____cache_alloc_node(struct kmem_cache *cachep, gfp_t flags,
3278
3236
BUG_ON (slabp -> inuse == cachep -> num );
3279
3237
3280
3238
obj = slab_get_obj (cachep , slabp , nodeid );
3281
- check_slabp (cachep , slabp );
3282
3239
n -> free_objects -- ;
3283
3240
/* move slabp to correct slabp list: */
3284
3241
list_del (& slabp -> list );
3285
3242
3286
- if (slabp -> free == BUFCTL_END )
3243
+ if (slabp -> free == cachep -> num )
3287
3244
list_add (& slabp -> list , & n -> slabs_full );
3288
3245
else
3289
3246
list_add (& slabp -> list , & n -> slabs_partial );
@@ -3445,11 +3402,9 @@ static void free_block(struct kmem_cache *cachep, void **objpp, int nr_objects,
3445
3402
n = cachep -> node [node ];
3446
3403
list_del (& slabp -> list );
3447
3404
check_spinlock_acquired_node (cachep , node );
3448
- check_slabp (cachep , slabp );
3449
3405
slab_put_obj (cachep , slabp , objp , node );
3450
3406
STATS_DEC_ACTIVE (cachep );
3451
3407
n -> free_objects ++ ;
3452
- check_slabp (cachep , slabp );
3453
3408
3454
3409
/* fixup slab chains */
3455
3410
if (slabp -> inuse == 0 ) {
@@ -4308,12 +4263,23 @@ static inline int add_caller(unsigned long *n, unsigned long v)
4308
4263
static void handle_slab (unsigned long * n , struct kmem_cache * c , struct slab * s )
4309
4264
{
4310
4265
void * p ;
4311
- int i ;
4266
+ int i , j ;
4267
+
4312
4268
if (n [0 ] == n [1 ])
4313
4269
return ;
4314
4270
for (i = 0 , p = s -> s_mem ; i < c -> num ; i ++ , p += c -> size ) {
4315
- if (slab_bufctl (s )[i ] != BUFCTL_ACTIVE )
4271
+ bool active = true;
4272
+
4273
+ for (j = s -> free ; j < c -> num ; j ++ ) {
4274
+ /* Skip freed item */
4275
+ if (slab_bufctl (s )[j ] == i ) {
4276
+ active = false;
4277
+ break ;
4278
+ }
4279
+ }
4280
+ if (!active )
4316
4281
continue ;
4282
+
4317
4283
if (!add_caller (n , (unsigned long )* dbg_userword (c , p )))
4318
4284
return ;
4319
4285
}
0 commit comments