开发者

Is it necessary to disable IRQ during copying memory for sg_copy_buffer?

Here is the function of sg_copy_buffer for Linux kernel 2.6.32. Is it necessary to disable IRQ during copying memory?

 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;
}
开发者_C百科


The sg_miter_start() function that is called in this function calls kmap_atomic(), which can only be used inside atomic (non interruptible) code paths. kmap_atomic() in turn is being used since it is MUCH cheaper then a regular kmap, since it does not need to do a global TLB flush.

The original implementation of sg_copy_buffer() left disabling interrupts to the caller, but after some callers forgot, causing bugs (e.g. https://bugzilla.kernel.org/show_bug.cgi?id=11529) the decision was made to disable interrupt in the function itself (see: http://www.spinics.net/lists/linux-scsi/msg29428.html for the discussion).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜