Re: stack overflow

Mark Hemment
2000-09-05T10:55:32Z

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1525 bytes --]

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
>

[-- Attachment #2: slab.patch --]
[-- Type: TEXT/PLAIN, Size: 1152 bytes --]

--- 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,