swap Android,Android系统实现用户态swap(研究贴)

一. Android下用户态swap的意义

二. Android下用户态swap的实现方法

1. 首先实现系统调用swap_process

(在Andriod的内核层实现系统调用,可以参考我前面的文章。)

2. $kernel/mm/swap_state.c

定义系统调用函数swap_process,参数为pid(用户层传过来的进程id)

/**

* swap inactive pages of process with pid

*/

SYSCALL_DEFINE1(swap_process, pid_t, pid)

{

struct task_struct* p = NULL;

LIST_HEAD(pagelist);

unsigned long nr_reclaimed_pages = 0;

//1. find the process ds() through pid

printk(KERN_INFO "user pid: %d\n", pid);

p = find_task_by_pid_ns(pid, current->nsproxy->pid_ns);

if(NULL == p)

{

printk(KERN_ERR "+++could not find task_struct with the pid+++\n");

return 0;

}

//2. filter the inactive pages and add them to swap cache

traverse_pages(p, &pagelist);

//3. swap out pages

if(!list_empty(&pagelist)){

//path: mm/vmscan.c

nr_reclaimed_pages = shrink_process_list(&pagelist);

printk(KERN_INFO "reclaimed pages: %lu\n", nr_reclaimed_pages);

}

return (int)nr_reclaimed_pages;

}

遍历进程的地址空间(各个线性区)

/**

* traverse the page frames of the given process

* parameter: process des,

*/

int traverse_pages(struct task_struct* p, struct list_head *pagelist)

{

struct mm_struct* mm = NULL;

struct vm_area_struct* temp_vm = NULL;

struct vm_area_struct* init_vm = NULL;

struct page * reclaim_page = NULL;

unsigned long PAGE_INNER = (1 << PAGE_SHIFT) -1, temp_addr = 0;

int inactive_page_count = 0;

int err = 0;

LIST_HEAD(page_list);

if(!p)

goto out;

mm = p->mm;

if(!mm)

goto out;

down_read(&mm->mmap_sem);

init_vm = mm->mmap;

temp_vm = init_vm;

do{

if(temp_vm->vm_flags)

for(temp_addr=temp_vm->vm_start; temp_addr < temp_vm->vm_end; temp_addr+=PAGE_SIZE)

{

if(!(temp_addr & PAGE_INNER))

{

//reclaim_page = get_inactive_page(mm, temp_addr);

reclaim_page = follow_page(temp_vm, temp_addr, FOLL_GET|FOLL_SPLIT);

if(IS_ERR(reclaim_page) || !reclaim_page)

continue;

err = isolate_lru_page(reclaim_page);

if(!err){

//if(page_lru(reclaim_page) == LRU_INACTIVE_ANON){

list_add_tail(&reclaim_page->lru, pagelist);

inc_zone_page_state(reclaim_page, NR_ISOLATED_ANON + page_is_file_cache(reclaim_page));

inactive_page_count++;

//}

}

}

}

if(temp_vm->vm_next == NULL)

break;

temp_vm = temp_vm->vm_next;

}while(true);

printk(KERN_INFO "swap process success: inactive pages = %d map_count:%d\n", inactive_page_count, mm->map_count);

up_read(&mm->mmap_sem);

return 1;

out:

up_read(&mm->mmap_sem);

printk(KERN_ERR "traverse page error!\n");

return 0;

}

根据线性地址找到页表项,进而找到数据所处的物理页面

/**

* get inactive pages of the given linear address

* parameter: pgd, linear addr

*/

struct page* get_inactive_page(struct mm_struct* mm, unsigned long addr)

{

struct page* inactive_page = NULL;

pgd_t* pgd;

pmd_t* pmd;

pte_t* pte;

pgd = pgd_offset(mm, addr);

if(pgd_none(*pgd) || pgd_bad(*pgd))

goto out;

//pmd = pmd_offset(pgd, addr);

pmd = (pmd_t*) pgd;

if(pmd_none(*pmd) || pmd_bad(*pmd))

goto out;

pte = pte_offset_map(pmd, addr);

if(!pte)

goto out;

inactive_page = pte_page(*pte);

if(page_lru(inactive_page) == LRU_INACTIVE_ANON)

return inactive_page;

out:

printk(KERN_ERR "+++walk through invalid page table+++\n");

return NULL;

}

3. $kernel/mm/vmscan.c

将指定的页面链表换出到flash swap区域

unsigned long shrink_process_list(struct list_head *pagelist)

{

int priority = 0;

unsigned long ret_nr_dirty = 0, ret_nr_writeback = 0, nr_reclaimed_pages = 1;

struct zone *zone;

struct scan_control sc = {

.gfp_mask = GFP_USER,

.may_writepage = !laptop_mode,

.nr_to_reclaim = SWAP_CLUSTER_MAX,

.may_unmap = 1,

.may_swap = 1,

.order = 0,

.target_mem_cgroup = NULL,

};

struct mem_cgroup *root = sc.target_mem_cgroup;

struct mem_cgroup_reclaim_cookie reclaim = {

.priority = priority,

};

struct mem_cgroup *memcg;

struct mem_cgroup_zone mz;

struct page *page = lru_to_page(pagelist);

zone = page_zone(page);

reclaim.zone = zone;

memcg = mem_cgroup_iter(root, NULL, &reclaim);

mz.mem_cgroup = memcg;

mz.zone = zone;

nr_reclaimed_pages = shrink_page_list(pagelist, &mz, &sc, priority, &ret_nr_dirty, &ret_nr_writeback);

return nr_reclaimed_pages;

} 三. 评估以及后记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值