We have interesting deadlocks when slab decides to use order-1 allocations for ext3_inode_cache. This is because ext3_alloc_inode() needs to perform a GFP_NOFS 1-order allocation. Sometimes the 1-order allocation needs to free a huge number of pages (tens of megabytes) before a 1-order grouping becomes available. But the GFP_NOFS allocator cannot free dcache (and hence icache) due to the deadlock problems identified in shrink_dcache_memory(). So change slab so that it will force 0-order allocations for shrinkable VFS objects. We can handle those OK. --- 25-akpm/mm/slab.c | 74 ++++++++++++++++++++++++++++++++---------------------- 1 files changed, 44 insertions(+), 30 deletions(-) diff -puN mm/slab.c~slab-order-0-for-vfs-caches mm/slab.c --- 25/mm/slab.c~slab-order-0-for-vfs-caches 2004-04-22 23:11:34.118371752 -0700 +++ 25-akpm/mm/slab.c 2004-04-22 23:20:01.615220504 -0700 @@ -1220,41 +1220,55 @@ kmem_cache_create (const char *name, siz size = ALIGN(size, align); - /* Cal size (in pages) of slabs, and the num of objs per slab. - * This could be made much more intelligent. For now, try to avoid - * using high page-orders for slabs. When the gfp() funcs are more - * friendly towards high-order requests, this should be changed. - */ - do { - unsigned int break_flag = 0; -cal_wastage: + if ((flags & SLAB_RECLAIM_ACCOUNT) && size <= PAGE_SIZE) { + /* + * A VFS-reclaimable slab tends to have most allocations + * as GFP_NOFS and we really don't want to have to be allocating + * higher-order pages when we are unable to shrink dcache. + */ + cachep->gfporder = 0; cache_estimate(cachep->gfporder, size, align, flags, - &left_over, &cachep->num); - if (break_flag) - break; - if (cachep->gfporder >= MAX_GFP_ORDER) - break; - if (!cachep->num) - goto next; - if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) { - /* Oops, this num of objs will cause problems. */ - cachep->gfporder--; - break_flag++; - goto cal_wastage; - } - + &left_over, &cachep->num); + } else { /* - * Large num of objs is good, but v. large slabs are currently - * bad for the gfp()s. + * Calculate size (in pages) of slabs, and the num of objs per + * slab. This could be made much more intelligent. For now, + * try to avoid using high page-orders for slabs. When the + * gfp() funcs are more friendly towards high-order requests, + * this should be changed. */ - if (cachep->gfporder >= slab_break_gfp_order) - break; + do { + unsigned int break_flag = 0; +cal_wastage: + cache_estimate(cachep->gfporder, size, align, flags, + &left_over, &cachep->num); + if (break_flag) + break; + if (cachep->gfporder >= MAX_GFP_ORDER) + break; + if (!cachep->num) + goto next; + if (flags & CFLGS_OFF_SLAB && + cachep->num > offslab_limit) { + /* This num of objs will cause problems. */ + cachep->gfporder--; + break_flag++; + goto cal_wastage; + } - if ((left_over*8) <= (PAGE_SIZE<gfporder)) - break; /* Acceptable internal fragmentation. */ + /* + * Large num of objs is good, but v. large slabs are + * currently bad for the gfp()s. + */ + if (cachep->gfporder >= slab_break_gfp_order) + break; + + if ((left_over*8) <= (PAGE_SIZE<gfporder)) + break; /* Acceptable internal fragmentation. */ next: - cachep->gfporder++; - } while (1); + cachep->gfporder++; + } while (1); + } if (!cachep->num) { printk("kmem_cache_create: couldn't create cache %s.\n", name); _