public inbox for [email protected]
 help / color / mirror / Atom feed
From: Hrvoje Zeba <[email protected]>
To: [email protected]
Subject: Odd timeout behavior
Date: Sat, 11 Apr 2020 19:00:17 -0400	[thread overview]
Message-ID: <CAEsUgYgTSVydbQdjVn1QuqFSHZp_JfDZxRk7KwWVSZikxY+hYg@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 885 bytes --]

Hi,

I've been looking at timeouts and found a case I can't wrap my head around.

Basically, If you submit OPs in a certain order, timeout fires before
time elapses where I wouldn't expect it to. The order is as follows:

poll(listen_socket, POLLIN) <- this never fires
nop(async)
timeout(1s, count=X)

If you set X to anything but 0xffffffff/(unsigned)-1, the timeout does
not fire (at least not immediately). This is expected apart from maybe
setting X=1 which would potentially allow the timeout to fire if nop
executes after the timeout is setup.

If you set it to 0xffffffff, it will always fire (at least on my
machine). Test program I'm using is attached.

The funny thing is that, if you remove the poll, timeout will not fire.

I'm using Linus' tree (v5.6-12604-gab6f762f0f53).

Could anybody shine a bit of light here?


Thank you,
Hrvoje

-- 
I doubt, therefore I might be.

[-- Attachment #2: nop-timeout.c --]
[-- Type: text/x-csrc, Size: 2205 bytes --]

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <time.h>
#include <poll.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <arpa/inet.h>

#include "liburing.h"

struct io_uring_sqe* get_sqe(struct io_uring* ring)
{
	struct io_uring_sqe* sqe = io_uring_get_sqe(ring);
	assert(sqe != NULL);
	return sqe;
}

void enqueue_nop(struct io_uring* ring)
{
	struct io_uring_sqe* sqe = get_sqe(ring);

	io_uring_prep_nop(sqe);
	io_uring_sqe_set_data(sqe, (void*)1);
	io_uring_sqe_set_flags(sqe, IOSQE_ASYNC);
}

void enqueue_timeout(struct io_uring* ring)
{
	struct io_uring_sqe* sqe = get_sqe(ring);
	static struct __kernel_timespec ts;

	ts.tv_sec = 1;
	ts.tv_nsec = 0;

	io_uring_prep_timeout(sqe, &ts, (unsigned)-1, 0);
	io_uring_sqe_set_data(sqe, (void*)2);
}

void enqueue_poll(struct io_uring* ring, int fd)
{
	struct io_uring_sqe* sqe = get_sqe(ring);

	io_uring_prep_poll_add(sqe, fd, POLLIN | POLLERR | POLLHUP);
	io_uring_sqe_set_data(sqe, (void*)3);
}

int create_socket()
{
	int s = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_TCP);
	assert(s != -1);

	int flags = fcntl(s, F_GETFL, 0);
	assert(flags != -1);

	flags |= O_NONBLOCK;

	assert(fcntl(s, F_SETFL, flags) != -1);

	struct sockaddr_in addr;

	addr.sin_family = AF_INET;
	addr.sin_port = 0x1236;
	addr.sin_addr.s_addr = 0x0100007fU;

	assert(bind(s, (struct sockaddr*)&addr, sizeof(addr)) != -1);
	assert(listen(s, 1024) != -1);

	return s;
}

int main(int argc, char *argv[])
{
	struct io_uring ring;
	int ret;

	ret = io_uring_queue_init(4, &ring, 0);
	if (ret) {
		fprintf(stderr, "ring setup failed\n");
		return 1;
	}

	int s = create_socket();
	enqueue_poll(&ring, s);

	enqueue_nop(&ring);
	enqueue_timeout(&ring);

	ret = io_uring_submit_and_wait(&ring, 1);
	if (ret == -1) {
		fprintf(stderr, "submit failed\n");
		return 1;
	}

	struct io_uring_cqe* cqe;
	uint32_t head;
	uint32_t count = 0;

	io_uring_for_each_cqe(&ring, head, cqe) {
		if (io_uring_cqe_get_data(cqe) == (void*)2)
			fprintf(stderr, "Timeout triggered!\n");

		count++;
	}

	io_uring_cq_advance(&ring, count);

	io_uring_queue_exit(&ring);
	return 0;
}

             reply	other threads:[~2020-04-11 23:00 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-11 23:00 Hrvoje Zeba [this message]
2020-04-12  2:07 ` Odd timeout behavior Jens Axboe
2020-04-12  9:15   ` Pavel Begunkov
2020-04-12 14:40     ` Jens Axboe
2020-04-17  8:39       ` Pavel Begunkov
2020-04-17 14:37         ` Hrvoje Zeba
2020-04-12 15:14     ` Hrvoje Zeba
2020-04-13  8:21       ` Pavel Begunkov
2020-04-13 14:16         ` Jens Axboe
2020-04-13 19:09           ` Pavel Begunkov
2020-04-14  0:44             ` Jens Axboe
2020-04-14 15:46               ` Pavel Begunkov
2020-04-14 16:04                 ` Jens Axboe
2020-04-14 16:31                   ` Pavel Begunkov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAEsUgYgTSVydbQdjVn1QuqFSHZp_JfDZxRk7KwWVSZikxY+hYg@mail.gmail.com \
    [email protected] \
    [email protected] \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox