Messages in this thread Patches in this message | | | Date | Fri, 23 Apr 1999 18:46:46 +0200 (CEST) | From | Andrea Arcangeli <> | Subject | [patch] shm not swappable in 2.2.6 |
| |
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/
| |