Problem with the mm code in 2.1.75

Balaji Srinivasan (balaji@ittc.ukans.edu)
Sun, 4 Jan 1998 16:03:31 -0600 (CST)


Hi Everyone,

I am having some problems with the mm code in 2.1.75 kernel.
I have a swap_out function that tries to swap out all processes
that do not have a particular scheduling policy. (Since we
have a real time kernel in which real time processes are marked
having a scheduling policy of SCHED_KURT, we want to swap out
all non-SCHED_KURT processes)

This bit of code used to work upto the 2.1.62 kernel but in
2.1.75 it segfaults (it segfaults in find_vma function defined
in include/linux/mm.h)

Here is the code
------------

void swap_out_nrt(void)
{
int swap_task;
int cnt;
struct task_struct *p;
int decline;
int num_pages_swapped=0;

/* set page aging to maximum! */
decline = PAGE_DECLINE;
PAGE_DECLINE = MAX_PAGE_AGE;

/*
* Find a process, that is suitable for swapping. Please
* note, that the process table may be altered, while a
* page is swapped, so be carefull. Also, due to how
* aging works, we have to actually check each process
* twice, if it has a swappable page!
*/
swap_task = 0;
cnt = 0;
spin_lock(&taskslot_lock);
for (;;) {
if (swap_task >= NR_TASKS)
swap_task = 0;

p = task[swap_task];
if (p && (p->policy != SCHED_KURT) &&
p->swappable && p->mm && (p->mm->rss > 0) &&
swap_out_process(p, 0, 1)) {
/*
* We succesfully swapped out something. Therefore,
* we retry with the same process number next time.
*/
num_pages_swapped ++;
cnt = 0;
continue;
}

/*
* No swapping possible. Retry with the next process.
* If we ran through the process table twice without
* any luck, we are done.
*/
swap_task++;
if (++cnt >= NR_TASKS*2)
break;
}
spin_unlock(&taskslot_lock);
PAGE_DECLINE = decline;
/* Now try to shrink the buffers
*/
while (shrink_mmap(GFP_KERNEL,0));
}
----------------------------------------------------
Note that kswapd is marked as SCHED_KURT and hence will not be
swapped out...

Here is the line it segfaults in
-----------------------------
static inline struct vm_area_struct * find_vma(struct mm_struct * mm, unsigned \long addr)
{
struct vm_area_struct *vma = NULL;

if (mm) {
/* Check the cache first. */
vma = mm->mmap_cache;
====> if(!vma || (vma->vm_end <= addr) || (vma->vm_start > addr)) {
vma = mm->mmap;
while(vma && vma->vm_end <= addr)
vma = vma->vm_next;
mm->mmap_cache = vma;
}
}
return vma;
}
-----------------------------

Since i dont know much (actually i dont know anything) abt the mem management
code, i would appreciate it if someone could point out what im doing wrong.

Thanx
balaji

-------------------------------------------------------------------------------
Balaji Srinivasan
email: balaji@hegel.ittc.ukans.edu
WWW : http://www.ittc.ukans.edu/~balaji