Messages in this thread | | | Date | Tue, 17 Mar 1998 09:40:47 +0100 | From | Philipp Reisner <> | Subject | mergemem: announce & design issues |
| |
Hi Linux mm hackers,
Linux is able to share anonymous mappings of running processes, employing copy on write. But this is hardly used, because most processes are started by a shell. For example two users are running a netscape, and since the processes are not in a parent-child relationship the anonymous mappings are not shared.
Mergemem can merge this anonymous mappings of already running processes. This is done by: *) search for equal pages in the anonymous mappings (done in user-land) *) The user-level process only sees a checksum and the map-count of a page (checksum calculation in kernel-land) *) If two equal pages are found, map one of them to the vm of both processes, and free the spare page. (done in kernel-land)
*) If one of the processes is writing to that page afterwards, the normal copy on write takes place.
We are quite satisfied with the gain of free memory, and the cpu-cycles used by the search process are affordable.
Design issues: *) The user-level / kernel interface is a mess (currently by writes to an entry in the proc-fs). What is the good thing(tm) ?? *) a device and ioctls ? (We are looking at this already) *) or a syscall ? *) It is currently not SMP save. Can someone give me a hint how to do it ?? ( A spin_lock(mmlck) at the beginning of mergemem & do_wp_page ? ) *) If I include it into a 2.1.xx kernel and make a patch of it, will it be included into further kernels ?? (Linus ?)
Status: mergemem-0.05 is usable. ( We are using it; Even when my girlfriend touches the computer, it is not crashing, thus it must be bugfree :-) ) (All previous releases had bugs... dying processes, OOPSs...) We are already working on 0.06, but I want to hear your opinion on mergemem
The working package is at http://www.mondoshawan.ml.org, here is the core part, so the mm hackers can have a first look at it.
static int mergemod(int pid1,unsigned long addr1,int pid2, unsigned long addr2) { struct task_struct * tsk1, * tsk2; char * page1, * page2; pte_t * pte1, * pte2, pte; tsk1 = find_task_by_pid(pid1); if(!tsk1) return MERGEMEM_NOTASK1; tsk2 = find_task_by_pid(pid2); if(!tsk2) return MERGEMEM_NOTASK2; page1 = get_phys_addr(tsk1,addr1,&pte1); if(!page1) return MERGEMEM_NOPAGE1; page2 = get_phys_addr(tsk2,addr2,&pte2); if(!page2) return MERGEMEM_NOPAGE2; if(page1 == page2) return MERGEMEM_ALREADYSH;
if(atomic_read(&mem_map[MAP_NR(page2)].count) != 1) return MERGEMEM_MOREMAP;
cli(); /* start of critical section */ if(memcmp(page1,page2,PAGE_SIZE)) { sti(); /* possible end of critical section */ return MERGEMEM_NOTEQUAL; } /* Do the actual work... */
/* new pte's are readonly and point to page1 */ pte = pte_wrprotect(*pte1);
/* increase the count in the according mem_map structure */ atomic_inc(&mem_map[MAP_NR(page1)].count);
/* page1 must go off the swap_cache, since it is now mapped more * than one time */ if(delete_from_swap_cache(&mem_map[MAP_NR(page1)])) pte = pte_mkdirty(pte);
set_pte(pte1,pte); set_pte(pte2,pte_mkold(pte));
sti(); /* possible end of critical section */ /* free page2 */ free_page((unsigned long)page2);
/* decrease the rss counters */ tsk2->mm->rss--;
/* No, TLB flushing needed, because the processes which PTEs where * altered, are not running at the moment. */ return MERGEMEM_SUCCESS; }
------------------------------------------------------------------------ Want to try something new? Are you a Linux hacker? Volunteer in testing mergemem! (Get it from http://www.mondoshawan.ml.org/mergemem) ----- Philipp Reisner E-Mail mailto:e9525415@student.tuwien.ac.at
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |