|
前不久想用LINUX的文件映射的机制把动态分配的内存映射到用户空间,可是觉得有些必需得考虑的地方我没有能理解,下面两个问题希望有人能指点。
一、交换机制的一个问题:
用户空间扩展堆栈时和用brk分配内存时通过do_no_page进入do_anonymous_page函数映射的页面,为什么没有挂入LRU队列(包括address_space里的换入换出队列和hash队列)?不挂入LRU队列的页面如何进行换入换出?通过try_to_swap_out扫描进程页面表的时候也没能把这些页面挂入LRU队列,我把页面换入换出部分看了好几遍,也找不出能把通过扩展堆栈和用brk映射的页面挂入LRU队列的途径(另外共享父进程空间写时拷贝分配的页面也没有挂入LRU队列),但通过do_swap_page分配或找到的页面都可以顺利的挂入三种队列(本身就在LRU队列里的页面通过lookup_swap_cache找到并加入活跃队列,在交换盘上的页面能过read_swap_cache_async读入并挂入三种队列里,还有为共享内存分配或找到的页面也都挂入LRU队列)。
二、下面的这个函数是写时拷贝的一个函数,作用是如果count==3便新复制一份新的页面,我的问题是如果跳到 case 2:就是说目前这个页面有一个用户(页面分配时页面计数就为1),然后通过exclusive_swap_page检测,在这里count += swap_count (page);就是说如果此页面在交换设备上分配了一个页面就进行页面拷贝,如果交换设备上没有分配页面就走到case 1:在这里把此页面改成可写返回后就可以对此页面进行写访问,而不用另外复制一份页面。不知道我的理解有没有偏差,这里我不明白的一个地方就是为什么count == 3也就是交换设备分配页面就复制页面呢?
- static inline int exclusive_swap_page(struct page *page)
- {
- unsigned int count;
- if (!PageLocked(page))
- BUG();
- if (!PageSwapCache(page))
- return 0;
- count = page_count(page) - !!page->buffers; /* 2: us + swap cache */
- count += swap_count(page); /* +1: just swap cache */
- return count == 3; /* =3: total */
- }
- static int do_wp_page(struct mm_struct *mm, struct vm_area_struct * vma,
- unsigned long address, pte_t *page_table, pte_t pte)
- {
- ……………………
- switch (page_count(old_page)) {
- int can_reuse;
- case 3:
- if (!old_page->buffers)
- break;
- /* FallThrough */
- case 2:
- if (!PageSwapCache(old_page))
- break;
- if (TryLockPage(old_page))
- break;
- /* Recheck swapcachedness once the page is locked */
- can_reuse = exclusive_swap_page(old_page);
- UnlockPage(old_page);
- if (!can_reuse)
- break;
- /* FallThrough */
- case 1:
- flush_cache_page(vma, address);
- establish_pte(vma, address, page_table, pte_mkyoung(pte_mkdirty(pte_mkwrite(pte))));
- return 1; /* Minor fault */
- }
- ………………
- bad_wp_page:
- printk("do_wp_page: bogus page at address %08lx (page 0x%lx)\n",address,(unsigned long)old_page);
- return -1;
- }
复制代码 |
|