[patch] shm not swappable in 2.2.6

Andrea Arcangeli (andrea@e-mind.com)
Fri, 23 Apr 1999 18:46:46 +0200 (CEST)


I agree completly with the 2.2.6 changes of shm. But I discovered a little
bug. The bug avoids swap_out() to really unmap shm pages from the process
attached to the shm. This in turn forbids shm_swap() to swapout the shm
page because its reference count is still >0 (the shm page is still mapped
by the process). Unfortunately this mean that every user can make a
machine unusable simply allocating many 16mbyte-sized shm segment of
unswappable ram in 2.2.6.

Here it is the fix against 2.2.6:

Index: vmscan.c
===================================================================
RCS file: /var/cvs/linux/mm/vmscan.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 vmscan.c
--- vmscan.c 1999/02/06 13:22:09 1.1.1.5
+++ linux/mm/vmscan.c 1999/04/23 16:32:41
@@ -248,9 +248,8 @@
pgd_t *pgdir;
unsigned long end;

- /* Don't swap out areas like shared memory which have their
- own separate swapping mechanism or areas which are locked down */
- if (vma->vm_flags & (VM_SHM | VM_LOCKED))
+ /* Don't swap out areas which are locked down */
+ if (vma->vm_flags & VM_LOCKED)
return 0;

pgdir = pgd_offset(tsk->mm, address);

Since we are talking about vmscan I want also to propose a change (that I
am doing here all the time).

Index: vmscan.c
===================================================================
RCS file: /var/cvs/linux/mm/vmscan.c,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 vmscan.c
--- vmscan.c 1999/02/06 13:22:09 1.1.1.5
+++ linux/mm/vmscan.c 1999/04/23 16:32:41
@@ -45,12 +45,7 @@
page = pte_page(pte);
if (MAP_NR(page) >= max_mapnr)
return 0;
-
page_map = mem_map + MAP_NR(page);
- if (PageReserved(page_map)
- || PageLocked(page_map)
- || ((gfp_mask & __GFP_DMA) && !PageDMA(page_map)))
- return 0;

if (pte_young(pte)) {
/*
@@ -62,6 +57,11 @@
return 0;
}

+ if (PageReserved(page_map)
+ || PageLocked(page_map)
+ || ((gfp_mask & __GFP_DMA) && !PageDMA(page_map)))
+ return 0;
+
/*
* Is the page already in the swap cache? If so, then
* we can just drop our reference to it without doing

I rewritten it from scratch now in a 2.2.6-clean tree and I haven't tried
it in a clean 2.2.6-VM, but I think it should work fine too. My idea is
that we wasn't collecting the accessed bit (the one set by the hardware at
every read or write touch) of the pte in a fair way. Think if we have a
GFP_DMA request, before returning we _must_ set the reference bit
otherwise the random page we had under us could be the most accessed but
we may go to free it. I don't know how much this make difference in real
life (tester needed?) but I think it's a good think anyway. Comments?

Andrea Arcangeli

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/