Linux 대기열은 입력/출력 위치(__kfifo.in/__kfifo.out)의 오버플로를 어떻게 처리합니까?

Linux 대기열은 입력/출력 위치(__kfifo.in/__kfifo.out)의 오버플로를 어떻게 처리합니까?

저는 현재 Linux 대기열 구현(kfifo)과 관련된 작업을 진행 중입니다.

최근에 나는 발견했다.존재하다내의 변수구조__kfifo지속적으로 증가하며 사용하기 전에 마스크와 비트 단위 AND를 수행하면 간단히 사용할 수 있습니다. 그러나 큐잉 함수(__kfifo_in)는 오버플로 관련 문제를 처리하지 않는 것 같습니다.__kfifo.in. 나는 이것이 몇 가지 문제를 일으킬 수 있다고 생각합니다.__kfifo.out보다 클 것이다__kfifo.in. 예를 들어,kfifo_len매크로 사용법 __tmpl->kfifo.in - __tmpl->kfifo.out;.

내가 무엇을 놓치고 있나요? Linux는 이 오버플로를 어떻게, 어디서 처리합니까?


아래 코드는 제가 언급한 __kfifo_in이며 Linux 5.4에서 발견되었습니다.

unsigned int __kfifo_in(struct __kfifo *fifo,
        const void *buf, unsigned int len)
{
    unsigned int l;

    l = kfifo_unused(fifo);
    if (len > l)
        len = l;

    kfifo_copy_in(fifo, buf, len, fifo->in);
    fifo->in += len;
    return len;
}

답변1

in는 fifo에 푸시된 총 바이트 수이고 outfifo에서 팝된 총 바이트 수입니다. 논리적으로는 in항상 >= out이지만 모든 유한 정수 표현에는 오버플로가 있습니다.

unsigned int가 단일 바이트(범위 0..255)로 표현된다고 가정하면 256바이트를 푸시하지만 255바이트만 팝됩니다. 이 경우 kfifo_unused반환됩니다.

(fifo->마스크 + 1) - (fifo->in - fifo->out) = (full_queue_space) -(used_space) = (remaning_space) = (full_queue_space) -(0-255) = (full_queue_space) - (1 ) .

실제로 0x00 - 0xFF = 0x01을 표현하는데 1바이트가 사용됩니다.

관련 정보