QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 3495|回复: 2

linux内核page_address函数有疑问!

[复制链接]
发表于 2006-11-2 20:35:59 | 显示全部楼层 |阅读模式
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 数据结构的组织就知道.
发表于 2006-11-10 21:10:14 | 显示全部楼层
因为在hash表中可能会有冲突现象,也就是说不同的几页可能散列在了一个结点上,所以就将这些页组成双链表。pas = page_slot(page)只是找到了这个结点而已,但是,这个结点上可能有很多的页,所以要list_for_each_entry遍历这个结点上的链表来查找出真正这一页的slot才可以知道页地址。不知解释是否清楚。简而言之是为了解决散列冲突的问题而准备的。
回复

使用道具 举报

 楼主| 发表于 2006-11-11 09:29:32 | 显示全部楼层
太感谢lwf163,你一说到我倒想起来了,怎么把hash表的这个特性忘了,哈哈,太感谢了.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-3-28 17:03 , Processed in 0.076387 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表