免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2830 | 回复: 1
打印 上一主题 下一主题

[内存管理] __get_user_pages_fast为什么不用锁 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-01-25 14:02 |显示全部楼层 |倒序浏览
__get_user_pages_fast会遍历当前进程的页表,如果两个线程共享内存空间,不就会引起冲突了吗。为何此处不用加锁呢?另外,如果这种访问时安全的,那为什么还要在遍历页表前关中断呢?这样做的目的是什么?一直没想通这两个问题。

int __get_user_pages_fast(unsigned long start, int nr_pages, int write,
                          struct page **pages)
{
        struct mm_struct *mm = current->mm;
        unsigned long addr, len, end;
        unsigned long next;
        unsigned long flags;
        pgd_t *pgdp;
        int nr = 0;

        start &= PAGE_MASK;
        addr = start;
        len = (unsigned long) nr_pages << PAGE_SHIFT;
        end = start + len;
        if (unlikely(!access_ok(write ? VERIFY_WRITE : VERIFY_READ,
                                        (void __user *)start, len)))
                return 0;

        /*
         * XXX: batch / limit 'nr', to avoid large irq off latency
         * needs some instrumenting to determine the common sizes used by
         * important workloads (eg. DB2), and whether limiting the batch size
         * will decrease performance.
         *
         * It seems like we're in the clear for the moment. Direct-IO is
         * the main guy that batches up lots of get_user_pages, and even
         * they are limited to 64-at-a-time which is not so many.
         */
        /*
         * This doesn't prevent pagetable teardown, but does prevent
         * the pagetables and pages from being freed on x86.
         *
         * So long as we atomically load page table pointers versus teardown
         * (which we do on x86, with the above PAE exception), we can follow the
         * address down to the the page and take a ref on it.
         */
        local_irq_save(flags);
        pgdp = pgd_offset(mm, addr);
        do {
                pgd_t pgd = *pgdp;

                next = pgd_addr_end(addr, end);
                if (pgd_none(pgd))
                        break;
                if (!gup_pud_range(pgd, addr, next, write, pages, &nr))
                        break;
        } while (pgdp++, addr = next, addr != end);
        local_irq_restore(flags);

        return nr;
}

论坛徽章:
0
2 [报告]
发表于 2015-02-02 19:25 |显示全部楼层
兄台的分析很有道理。明白了,谢谢
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP