加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

BUG:无法处理内核分页请求

发布时间:2020-12-16 07:11:35 所属栏目:百科 来源:网络整理
导读:出于某些特定原因,我需要编辑2.6.32.65 Linux内核,以便在将内容分配到内存之前,将扇区从硬盘读取到特定位置.例如在mm / filemap.c中的函数do_generic_file_read中我执行以下操作: myRet = mapping-a_ops-readpage(filp,myPage); //AddedFunction_Operates_O
出于某些特定原因,我需要编辑2.6.32.65 Linux内核,以便在将内容分配到内存之前,将扇区从硬盘读取到特定位置.例如在mm / filemap.c中的函数do_generic_file_read中我执行以下操作:

myRet = mapping->a_ops->readpage(filp,myPage);          //Added
Function_Operates_On_MyPage();                          //Added

page = page_cache_alloc_cold(mapping);
if (!page) {
    desc->error = -ENOMEM;
    goto out;
}

然后该函数实际上再次将扇区读取到分配的页面,如下所示:

error = mapping->a_ops->readpage(filp,page);

当然这不是最佳选择,但我只需要它用于测试目的,因此无关紧要.现在这很好用,做我想做的事.它在多个其他位置也可以正常工作,但mm / readahead.c中的__do_page_cache_readahead除外.它看起来如下:

for (page_idx = 0; page_idx < nr_to_read; page_idx++) {
    pgoff_t page_offset = offset + page_idx;

    if (page_offset > end_index)
        break;

    rcu_read_lock();
    page = radix_tree_lookup(&mapping->page_tree,page_offset);
    rcu_read_unlock();
    if (page)
        continue;

    myRet = mapping->a_ops->readpage(filp,myPage);          //Added
    Function_Operates_On_Mypage();                          //Added
    page = page_cache_alloc_cold(mapping);
    if (!page)
        break;
    page->index = page_offset;
    list_add(&page->lru,&page_pool);
    if (page_idx == nr_to_read - lookahead_size)
        SetPageReadahead(page);
    ret++;
}

if (ret)
    read_pages(mapping,filp,&page_pool,ret);

它调用read_pages,它实际上再次读取扇区到它们分配的页面.现在read_pages据我所知和我一样:

for (page_idx = 0; page_idx < nr_pages; page_idx++) {
    struct page *page = list_to_page(pages);
    list_del(&page->lru);
    if (!add_to_page_cache_lru(page,mapping,page->index,GFP_KERNEL)) {
        mapping->a_ops->readpage(filp,page);
    }
    page_cache_release(page);
}
ret = 0;

但read_pages中的readpage工作正常但是当我在__do_page_cache_readahead中添加它时会导致错误BUG:无法在ffffea0df0668018处理内核分页请求.两行之间的唯一区别是获取数据的页面.在其他情况下,我和我一起工作得很好.为什么会这样?怎么解决?

编辑1

readpage是文件fs / mpage.c中函数mpage_readpage的指针,它在同一文件中调用do_mpage_readpage.使用printks我能够发现故障实际发生在do_mpage_readpage的第一行,如下所示:

struct inode *inode = page->mapping->host;

问题是我用来从硬盘读取的页面在启动时被标记为保留(我不希望将此位置分配给任何进程!).所以我不确定是什么页面>映射.我猜这是造成错误的原因,但我不知道如何解决这个问题!我也不确定它是如何在其他位置工作的,可能是因为readpage指向除mpage_readpage之外的函数.

解决方法

从您的代码中,我猜到了page = page_cache_alloc_cold(mapping);中发生的错误.我用Google搜索了它:page_cache_alloc_cold用于在缓存中找不到想要的页面时分配新页面.但是如果你经常调用该函数,内核会oops,因为为内核提供的内存太小了!我遇到的问题,我的解决方案是在你的module_init()函数中预先分配页面(预分配).它会避免经常调用page_cache_alloc_cold.我希望这能帮到您.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读