diff options
| -rw-r--r-- | include/linux/slub_def.h | 1 | ||||
| -rw-r--r-- | mm/slab.c | 27 | ||||
| -rw-r--r-- | mm/slob.c | 5 | ||||
| -rw-r--r-- | mm/slub.c | 45 |
4 files changed, 16 insertions, 62 deletions
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index c6c1f4a120e3..5e2e7297dfaa 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
| @@ -40,7 +40,6 @@ struct kmem_cache { | |||
| 40 | int objects; /* Number of objects in slab */ | 40 | int objects; /* Number of objects in slab */ |
| 41 | int refcount; /* Refcount for slab cache destroy */ | 41 | int refcount; /* Refcount for slab cache destroy */ |
| 42 | void (*ctor)(void *, struct kmem_cache *, unsigned long); | 42 | void (*ctor)(void *, struct kmem_cache *, unsigned long); |
| 43 | void (*dtor)(void *, struct kmem_cache *, unsigned long); | ||
| 44 | int inuse; /* Offset to metadata */ | 43 | int inuse; /* Offset to metadata */ |
| 45 | int align; /* Alignment */ | 44 | int align; /* Alignment */ |
| 46 | const char *name; /* Name (only for display!) */ | 45 | const char *name; /* Name (only for display!) */ |
| @@ -409,9 +409,6 @@ struct kmem_cache { | |||
| 409 | /* constructor func */ | 409 | /* constructor func */ |
| 410 | void (*ctor) (void *, struct kmem_cache *, unsigned long); | 410 | void (*ctor) (void *, struct kmem_cache *, unsigned long); |
| 411 | 411 | ||
| 412 | /* de-constructor func */ | ||
| 413 | void (*dtor) (void *, struct kmem_cache *, unsigned long); | ||
| 414 | |||
| 415 | /* 5) cache creation/removal */ | 412 | /* 5) cache creation/removal */ |
| 416 | const char *name; | 413 | const char *name; |
| 417 | struct list_head next; | 414 | struct list_head next; |
| @@ -1911,20 +1908,11 @@ static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) | |||
| 1911 | slab_error(cachep, "end of a freed object " | 1908 | slab_error(cachep, "end of a freed object " |
| 1912 | "was overwritten"); | 1909 | "was overwritten"); |
| 1913 | } | 1910 | } |
| 1914 | if (cachep->dtor && !(cachep->flags & SLAB_POISON)) | ||
| 1915 | (cachep->dtor) (objp + obj_offset(cachep), cachep, 0); | ||
| 1916 | } | 1911 | } |
| 1917 | } | 1912 | } |
| 1918 | #else | 1913 | #else |
| 1919 | static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) | 1914 | static void slab_destroy_objs(struct kmem_cache *cachep, struct slab *slabp) |
| 1920 | { | 1915 | { |
| 1921 | if (cachep->dtor) { | ||
| 1922 | int i; | ||
| 1923 | for (i = 0; i < cachep->num; i++) { | ||
| 1924 | void *objp = index_to_obj(cachep, slabp, i); | ||
| 1925 | (cachep->dtor) (objp, cachep, 0); | ||
| 1926 | } | ||
| 1927 | } | ||
| 1928 | } | 1916 | } |
| 1929 | #endif | 1917 | #endif |
| 1930 | 1918 | ||
| @@ -2124,7 +2112,7 @@ static int setup_cpu_cache(struct kmem_cache *cachep) | |||
| 2124 | * @align: The required alignment for the objects. | 2112 | * @align: The required alignment for the objects. |
| 2125 | * @flags: SLAB flags | 2113 | * @flags: SLAB flags |
| 2126 | * @ctor: A constructor for the objects. | 2114 | * @ctor: A constructor for the objects. |
| 2127 | * @dtor: A destructor for the objects. | 2115 | * @dtor: A destructor for the objects (not implemented anymore). |
| 2128 | * | 2116 | * |
| 2129 | * Returns a ptr to the cache on success, NULL on failure. | 2117 | * Returns a ptr to the cache on success, NULL on failure. |
| 2130 | * Cannot be called within a int, but can be interrupted. | 2118 | * Cannot be called within a int, but can be interrupted. |
| @@ -2159,7 +2147,7 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
| 2159 | * Sanity checks... these are all serious usage bugs. | 2147 | * Sanity checks... these are all serious usage bugs. |
| 2160 | */ | 2148 | */ |
| 2161 | if (!name || in_interrupt() || (size < BYTES_PER_WORD) || | 2149 | if (!name || in_interrupt() || (size < BYTES_PER_WORD) || |
| 2162 | (size > (1 << MAX_OBJ_ORDER) * PAGE_SIZE) || (dtor && !ctor)) { | 2150 | (size > (1 << MAX_OBJ_ORDER) * PAGE_SIZE) || dtor) { |
| 2163 | printk(KERN_ERR "%s: Early error in slab %s\n", __FUNCTION__, | 2151 | printk(KERN_ERR "%s: Early error in slab %s\n", __FUNCTION__, |
| 2164 | name); | 2152 | name); |
| 2165 | BUG(); | 2153 | BUG(); |
| @@ -2213,9 +2201,6 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
| 2213 | if (flags & SLAB_DESTROY_BY_RCU) | 2201 | if (flags & SLAB_DESTROY_BY_RCU) |
| 2214 | BUG_ON(flags & SLAB_POISON); | 2202 | BUG_ON(flags & SLAB_POISON); |
| 2215 | #endif | 2203 | #endif |
| 2216 | if (flags & SLAB_DESTROY_BY_RCU) | ||
| 2217 | BUG_ON(dtor); | ||
| 2218 | |||
| 2219 | /* | 2204 | /* |
| 2220 | * Always checks flags, a caller might be expecting debug support which | 2205 | * Always checks flags, a caller might be expecting debug support which |
| 2221 | * isn't available. | 2206 | * isn't available. |
| @@ -2370,7 +2355,6 @@ kmem_cache_create (const char *name, size_t size, size_t align, | |||
| 2370 | BUG_ON(!cachep->slabp_cache); | 2355 | BUG_ON(!cachep->slabp_cache); |
| 2371 | } | 2356 | } |
| 2372 | cachep->ctor = ctor; | 2357 | cachep->ctor = ctor; |
| 2373 | cachep->dtor = dtor; | ||
| 2374 | cachep->name = name; | 2358 | cachep->name = name; |
| 2375 | 2359 | ||
| 2376 | if (setup_cpu_cache(cachep)) { | 2360 | if (setup_cpu_cache(cachep)) { |
| @@ -2835,7 +2819,6 @@ failed: | |||
| 2835 | * Perform extra freeing checks: | 2819 | * Perform extra freeing checks: |
| 2836 | * - detect bad pointers. | 2820 | * - detect bad pointers. |
| 2837 | * - POISON/RED_ZONE checking | 2821 | * - POISON/RED_ZONE checking |
| 2838 | * - destructor calls, for caches with POISON+dtor | ||
| 2839 | */ | 2822 | */ |
| 2840 | static void kfree_debugcheck(const void *objp) | 2823 | static void kfree_debugcheck(const void *objp) |
| 2841 | { | 2824 | { |
| @@ -2894,12 +2877,6 @@ static void *cache_free_debugcheck(struct kmem_cache *cachep, void *objp, | |||
| 2894 | BUG_ON(objnr >= cachep->num); | 2877 | BUG_ON(objnr >= cachep->num); |
| 2895 | BUG_ON(objp != index_to_obj(cachep, slabp, objnr)); | 2878 | BUG_ON(objp != index_to_obj(cachep, slabp, objnr)); |
| 2896 | 2879 | ||
| 2897 | if (cachep->flags & SLAB_POISON && cachep->dtor) { | ||
| 2898 | /* we want to cache poison the object, | ||
| 2899 | * call the destruction callback | ||
| 2900 | */ | ||
| 2901 | cachep->dtor(objp + obj_offset(cachep), cachep, 0); | ||
| 2902 | } | ||
| 2903 | #ifdef CONFIG_DEBUG_SLAB_LEAK | 2880 | #ifdef CONFIG_DEBUG_SLAB_LEAK |
| 2904 | slab_bufctl(slabp)[objnr] = BUFCTL_FREE; | 2881 | slab_bufctl(slabp)[objnr] = BUFCTL_FREE; |
| 2905 | #endif | 2882 | #endif |
| @@ -280,7 +280,6 @@ struct kmem_cache { | |||
| 280 | unsigned long flags; | 280 | unsigned long flags; |
| 281 | const char *name; | 281 | const char *name; |
| 282 | void (*ctor)(void *, struct kmem_cache *, unsigned long); | 282 | void (*ctor)(void *, struct kmem_cache *, unsigned long); |
| 283 | void (*dtor)(void *, struct kmem_cache *, unsigned long); | ||
| 284 | }; | 283 | }; |
| 285 | 284 | ||
| 286 | struct kmem_cache *kmem_cache_create(const char *name, size_t size, | 285 | struct kmem_cache *kmem_cache_create(const char *name, size_t size, |
| @@ -296,13 +295,11 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, | |||
| 296 | c->name = name; | 295 | c->name = name; |
| 297 | c->size = size; | 296 | c->size = size; |
| 298 | if (flags & SLAB_DESTROY_BY_RCU) { | 297 | if (flags & SLAB_DESTROY_BY_RCU) { |
| 299 | BUG_ON(dtor); | ||
| 300 | /* leave room for rcu footer at the end of object */ | 298 | /* leave room for rcu footer at the end of object */ |
| 301 | c->size += sizeof(struct slob_rcu); | 299 | c->size += sizeof(struct slob_rcu); |
| 302 | } | 300 | } |
| 303 | c->flags = flags; | 301 | c->flags = flags; |
| 304 | c->ctor = ctor; | 302 | c->ctor = ctor; |
| 305 | c->dtor = dtor; | ||
| 306 | /* ignore alignment unless it's forced */ | 303 | /* ignore alignment unless it's forced */ |
| 307 | c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0; | 304 | c->align = (flags & SLAB_HWCACHE_ALIGN) ? SLOB_ALIGN : 0; |
| 308 | if (c->align < align) | 305 | if (c->align < align) |
| @@ -371,8 +368,6 @@ void kmem_cache_free(struct kmem_cache *c, void *b) | |||
| 371 | slob_rcu->size = c->size; | 368 | slob_rcu->size = c->size; |
| 372 | call_rcu(&slob_rcu->head, kmem_rcu_free); | 369 | call_rcu(&slob_rcu->head, kmem_rcu_free); |
| 373 | } else { | 370 | } else { |
| 374 | if (c->dtor) | ||
| 375 | c->dtor(b, c, 0); | ||
| 376 | __kmem_cache_free(b, c->size); | 371 | __kmem_cache_free(b, c->size); |
| 377 | } | 372 | } |
| 378 | } | 373 | } |
| @@ -891,13 +891,13 @@ static void kmem_cache_open_debug_check(struct kmem_cache *s) | |||
| 891 | * On 32 bit platforms the limit is 256k. On 64bit platforms | 891 | * On 32 bit platforms the limit is 256k. On 64bit platforms |
| 892 | * the limit is 512k. | 892 | * the limit is 512k. |
| 893 | * | 893 | * |
| 894 | * Debugging or ctor/dtors may create a need to move the free | 894 | * Debugging or ctor may create a need to move the free |
| 895 | * pointer. Fail if this happens. | 895 | * pointer. Fail if this happens. |
| 896 | */ | 896 | */ |
| 897 | if (s->size >= 65535 * sizeof(void *)) { | 897 | if (s->size >= 65535 * sizeof(void *)) { |
| 898 | BUG_ON(s->flags & (SLAB_RED_ZONE | SLAB_POISON | | 898 | BUG_ON(s->flags & (SLAB_RED_ZONE | SLAB_POISON | |
| 899 | SLAB_STORE_USER | SLAB_DESTROY_BY_RCU)); | 899 | SLAB_STORE_USER | SLAB_DESTROY_BY_RCU)); |
| 900 | BUG_ON(s->ctor || s->dtor); | 900 | BUG_ON(s->ctor); |
| 901 | } | 901 | } |
| 902 | else | 902 | else |
| 903 | /* | 903 | /* |
| @@ -1030,15 +1030,12 @@ static void __free_slab(struct kmem_cache *s, struct page *page) | |||
| 1030 | { | 1030 | { |
| 1031 | int pages = 1 << s->order; | 1031 | int pages = 1 << s->order; |
| 1032 | 1032 | ||
| 1033 | if (unlikely(SlabDebug(page) || s->dtor)) { | 1033 | if (unlikely(SlabDebug(page))) { |
| 1034 | void *p; | 1034 | void *p; |
| 1035 | 1035 | ||
| 1036 | slab_pad_check(s, page); | 1036 | slab_pad_check(s, page); |
| 1037 | for_each_object(p, s, page_address(page)) { | 1037 | for_each_object(p, s, page_address(page)) |
| 1038 | if (s->dtor) | ||
| 1039 | s->dtor(p, s, 0); | ||
| 1040 | check_object(s, page, p, 0); | 1038 | check_object(s, page, p, 0); |
| 1041 | } | ||
| 1042 | } | 1039 | } |
| 1043 | 1040 | ||
| 1044 | mod_zone_page_state(page_zone(page), | 1041 | mod_zone_page_state(page_zone(page), |
| @@ -1871,7 +1868,7 @@ static int calculate_sizes(struct kmem_cache *s) | |||
| 1871 | * then we should never poison the object itself. | 1868 | * then we should never poison the object itself. |
| 1872 | */ | 1869 | */ |
| 1873 | if ((flags & SLAB_POISON) && !(flags & SLAB_DESTROY_BY_RCU) && | 1870 | if ((flags & SLAB_POISON) && !(flags & SLAB_DESTROY_BY_RCU) && |
| 1874 | !s->ctor && !s->dtor) | 1871 | !s->ctor) |
| 1875 | s->flags |= __OBJECT_POISON; | 1872 | s->flags |= __OBJECT_POISON; |
| 1876 | else | 1873 | else |
| 1877 | s->flags &= ~__OBJECT_POISON; | 1874 | s->flags &= ~__OBJECT_POISON; |
| @@ -1901,7 +1898,7 @@ static int calculate_sizes(struct kmem_cache *s) | |||
| 1901 | 1898 | ||
| 1902 | #ifdef CONFIG_SLUB_DEBUG | 1899 | #ifdef CONFIG_SLUB_DEBUG |
| 1903 | if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) || | 1900 | if (((flags & (SLAB_DESTROY_BY_RCU | SLAB_POISON)) || |
| 1904 | s->ctor || s->dtor)) { | 1901 | s->ctor)) { |
| 1905 | /* | 1902 | /* |
| 1906 | * Relocate free pointer after the object if it is not | 1903 | * Relocate free pointer after the object if it is not |
| 1907 | * permitted to overwrite the first word of the object on | 1904 | * permitted to overwrite the first word of the object on |
| @@ -1970,13 +1967,11 @@ static int calculate_sizes(struct kmem_cache *s) | |||
| 1970 | static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags, | 1967 | static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags, |
| 1971 | const char *name, size_t size, | 1968 | const char *name, size_t size, |
| 1972 | size_t align, unsigned long flags, | 1969 | size_t align, unsigned long flags, |
| 1973 | void (*ctor)(void *, struct kmem_cache *, unsigned long), | 1970 | void (*ctor)(void *, struct kmem_cache *, unsigned long)) |
| 1974 | void (*dtor)(void *, struct kmem_cache *, unsigned long)) | ||
| 1975 | { | 1971 | { |
| 1976 | memset(s, 0, kmem_size); | 1972 | memset(s, 0, kmem_size); |
| 1977 | s->name = name; | 1973 | s->name = name; |
| 1978 | s->ctor = ctor; | 1974 | s->ctor = ctor; |
| 1979 | s->dtor = dtor; | ||
| 1980 | s->objsize = size; | 1975 | s->objsize = size; |
| 1981 | s->flags = flags; | 1976 | s->flags = flags; |
| 1982 | s->align = align; | 1977 | s->align = align; |
| @@ -2161,7 +2156,7 @@ static struct kmem_cache *create_kmalloc_cache(struct kmem_cache *s, | |||
| 2161 | 2156 | ||
| 2162 | down_write(&slub_lock); | 2157 | down_write(&slub_lock); |
| 2163 | if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN, | 2158 | if (!kmem_cache_open(s, gfp_flags, name, size, ARCH_KMALLOC_MINALIGN, |
| 2164 | flags, NULL, NULL)) | 2159 | flags, NULL)) |
| 2165 | goto panic; | 2160 | goto panic; |
| 2166 | 2161 | ||
| 2167 | list_add(&s->list, &slab_caches); | 2162 | list_add(&s->list, &slab_caches); |
| @@ -2463,7 +2458,7 @@ static int slab_unmergeable(struct kmem_cache *s) | |||
| 2463 | if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE)) | 2458 | if (slub_nomerge || (s->flags & SLUB_NEVER_MERGE)) |
| 2464 | return 1; | 2459 | return 1; |
| 2465 | 2460 | ||
| 2466 | if (s->ctor || s->dtor) | 2461 | if (s->ctor) |
| 2467 | return 1; | 2462 | return 1; |
| 2468 | 2463 | ||
| 2469 | return 0; | 2464 | return 0; |
| @@ -2471,15 +2466,14 @@ static int slab_unmergeable(struct kmem_cache *s) | |||
| 2471 | 2466 | ||
| 2472 | static struct kmem_cache *find_mergeable(size_t size, | 2467 | static struct kmem_cache *find_mergeable(size_t size, |
| 2473 | size_t align, unsigned long flags, | 2468 | size_t align, unsigned long flags, |
| 2474 | void (*ctor)(void *, struct kmem_cache *, unsigned long), | 2469 | void (*ctor)(void *, struct kmem_cache *, unsigned long)) |
| 2475 | void (*dtor)(void *, struct kmem_cache *, unsigned long)) | ||
| 2476 | { | 2470 | { |
| 2477 | struct list_head *h; | 2471 | struct list_head *h; |
| 2478 | 2472 | ||
| 2479 | if (slub_nomerge || (flags & SLUB_NEVER_MERGE)) | 2473 | if (slub_nomerge || (flags & SLUB_NEVER_MERGE)) |
| 2480 | return NULL; | 2474 | return NULL; |
| 2481 | 2475 | ||
| 2482 | if (ctor || dtor) | 2476 | if (ctor) |
| 2483 | return NULL; | 2477 | return NULL; |
| 2484 | 2478 | ||
| 2485 | size = ALIGN(size, sizeof(void *)); | 2479 | size = ALIGN(size, sizeof(void *)); |
| @@ -2521,8 +2515,9 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, | |||
| 2521 | { | 2515 | { |
| 2522 | struct kmem_cache *s; | 2516 | struct kmem_cache *s; |
| 2523 | 2517 | ||
| 2518 | BUG_ON(dtor); | ||
| 2524 | down_write(&slub_lock); | 2519 | down_write(&slub_lock); |
| 2525 | s = find_mergeable(size, align, flags, ctor, dtor); | 2520 | s = find_mergeable(size, align, flags, ctor); |
| 2526 | if (s) { | 2521 | if (s) { |
| 2527 | s->refcount++; | 2522 | s->refcount++; |
| 2528 | /* | 2523 | /* |
| @@ -2536,7 +2531,7 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, | |||
| 2536 | } else { | 2531 | } else { |
| 2537 | s = kmalloc(kmem_size, GFP_KERNEL); | 2532 | s = kmalloc(kmem_size, GFP_KERNEL); |
| 2538 | if (s && kmem_cache_open(s, GFP_KERNEL, name, | 2533 | if (s && kmem_cache_open(s, GFP_KERNEL, name, |
| 2539 | size, align, flags, ctor, dtor)) { | 2534 | size, align, flags, ctor)) { |
| 2540 | if (sysfs_slab_add(s)) { | 2535 | if (sysfs_slab_add(s)) { |
| 2541 | kfree(s); | 2536 | kfree(s); |
| 2542 | goto err; | 2537 | goto err; |
| @@ -3177,17 +3172,6 @@ static ssize_t ctor_show(struct kmem_cache *s, char *buf) | |||
| 3177 | } | 3172 | } |
| 3178 | SLAB_ATTR_RO(ctor); | 3173 | SLAB_ATTR_RO(ctor); |
| 3179 | 3174 | ||
| 3180 | static ssize_t dtor_show(struct kmem_cache *s, char *buf) | ||
| 3181 | { | ||
| 3182 | if (s->dtor) { | ||
| 3183 | int n = sprint_symbol(buf, (unsigned long)s->dtor); | ||
| 3184 | |||
| 3185 | return n + sprintf(buf + n, "\n"); | ||
| 3186 | } | ||
| 3187 | return 0; | ||
| 3188 | } | ||
| 3189 | SLAB_ATTR_RO(dtor); | ||
| 3190 | |||
| 3191 | static ssize_t aliases_show(struct kmem_cache *s, char *buf) | 3175 | static ssize_t aliases_show(struct kmem_cache *s, char *buf) |
| 3192 | { | 3176 | { |
| 3193 | return sprintf(buf, "%d\n", s->refcount - 1); | 3177 | return sprintf(buf, "%d\n", s->refcount - 1); |
| @@ -3419,7 +3403,6 @@ static struct attribute * slab_attrs[] = { | |||
| 3419 | &partial_attr.attr, | 3403 | &partial_attr.attr, |
| 3420 | &cpu_slabs_attr.attr, | 3404 | &cpu_slabs_attr.attr, |
| 3421 | &ctor_attr.attr, | 3405 | &ctor_attr.attr, |
| 3422 | &dtor_attr.attr, | ||
| 3423 | &aliases_attr.attr, | 3406 | &aliases_attr.attr, |
| 3424 | &align_attr.attr, | 3407 | &align_attr.attr, |
| 3425 | &sanity_checks_attr.attr, | 3408 | &sanity_checks_attr.attr, |
