mergemem: announce & design issues

Philipp Reisner (e9525415@student.tuwien.ac.at)
Tue, 17 Mar 1998 09:40:47 +0100


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