[SSI] openssi/kernel/cluster/ssi/mosixll freemem.c, 1.11, 1.12 service.c, 1.9, 1.10
Roger Tsang <[email protected]> Sun, 18 Apr 2010 20:42:26 +0000
| Newsgroups | gmane.linux.cluster.ssic.cvs |
|---|---|
| Message-ID | <[email protected]> |
Update of /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll
In directory sfp-cvsdas-3.v30.ch3.sourceforge.com:/tmp/cvs-serv10942/cluster/ssi/mosixll
Modified Files:
Tag: OPENSSI-FC
freemem.c service.c
Log Message:
MOSIX (#ifdef SSI_BALANCE_MEMORY):
- Use cond_resched_lock() instead of run_over_maxchunk, sort_age_maxchunk. Prevent needless re-traversing of the page table.
- run_over_dirty_pages(), sort_and_age_pages() support 4-level page table.
Index: service.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/service.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- service.c 17 Dec 2009 06:43:51 -0000 1.9
+++ service.c 18 Apr 2010 20:42:24 -0000 1.10
@@ -210,38 +210,91 @@
return(PageDirty(page) || PageSwapCache(page));
}
-#define RUN_OVER_MAGIC 126094
+#ifdef SSI_BALANCE_MEMORY
+/* We hold mm semaphore and page_table_lock on entry */
+static unsigned long
+__run_over_dirty_pg(
+ unsigned long *addr,
+ pgd_t *pgdir,
+ unsigned long pgd_end,
+ int isfile,
+ int count_in_file)
+{
+ pud_t *pudir;
+ pmd_t *pmdir;
+ pte_t *pte, *pte_dir;
+ unsigned long pud_end, pmd_end, pte_end, count = 0;
-static int run_over_maxchunk;
+ pudir = pud_offset(pgdir, *addr);
+ for(; *addr < pgd_end ; *addr = pud_end , pudir++) {
+ pud_end = (*addr + PUD_SIZE) & PUD_MASK;
+ if(pud_end > pgd_end || pud_end <= *addr)
+ pud_end = pgd_end;
+ if(pud_none(*pudir) || pud_bad(*pudir))
+ continue;
+
+ pmdir = pmd_offset(pudir, *addr);
+ for(; *addr < pud_end ; *addr = pmd_end , pmdir++) {
+ pmd_end = (*addr + PMD_SIZE) & PMD_MASK;
+ if(pmd_end > pud_end || pmd_end <= *addr)
+ pmd_end = pud_end;
+ if(pmd_none(*pmdir) || pmd_bad(*pmdir))
+ continue;
+
+ pte = pte_dir = pte_offset_map(pmdir, *addr);
+ for(; *addr < pmd_end ; *addr = pte_end , pte++) {
+ pte_end = *addr + PAGE_SIZE;
+ if(pte_end > pmd_end)
+ pte_end = pmd_end;
+ if(pte_present(*pte) ?
+ (isfile && !pte_really_dirty(*pte)) :
+ pte_none(*pte)) {
+ if(isfile && count_in_file)
+ count++;
+ continue;
+ }
+ if(!count_in_file)
+ count++;
+ }
+ pte_unmap(pte_dir);
+ }
+ }
+ return count;
+}
-#ifdef SSI_BALANCE_MEMORY
/* Locking:
* down_read(&mm->mmap_sem)
* -> spin_lock(&mm->page_table_lock)
*/
unsigned long
-#else
+run_over_dirty_pages(int (*func)(unsigned long, int), int count_in_file)
+#else /* SSI_BALANCE_MEMORY */
+#define RUN_OVER_MAGIC 126094
+
+static int run_over_maxchunk;
+
int
-#endif
run_over_dirty_pages(int (*func)(unsigned long, int), int count_in_file)
+#endif /* !SSI_BALANCE_MEMORY */
{
- struct task_struct *p = current;
- struct mm_struct *mm = p->mm;
+ struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
+ unsigned long addr, pgd_end;
+ int isfile;
+ pgd_t *pgdir;
#ifdef SSI_BALANCE_MEMORY
unsigned long count = 0;
#else
+ unsigned long pmd_end, pte_end;
+ unsigned long start;
int count = 0;
-#endif
- int isfile;
- unsigned long start, addr, pgd_end, pmd_end, pte_end;
- pgd_t *pgdir;
pud_t *pudir;
pmd_t *pmdir;
pte_t *pte;
pte_t *pte_dir;
- int err;
int let_go;
+ int err;
+#endif
#ifdef CONFIG_SSI
if(!mm || mm == &init_mm)
@@ -250,6 +303,7 @@
return(0);
}
#endif /* CONFIG_SSI */
+#ifndef SSI_BALANCE_MEMORY
if(!run_over_maxchunk)
{
/* this routine can take very long for huge processes:
@@ -260,6 +314,7 @@
if(!run_over_maxchunk) /* slow processors */
run_over_maxchunk = 1;
}
+#endif /* !SSI_BALANCE_MEMORY */
#ifdef CONFIG_MOSIX_DIAG
if(!mm || mm == &init_mm)
@@ -276,13 +331,33 @@
}
/* so now there is no need to lock mmap_sem! */
#endif /* CONFIG_MOSIX_DIAG */
+#ifdef SSI_BALANCE_MEMORY
+ BUG_ON(func);
+ down_read(&mm->mmap_sem);
+ for(vma = mm->mmap ; vma != NULL ; vma = vma->vm_next) {
+ isfile = (vma->vm_file != NULL);
+ addr = vma->vm_start;
+ pgdir = pgd_offset(mm, addr);
+
+ spin_lock(&mm->page_table_lock);
+ for(; addr < vma->vm_end; addr = pgd_end, pgdir++) {
+ cond_resched_lock(&mm->page_table_lock);
+
+ pgd_end = (addr + PGDIR_SIZE) & PGDIR_MASK;
+ if(pgd_end > vma->vm_end || pgd_end <= addr)
+ pgd_end = vma->vm_end;
+ if(pgd_none(*pgdir) || pgd_bad(*pgdir))
+ continue;
+ count += __run_over_dirty_pg(&addr, pgdir, pgd_end,
+ isfile, count_in_file);
+ }
+ spin_unlock(&mm->page_table_lock);
+ }
+ up_read(&mm->mmap_sem);
+#else /* SSI_BALANCE_MEMORY */
addr = 0;
loop:
let_go = run_over_maxchunk;
-#ifdef SSI_BALANCE_MEMORY
- down_read(&mm->mmap_sem);
- spin_lock(&mm->page_table_lock);
-#endif
for(vma = mm->mmap ; vma != NULL ; vma = vma->vm_next)
if(addr < vma->vm_end)
{
@@ -295,12 +370,7 @@
{
if(let_go-- == 0)
{
-#ifdef SSI_BALANCE_MEMORY
- spin_unlock(&mm->page_table_lock);
- up_read(&mm->mmap_sem);
-#else
yield();
-#endif
goto loop;
}
pgd_end = (addr + PGDIR_SIZE) & PGDIR_MASK;
@@ -308,9 +378,8 @@
pgd_end = vma->vm_end;
if(pgd_none(*pgdir) || pgd_bad(*pgdir))
continue;
-#ifndef SSI_BALANCE_MEMORY
+
spin_lock(&mm->page_table_lock);
-#endif
pudir = pud_offset(pgdir, addr);
pmdir = pmd_offset(pudir, addr);
for(; addr < pgd_end ; addr = pmd_end , pmdir++)
@@ -338,10 +407,6 @@
count++;
if(func)
{
-#ifdef SSI_BALANCE_MEMORY
- BUG();
- for (;;);
-#endif
spin_unlock(&mm->page_table_lock);
if((err = (*func)(addr, PAGE_SIZE))) {
pte_unmap(pte_dir);
@@ -352,15 +417,10 @@
}
pte_unmap(pte_dir);
}
-#ifndef SSI_BALANCE_MEMORY
spin_unlock(&mm->page_table_lock);
-#endif
}
}
-#ifdef SSI_BALANCE_MEMORY
- spin_unlock(&mm->page_table_lock);
- up_read(&mm->mmap_sem);
-#endif
+#endif /* !SSI_BALANCE_MEMORY */
return(count);
}
Index: freemem.c
===================================================================
RCS file: /cvsroot/ssic-linux/openssi/kernel/cluster/ssi/mosixll/freemem.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- freemem.c 17 Dec 2009 06:43:51 -0000 1.11
+++ freemem.c 18 Apr 2010 20:42:24 -0000 1.12
@@ -44,8 +44,8 @@
int pages_to_keep_free;
int latest_free_mem;
static int marker;
-#endif
static int sort_age_maxchunk;
+#endif
#ifdef SSI_BALANCE_MEMORY
static inline unsigned long
@@ -417,20 +417,20 @@
sort_and_age_pages(struct mm_struct *mm)
{
#ifdef SSI_BALANCE_MEMORY
- unsigned long used = 0, swapped = 0;
+ pud_t *pudir;
+ unsigned long pud_end, used = 0, swapped = 0;
#else
int used = 0, unused = 0, swapped = 0, private_unused = 0;
-#endif
+ static int let_go = -1;
+#endif /* !SSI_BALANCE_MEMORY */
int need_flush = 0;
register struct vm_area_struct *vma;
pgd_t *pgdir;
- pud_t *pudir;
pmd_t *pmdir;
pte_t *pte;
pte_t *pte_dir;
struct page *page;
unsigned long addr, start, pgd_end, pmd_end;
- static int let_go = -1;
int interval = sort_interval(1);
if(!mm->last_memsort && interval)
@@ -440,14 +440,45 @@
if((u16)((jiffies & 0xffff) - mm->used) < interval)
return;
}
+#ifdef SSI_BALANCE_MEMORY
+ down_read(&mm->mmap_sem);
+ for(vma = mm->mmap ; vma != NULL ; vma = vma->vm_next) {
+ start = vma->vm_start;
+
+ spin_lock(&mm->page_table_lock);
+ pgdir = pgd_offset(mm, start);
+ for(addr = start ; addr < vma->vm_end ;
+ addr = pgd_end , pgdir++)
+ {
+ cond_resched_lock(&mm->page_table_lock);
+
+ pgd_end = (addr + PGDIR_SIZE) & PGDIR_MASK;
+ if(pgd_end > vma->vm_end || pgd_end <= addr)
+ pgd_end = vma->vm_end;
+ if(pgd_none(*pgdir) || pgd_bad(*pgdir))
+ continue;
+
+ pudir = pud_offset(pgdir, addr);
+ for(; addr < pgd_end ; addr = pud_end , pudir++)
+ {
+ pud_end = (addr + PUD_SIZE) & PUD_MASK;
+ if(pud_end > pgd_end || pud_end <= addr)
+ pud_end = pgd_end;
+ if(pud_none(*pudir) || pud_bad(*pudir))
+ continue;
+
+ pmdir = pmd_offset(pudir, addr);
+ for(; addr < pud_end ; addr = pmd_end , pmdir++)
+ {
+ pmd_end = (addr + PMD_SIZE) & PMD_MASK;
+ if(pmd_end > pud_end || pmd_end <= addr)
+ pmd_end = pud_end;
+#else /* SSI_BALANCE_MEMORY */
addr = 0;
loop:
if(let_go == -1)
let_go = sort_age_maxchunk;
-#ifdef SSI_BALANCE_MEMORY
- down_read(&mm->mmap_sem);
-#endif
spin_lock(&mm->page_table_lock);
for(vma = mm->mmap ; vma != NULL ; vma = vma->vm_next)
@@ -463,11 +494,7 @@
if(let_go-- == 0)
{
spin_unlock(&mm->page_table_lock);
-#ifdef SSI_BALANCE_MEMORY
- up_read(&mm->mmap_sem);
-#else
yield();
-#endif
goto loop;
}
pgd_end = (addr + PGDIR_SIZE) & PGDIR_MASK;
@@ -475,13 +502,13 @@
pgd_end = vma->vm_end;
if(pgd_none(*pgdir) || pgd_bad(*pgdir))
continue;
- pudir = pud_offset(pgdir, addr);
- pmdir = pmd_offset(pudir, addr);
+ pmdir = pmd_offset(pgdir, addr);
for(; addr < pgd_end ; addr = pmd_end , pmdir++)
{
pmd_end = (addr + PMD_SIZE) & PMD_MASK;
if(pmd_end > pgd_end)
pmd_end = pgd_end;
+#endif /* !SSI_BALANCE_MEMORY */
if(pmd_none(*pmdir) || pmd_bad(*pmdir))
continue;
pte = pte_dir = pte_offset_map(pmdir, addr);
@@ -530,16 +557,22 @@
}
pte_unmap(pte_dir);
}
+#ifdef SSI_BALANCE_MEMORY
+ } /* for pudir */
+#endif
}
+#ifdef SSI_BALANCE_MEMORY
+ spin_unlock(&mm->page_table_lock);
+#endif
}
if(need_flush)
flush_tlb_mm(mm);
- spin_unlock(&mm->page_table_lock);
#ifdef SSI_BALANCE_MEMORY
up_read(&mm->mmap_sem);
spin_lock(&mm->memsort_lock);
#else
+ spin_unlock(&mm->page_table_lock);
write_lock_irq(&tasklist_lock);
#endif
mm->used = used;
@@ -565,7 +598,9 @@
#endif /* CONFIG_MOSIX_DEBUG */
}
+#ifndef SSI_BALANCE_MEMORY
#define SORT_AGE_MAGIC 2490368
+#endif
int
mosix_mem_daemon(void *nothing)
@@ -591,6 +626,7 @@
pages_to_keep_free = MAX_PAGES_TO_KEEP_FREE;
compute_freemem();
+#ifndef SSI_BALANCE_MEMORY
/* "sort_and_age_pages" can take very long for large memories:
* we must therefore allow other processes to take over at least
* about every millisecond.
@@ -598,6 +634,7 @@
sort_age_maxchunk = loops_per_jiffy / SORT_AGE_MAGIC;
if(!sort_age_maxchunk) /* very slow processors */
sort_age_maxchunk = 1;
+#endif /* !SSI_BALANCE_MEMORY */
while (1)
{
current->state = TASK_INTERRUPTIBLE;
------------------------------------------------------------------------------
Download Intel® Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev