diff options
| -rw-r--r-- | mm/slub.c | 59 |
1 files changed, 45 insertions, 14 deletions
| @@ -211,7 +211,8 @@ static inline void ClearSlabDebug(struct page *page) | |||
| 211 | #define MAX_OBJECTS_PER_SLAB 65535 | 211 | #define MAX_OBJECTS_PER_SLAB 65535 |
| 212 | 212 | ||
| 213 | /* Internal SLUB flags */ | 213 | /* Internal SLUB flags */ |
| 214 | #define __OBJECT_POISON 0x80000000 /* Poison object */ | 214 | #define __OBJECT_POISON 0x80000000 /* Poison object */ |
| 215 | #define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */ | ||
| 215 | 216 | ||
| 216 | /* Not all arches define cache_line_size */ | 217 | /* Not all arches define cache_line_size */ |
| 217 | #ifndef cache_line_size | 218 | #ifndef cache_line_size |
| @@ -2277,10 +2278,26 @@ panic: | |||
| 2277 | } | 2278 | } |
| 2278 | 2279 | ||
| 2279 | #ifdef CONFIG_ZONE_DMA | 2280 | #ifdef CONFIG_ZONE_DMA |
| 2281 | |||
| 2282 | static void sysfs_add_func(struct work_struct *w) | ||
| 2283 | { | ||
| 2284 | struct kmem_cache *s; | ||
| 2285 | |||
| 2286 | down_write(&slub_lock); | ||
| 2287 | list_for_each_entry(s, &slab_caches, list) { | ||
| 2288 | if (s->flags & __SYSFS_ADD_DEFERRED) { | ||
| 2289 | s->flags &= ~__SYSFS_ADD_DEFERRED; | ||
| 2290 | sysfs_slab_add(s); | ||
| 2291 | } | ||
| 2292 | } | ||
| 2293 | up_write(&slub_lock); | ||
| 2294 | } | ||
| 2295 | |||
| 2296 | static DECLARE_WORK(sysfs_add_work, sysfs_add_func); | ||
| 2297 | |||
| 2280 | static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags) | 2298 | static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags) |
| 2281 | { | 2299 | { |
| 2282 | struct kmem_cache *s; | 2300 | struct kmem_cache *s; |
| 2283 | struct kmem_cache *x; | ||
| 2284 | char *text; | 2301 | char *text; |
| 2285 | size_t realsize; | 2302 | size_t realsize; |
| 2286 | 2303 | ||
| @@ -2289,22 +2306,36 @@ static noinline struct kmem_cache *dma_kmalloc_cache(int index, gfp_t flags) | |||
| 2289 | return s; | 2306 | return s; |
| 2290 | 2307 | ||
| 2291 | /* Dynamically create dma cache */ | 2308 | /* Dynamically create dma cache */ |
| 2292 | x = kmalloc(kmem_size, flags & ~SLUB_DMA); | 2309 | if (flags & __GFP_WAIT) |
| 2293 | if (!x) | 2310 | down_write(&slub_lock); |
| 2294 | panic("Unable to allocate memory for dma cache\n"); | 2311 | else { |
| 2312 | if (!down_write_trylock(&slub_lock)) | ||
| 2313 | goto out; | ||
| 2314 | } | ||
| 2315 | |||
| 2316 | if (kmalloc_caches_dma[index]) | ||
| 2317 | goto unlock_out; | ||
| 2295 | 2318 | ||
| 2296 | realsize = kmalloc_caches[index].objsize; | 2319 | realsize = kmalloc_caches[index].objsize; |
| 2297 | text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d", | 2320 | text = kasprintf(flags & ~SLUB_DMA, "kmalloc_dma-%d", (unsigned int)realsize), |
| 2298 | (unsigned int)realsize); | 2321 | s = kmalloc(kmem_size, flags & ~SLUB_DMA); |
| 2299 | s = create_kmalloc_cache(x, text, realsize, flags); | 2322 | |
| 2300 | down_write(&slub_lock); | 2323 | if (!s || !text || !kmem_cache_open(s, flags, text, |
| 2301 | if (!kmalloc_caches_dma[index]) { | 2324 | realsize, ARCH_KMALLOC_MINALIGN, |
| 2302 | kmalloc_caches_dma[index] = s; | 2325 | SLAB_CACHE_DMA|__SYSFS_ADD_DEFERRED, NULL)) { |
| 2303 | up_write(&slub_lock); | 2326 | kfree(s); |
| 2304 | return s; | 2327 | kfree(text); |
| 2328 | goto unlock_out; | ||
| 2305 | } | 2329 | } |
| 2330 | |||
| 2331 | list_add(&s->list, &slab_caches); | ||
| 2332 | kmalloc_caches_dma[index] = s; | ||
| 2333 | |||
| 2334 | schedule_work(&sysfs_add_work); | ||
| 2335 | |||
| 2336 | unlock_out: | ||
| 2306 | up_write(&slub_lock); | 2337 | up_write(&slub_lock); |
| 2307 | kmem_cache_destroy(s); | 2338 | out: |
| 2308 | return kmalloc_caches_dma[index]; | 2339 | return kmalloc_caches_dma[index]; |
| 2309 | } | 2340 | } |
| 2310 | #endif | 2341 | #endif |
