linux内核page_address函数有疑问!
void *page_address(struct page *page)
{
unsigned long flags;
void *ret;
struct page_address_slot *pas;
if (!PageHighMem(page))
return lowmem_page_address(page);
pas = page_slot(page);
ret = NULL;
spin_lock_irqsave(&pas->lock, flags);
if (!list_empty(&pas->lh)) {
struct page_address_map *pam;
list_for_each_entry(pam, &pas->lh, list) {
if (pam->page == page) {
ret = pam->virtual;
goto done;
}
}
}
done:
spin_unlock_irqrestore(&pas->lock, flags);
return ret;
}[\quote]
大虾们,请问函数中既然已经用HASH表找到了page_address_map ,那么此时其对应的PAGE FRAME也就找到了,继而virtual ADDRESS也就有了!既然如此,为何还要list_for_each_entry这样游历双链表LIST,这不是没必要了吗?
呵呵,可能还没搞清楚一些东西,不过还是希望DX们解释一下,谢谢!
注:pas = page_slot(page);从HASH表找到PAGE对应的page_address_slot ,所以我说下面的list_for_each_entry就显的"多余"了,因为从page_address_slot 已经可以得到PAGE对应的virtual ADDRESS了!看一下page_address_slot 数据结构的组织就知道.
因为在hash表中可能会有冲突现象,也就是说不同的几页可能散列在了一个结点上,所以就将这些页组成双链表。pas = page_slot(page)只是找到了这个结点而已,但是,这个结点上可能有很多的页,所以要list_for_each_entry遍历这个结点上的链表来查找出真正这一页的slot才可以知道页地址。不知解释是否清楚。简而言之是为了解决散列冲突的问题而准备的。 太感谢lwf163,你一说到我倒想起来了,怎么把hash表的这个特性忘了,哈哈,太感谢了.
页:
[1]