[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: stack overflow



Hi,

  A quick look indicates what could be the problem.
  In my original, the code assumes that all general purpose slabs below
"bufctl_limit" where suitable for bufctl allocation (look at a 2.2.x
version, in kmem_cache_sizes_init() I have a state variable called
"found").
  The modified code (by who?), which now uses "offslab_limit", removes
the assumption, which could very well be causing the stack overflow; the
code now breaks the comment "Inc off-slab bufctl limit until the ceiling
is hit" as it has no ceiling.
  Bringing back the state variable will close at least one door.

  I've attached a completely untested (and uncompiled) patch.

  If this doesn't fix it, I'll look deeper.

Mark



On Mon, 4 Sep 2000, Tigran Aivazian wrote:

> On Mon, 4 Sep 2000, Matti Aarnio wrote:
> > > when the function kmem_cache_sizes_init is called in
> > > /init/main.c The exact place where the stack overflow
> > > occurs is in the function kmem_cache_slabmgmt in
> > > /mm/slab.c
> > > 
> > > Is there any way to change the stack size in Kernel?
> > > Can the change in stack size simply solve this Kernel
> > > stack overflow problem?
> > 
> > 	That is indicative that somewhere along the path
> > 	you are:  a) recursin
> 
> looking at the code, it seems in theory possible to recurse via
> kmem_cache_alloc()->kmem_cache_grow()->kmem_cache_slabmgmt()->kmem_cache_alloc() but
> I thought Mark invented offslab_limit to prevent this.
> 
> Maybe decreasing offslab_limit can help? Defer to Mark...
> 
> Regards,
> Tigran
> 
--- slab.c.00	Tue Sep  5 12:49:16 2000
+++ slab.c	Tue Sep  5 12:51:36 2000
@@ -424,14 +424,17 @@
  */
 void __init kmem_cache_sizes_init(void)
 {
+	unsigned int	limit_found;
 	cache_sizes_t *sizes = cache_sizes;
 	char name[20];
+
 	/*
 	 * Fragmentation resistance on low memory - only use bigger
 	 * page orders on machines with more than 32MB of memory.
 	 */
 	if (num_physpages > (32 << 20) >> PAGE_SHIFT)
 		slab_break_gfp_order = BREAK_GFP_ORDER_HI;
+	limit_found = 0;
 	do {
 		/* For performance, all the general caches are L1 aligned.
 		 * This should be particularly beneficial on SMP boxes, as it
@@ -446,9 +449,12 @@
 		}
 
 		/* Inc off-slab bufctl limit until the ceiling is hit. */
-		if (!(OFF_SLAB(sizes->cs_cachep))) {
-			offslab_limit = sizes->cs_size-sizeof(slab_t);
-			offslab_limit /= 2;
+		if (limit_found == 0) {
+			if (!(OFF_SLAB(sizes->cs_cachep))) {
+				offslab_limit = sizes->cs_size-sizeof(slab_t);
+				offslab_limit /= 2;
+			} else
+				limit_found = 1;
 		}
 		sprintf(name, "size-%Zd(DMA)",sizes->cs_size);
 		sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0,