diff options
| author | Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com> | 2020-07-09 04:15:29 +0300 | 
|---|---|---|
| committer | Jens Axboe <axboe@kernel.dk> | 2020-07-09 04:17:06 +0300 | 
| commit | 6d5f904904608a9cd32854d7d0a4dd65b27f9935 (patch) | |
| tree | 2d862b5112e2cd9aae79a988e8c1a00768a5f122 /tools/perf/scripts/python/netdev-times.py | |
| parent | b7db41c9e03b5189bc94993bd50e4506ac9e34c1 (diff) | |
| download | linux-6d5f904904608a9cd32854d7d0a4dd65b27f9935.tar.xz | |
io_uring: export cq overflow status to userspace
For those applications which are not willing to use io_uring_enter()
to reap and handle cqes, they may completely rely on liburing's
io_uring_peek_cqe(), but if cq ring has overflowed, currently because
io_uring_peek_cqe() is not aware of this overflow, it won't enter
kernel to flush cqes, below test program can reveal this bug:
static void test_cq_overflow(struct io_uring *ring)
{
        struct io_uring_cqe *cqe;
        struct io_uring_sqe *sqe;
        int issued = 0;
        int ret = 0;
        do {
                sqe = io_uring_get_sqe(ring);
                if (!sqe) {
                        fprintf(stderr, "get sqe failed\n");
                        break;;
                }
                ret = io_uring_submit(ring);
                if (ret <= 0) {
                        if (ret != -EBUSY)
                                fprintf(stderr, "sqe submit failed: %d\n", ret);
                        break;
                }
                issued++;
        } while (ret > 0);
        assert(ret == -EBUSY);
        printf("issued requests: %d\n", issued);
        while (issued) {
                ret = io_uring_peek_cqe(ring, &cqe);
                if (ret) {
                        if (ret != -EAGAIN) {
                                fprintf(stderr, "peek completion failed: %s\n",
                                        strerror(ret));
                                break;
                        }
                        printf("left requets: %d\n", issued);
                        continue;
                }
                io_uring_cqe_seen(ring, cqe);
                issued--;
                printf("left requets: %d\n", issued);
        }
}
int main(int argc, char *argv[])
{
        int ret;
        struct io_uring ring;
        ret = io_uring_queue_init(16, &ring, 0);
        if (ret) {
                fprintf(stderr, "ring setup failed: %d\n", ret);
                return 1;
        }
        test_cq_overflow(&ring);
        return 0;
}
To fix this issue, export cq overflow status to userspace by adding new
IORING_SQ_CQ_OVERFLOW flag, then helper functions() in liburing, such as
io_uring_peek_cqe, can be aware of this cq overflow and do flush accordingly.
Signed-off-by: Xiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'tools/perf/scripts/python/netdev-times.py')
0 files changed, 0 insertions, 0 deletions
