fineamy 发表于 2006-11-2 20:35:59

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 数据结构的组织就知道.

lwf163 发表于 2006-11-10 21:10:14

因为在hash表中可能会有冲突现象,也就是说不同的几页可能散列在了一个结点上,所以就将这些页组成双链表。pas = page_slot(page)只是找到了这个结点而已,但是,这个结点上可能有很多的页,所以要list_for_each_entry遍历这个结点上的链表来查找出真正这一页的slot才可以知道页地址。不知解释是否清楚。简而言之是为了解决散列冲突的问题而准备的。

fineamy 发表于 2006-11-11 09:29:32

太感谢lwf163,你一说到我倒想起来了,怎么把hash表的这个特性忘了,哈哈,太感谢了.
页: [1]
查看完整版本: linux内核page_address函数有疑问!