在为sg_copy_buffer复制内存时是否需要禁用IRQ?

时间:2011-04-04 11:22:31

标签: c linux linux-kernel

这是Linux内核2.6.32的sg_copy_buffer的功能。复制内存时是否需要禁用IRQ?

 static size_t sg_copy_buffer(struct scatterlist *sgl, unsigned int nents,
                 void *buf, size_t buflen, int to_buffer)
{
    unsigned int offset = 0;
    struct sg_mapping_iter miter;
    unsigned long flags;
    unsigned int sg_flags = SG_MITER_ATOMIC;

    if (to_buffer)
        sg_flags |= SG_MITER_FROM_SG;
    else
        sg_flags |= SG_MITER_TO_SG;

    sg_miter_start(&miter, sgl, nents, sg_flags);

    local_irq_save(flags);

    while (sg_miter_next(&miter) && offset < buflen) {
        unsigned int len;

        len = min(miter.length, buflen - offset);

        if (to_buffer)
            memcpy(buf + offset, miter.addr, len);
        else
            memcpy(miter.addr, buf + offset, len);

        offset += len;
    }

    sg_miter_stop(&miter);

    local_irq_restore(flags);
    return offset;
}

1 个答案:

答案 0 :(得分:2)

在此函数中调用的sg_miter_start()函数调用kmap_atomic(),该函数只能在原子(不可中断)代码路径中使用。反过来正在使用kmap_atomic(),因为它比普通的kmap便宜得多,因为它不需要进行全局TLB刷新。

sg_copy_buffer()的原始实现会禁用对调用者的中断,但是在一些调用者忘记后,导致错误(例如https://bugzilla.kernel.org/show_bug.cgi?id=11529)后,决定禁用函数本身的中断(参见:{{3讨论)。