The PLMC memory controller.
Only one change in mm/vmscan.c, just to remove a comment
else patch1+patch2 don't compile...
Signed-off-by: Patrick Le Dot <[EMAIL PROTECTED]>
---
include/linux/mem_rc_inline.h | 8 -
kernel/res_group/Makefile | 2
kernel/res_group/memcore.c | 4
kernel/res_group/memctlr.c | 193 ++++++++++++++++++++++++++++++++++++++++++
mm/vmscan.c | 2
5 files changed, 201 insertions(+), 8 deletions(-)
diff -Naurp a3/include/linux/mem_rc_inline.h b3/include/linux/mem_rc_inline.h
--- a3/include/linux/mem_rc_inline.h 2006-10-03 09:57:26.000000000 +0200
+++ b3/include/linux/mem_rc_inline.h 2006-10-03 09:55:24.000000000 +0200
@@ -52,12 +52,12 @@ static inline void res_group_inc_active_
?: mem_root_res_group;
if (res == NULL)
return;
- // rg_mem_add_page(page, res);
+ rg_mem_add_page(page, res);
}
static inline void res_group_dec_active_list(struct page *page)
{
- // rg_mem_remove_page(page, NULL);
+ rg_mem_remove_page(page, NULL);
}
static inline void res_group_inc_inactive_list(struct page *page)
@@ -67,12 +67,12 @@ static inline void res_group_inc_inactiv
if (res == NULL)
return;
- // rg_mem_add_page(page, res);
+ rg_mem_add_page(page, res);
}
static inline void res_group_dec_inactive_list(struct page *page)
{
- // rg_mem_remove_page(page, NULL);
+ rg_mem_remove_page(page, NULL);
}
static inline void res_group_page_init(struct page *page)
diff -Naurp a3/kernel/res_group/Makefile b3/kernel/res_group/Makefile
--- a3/kernel/res_group/Makefile 2006-10-03 09:57:26.000000000 +0200
+++ b3/kernel/res_group/Makefile 2006-10-03 09:55:24.000000000 +0200
@@ -1,4 +1,4 @@
obj-y = res_group.o shares.o task.o
obj-$(CONFIG_RES_GROUPS_NUMTASKS) += numtasks.o
-obj-$(CONFIG_RES_GROUPS_MEM_RC) += memcore.o
+obj-$(CONFIG_RES_GROUPS_MEM_RC) += memcore.o memctlr.o
obj-$(CONFIG_RGCS) += rgcs.o
diff -Naurp a3/kernel/res_group/memcore.c b3/kernel/res_group/memcore.c
--- a3/kernel/res_group/memcore.c 2006-10-03 09:57:26.000000000 +0200
+++ b3/kernel/res_group/memcore.c 2006-10-03 09:55:24.000000000 +0200
@@ -81,7 +81,7 @@ static void set_tot_pages(void)
static void mem_res_init_one(struct mem_res_group *mem_res)
{
- mem_res->shares.min_shares = SHARE_UNSUPPORTED;
+ mem_res->shares.min_shares = SHARE_DONT_CARE;
mem_res->shares.max_shares = SHARE_UNSUPPORTED;
mem_res->shares.child_shares_divisor = SHARE_DEFAULT_DIVISOR;
mem_res->shares.unused_min_shares = SHARE_DEFAULT_DIVISOR;
@@ -322,7 +322,7 @@ static void mem_move_task(struct task_st
return;
mm = task->active_mm;
- // rg_mem_migrate_mm(mm, oldres, newres);
+ rg_mem_migrate_mm(mm, oldres, newres);
return;
}
diff -Naurp a3/kernel/res_group/memctlr.c b3/kernel/res_group/memctlr.c
--- a3/kernel/res_group/memctlr.c 1970-01-01 01:00:00.000000000 +0100
+++ b3/kernel/res_group/memctlr.c 2006-10-03 09:55:24.000000000 +0200
@@ -0,0 +1,193 @@
+/* memctlr.c - Basic routines for the Resource Groups memory controller
+ *
+ * Copyright (C) Jiantao Kong, IBM Corp. 2003
+ * (C) Chandra Seetharaman, IBM Corp. 2004
+ * (C) Patrick Le Dot <[EMAIL PROTECTED]@bull.net> 2006
+ *
+ * Provides a Memory Resource controller for Resource Groups
+ *
+ * Latest version, more details at http://ckrm.sf.net
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ */
+
+#include <linux/swap.h>
+#include <linux/pagemap.h>
+#include <linux/mem_rc_inline.h>
+
+static void check_guarantee(struct page *page, struct mem_res_group *res)
+{
+ if (atomic_read(&res->pg_inuse) <= res->pg_min_shares) {
+ if ((rgroup_guarantee & res->bit_id) == 0)
+ rgroup_guarantee = (rgroup_guarantee ^ res->bit_id);
+ } else {
+ if ((rgroup_guarantee & res->bit_id) != 0)
+ rgroup_guarantee = (rgroup_guarantee & ~res->bit_id);
+ }
+}
+
+void rg_mem_add_page(struct page *page, struct mem_res_group *res)
+{
+ if (!res)
+ return;
+ if (page->rg_bitmap & res->bit_id)
+ return;
+ page->rg_bitmap = (page->rg_bitmap ^ res->bit_id);
+ atomic_inc(&res->pg_inuse);
+ res->max_pg_used = max(res->max_pg_used, atomic_read(&res->pg_inuse));
+ if (res != mem_root_res_group)
+ check_guarantee(page, res);
+}
+
+static void dec_and_update(struct page *page, struct mem_res_group *res)
+{
+ page->rg_bitmap = (page->rg_bitmap & ~res->bit_id);
+ atomic_dec(&res->pg_inuse);
+ if (res != mem_root_res_group)
+ check_guarantee(page, res);
+}
+
+void rg_mem_remove_page(struct page *page, struct mem_res_group *res)
+{
+ struct mem_res_group *mem_rg;
+
+ if (page->rg_bitmap == 0)
+ return;
+ if (!res) {
+ // remove the page from all groups
+ list_for_each_entry(mem_rg, &mem_res_group_list, res_list) {
+ if (page->rg_bitmap & mem_rg->bit_id)
+ dec_and_update(page, mem_rg);
+ }
+ } else
+ dec_and_update(page, res);
+}
+
+static inline void
+rg_mem_change_page(struct page *page,
+ struct mem_res_group *old_res,
+ struct mem_res_group *new_res)
+{
+ if (!new_res) {
+ if (!mem_root_res_group)
+ return;
+ new_res = mem_root_res_group;
+ }
+
+ if (old_res == new_res)
+ return;
+
+ if (old_res) {
+ rg_mem_remove_page(page, old_res);
+ }
+
+ rg_mem_add_page(page, new_res);
+}
+
+static inline int
+rg_mem_migrate_pmd(struct vm_area_struct* vma, pmd_t* pmdir,
+ unsigned long address, unsigned long end,
+ struct mem_res_group *old, struct mem_res_group *new)
+{
+ pte_t *pte;
+ unsigned long pmd_end;
+
+ if (pmd_none(*pmdir))
+ return 0;
+ BUG_ON(pmd_bad(*pmdir));
+
+ pmd_end = (address+ PMD_SIZE) & PMD_MASK;
+ if (end > pmd_end)
+ end = pmd_end;
+
+ do {
+ pte = pte_offset_map(pmdir, address);
+ if (pte_present(*pte)) {
+ struct page *page = pte_page(*pte);
+ if (page->mapping) {
+ struct zone *zone = page_zone(page);
+ spin_lock_irq(&zone->lru_lock);
+ rg_mem_change_page(page, old, new);
+ spin_unlock_irq(&zone->lru_lock);
+ }
+ }
+ address += PAGE_SIZE;
+ pte_unmap(pte);
+ pte++;
+ } while(address && (address < end));
+ return 0;
+}
+
+static inline int
+rg_mem_migrate_pgd(struct vm_area_struct* vma, pgd_t* pgdir,
+ unsigned long address, unsigned long end,
+ struct mem_res_group *old, struct mem_res_group *new)
+{
+ pmd_t* pmd;
+ pud_t* pud;
+ unsigned long pgd_end;
+
+ if (pgd_none(*pgdir))
+ return 0;
+ BUG_ON(pgd_bad(*pgdir));
+
+ pud = pud_offset(pgdir, address);
+ if (pud_none(*pud))
+ return 0;
+ BUG_ON(pud_bad(*pud));
+ pmd = pmd_offset(pud, address);
+ pgd_end = (address + PGDIR_SIZE) & PGDIR_MASK;
+
+ if (pgd_end && (end > pgd_end))
+ end = pgd_end;
+
+ do {
+ rg_mem_migrate_pmd(vma, pmd, address, end, old, new);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address && (address < end));
+ return 0;
+}
+
+static inline int
+rg_mem_migrate_vma(struct vm_area_struct* vma, struct mem_res_group *old,
+ struct mem_res_group *new)
+{
+ pgd_t* pgdir;
+ unsigned long address, end;
+
+ address = vma->vm_start;
+ end = vma->vm_end;
+
+ pgdir = pgd_offset(vma->vm_mm, address);
+ do {
+ rg_mem_migrate_pgd(vma, pgdir, address, end, old, new);
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ pgdir++;
+ } while(address && (address < end));
+ return 0;
+}
+
+void rg_mem_migrate_mm(struct mm_struct* mm, struct mem_res_group *old,
+ struct mem_res_group *new)
+{
+ struct vm_area_struct *vma;
+
+ if (new) {
+ /* Go through all VMA to migrate pages */
+ down_read(&mm->mmap_sem);
+ spin_lock(&mm->page_table_lock);
+ vma = mm->mmap;
+ while(vma) {
+ rg_mem_migrate_vma(vma, old, new);
+ vma = vma->vm_next;
+ }
+ spin_unlock(&mm->page_table_lock);
+ up_read(&mm->mmap_sem);
+ }
+ return;
+}
diff -Naurp a3/mm/vmscan.c b3/mm/vmscan.c
--- a3/mm/vmscan.c 2006-10-03 09:57:26.000000000 +0200
+++ b3/mm/vmscan.c 2006-10-03 09:56:07.000000000 +0200
@@ -556,7 +556,7 @@ free_it:
if ((page->rg_bitmap & rgroup_guarantee) != 0)
goto keep_locked;
else
- // rg_mem_remove_page(page, NULL);
+ rg_mem_remove_page(page, NULL);
#endif
unlock_page(page);
nr_reclaimed++;
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ Patrick Le Dot
mailto: [EMAIL PROTECTED]@bull.net Centre UNIX de BULL SAS
Phone : +33 4 76 29 73 20 1, Rue de Provence BP 208
Fax : +33 4 76 29 76 00 38130 ECHIROLLES Cedex FRANCE
Bull, Architect of an Open World TM
www.bull.com
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
ckrm-tech mailing list
https://lists.sourceforge.net/lists/listinfo/ckrm-tech