You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免find_get_entries返回无效页引发Linux内核崩溃?

解决find_get_entries()返回无效页面导致put_page()崩溃的问题

针对你遇到的find_get_entries()竞态导致页面指针无效、调用put_page()触发内核崩溃的问题,可以通过以下实操方案规避:

1. 严格验证页面有效性

在调用put_page()前,必须对返回的struct page *做有效性校验,核心检查点包括:

  • 校验页面的page->mapping是否与目标文件的address_space(即file->f_mapping)一致,不匹配则说明页面已被回收或复用。
  • 校验page->index是否对应你请求的文件偏移索引(计算逻辑:目标偏移 >> PAGE_SHIFT),避免页面被重新分配后索引不符的情况。
  • 检查页面引用计数:通过page_ref_count(page)确认计数大于0,若为0则页面已被释放,绝对不能调用put_page()。

2. 安全的页面遍历与释放流程

对find_get_entries()返回的页面逐个处理,无效页面直接跳过,不要调用put_page(),示例代码如下:

struct page **pages;
unsigned int nr_pages = find_get_entries(mapping, start, nr, &pages);
unsigned int i;

for (i = 0; i < nr_pages; i++) {
    struct page *page = pages[i];
    bool valid = true;

    if (!page) {
        valid = false;
    } else if (page->mapping != mapping) {
        valid = false;
    } else if (page->index != (start + i) >> PAGE_SHIFT) {
        valid = false;
    }

    if (valid) {
        // 执行你的页面业务逻辑
        // ...
        put_page(page);
    }
}
kfree(pages);

3. 替换为更安全的遍历函数

如果业务场景允许,优先使用内核提供的、已处理竞态的页面遍历函数:

  • filemap_read():内部封装了页面有效性校验与引用计数管理,无需手动处理竞态。
  • walk_page_range():通过回调函数遍历页面,内核会保证回调执行期间页面的有效性。

4. 加锁缩小竞态窗口

若必须使用find_get_entries(),可通过加锁减少页面被回收的概率:

  • 持有文件的i_mutex锁,或地址空间的mapping->tree_lock(注意:tree_lock是自旋锁,需在原子上下文使用,且持有时间不宜过长),加锁后页面不会被回收或复用,确保遍历期间的有效性。

内容的提问来源于stack exchange,提问作者TheAhmad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 09:45:17