请教内存管理的问题
前不久想用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;
} 不管怎样给我回一下吧或者给我指个路也行 我今天真高兴,这个问题我也找到原因了,呵呵 大哥,别自己乐,给我们也讲讲阿. :-( 是try_to_swap_out扫描页表的时候加入lru队列的,以前看的不仔细,不过现在对内存管理这部分理解还是挺深刻的呵呵
页:
[1]