Re: accept() improvements for rt signals

From: Julian Anastasov (uli@linux.tu-varna.acad.bg)
Date: Tue Feb 22 2000 - 10:38:45 EST


        Hello,

        I continue this thread but with another problem.

        Is there a known problem with O_NONBLOCK|O_ASYNC listening
sockets (2.2.15pre7 UP) ? I receive unexpected SIGIO after accept()
using such listening socket. Or may be the problem is near
close(conencted_socket) ?

        My test:

- the listening socket is setup with O_RDWR|O_ASYNC|O_NONBLOCK and
for rt signal SIGRTMIN+5 using F_SETFL, F_SETSIG and F_SETOWN in
this order. No threads. Only one rt signal used.

In the loop:

for (;;) {
        sigwaitinfo()
        fd = info->si_fd;
        if (fd == listener) {
                connected = accept(listener)
                fcntl F_SETFL
                fcntl F_SETSIG
                fcntl F_SETOWN
                // Fallback to (the first) read
                fd = connected;
        }
        read(fd)=18 bytes(90%) or EAGAIN(10%)
        // no write() just close if the expected data is received
        if (data ok, 18 bytes) close(fd)=0
        time(0); //<-- SIGIO received after successful close()
}

        I flood this server with only one connection, i.e.
connect(non blocking), write() 18 bytes, wait for remote EOF, close()
and loop again. So, in the server there is no rt queue overflow, etc.
Looking in rtsig-nr the max value is 1. The program doesn't detect errors
from the syscalls. I even enabled syn cookies - no warnings for
syn flood. When I flood from the local host (client and server on
same host) I have ~1400 connections/sec but no unexpected SIGIOs.
When I flood from other host on the 10Mbps LAN I receive these
unexpected SIGIOs, the speed is 300-500 connections/sec.

        When the SIGIO is received I detect that last event reported
from sigwaitinfo() is for the listener. I call accept() ...
fcntls, read() and close() and in the following syscalls I receive
the unexpected SIGIO. I added some extra time(0) after
close(connected_scoket) and the SIGIO is received 2-3 of these
syscalls after close(). I think, in these situations the SIGIO is
enqueued for the listener but should be enqueued for the connected
socket. I think this is a bug:

- SIGIO can't be received for the listener because it is setup
for SIGRTMIN+5

- SIGIO can't be received for the connected socket because F_SETOWN
is not reached yet, or I don't use the fcntls in the correct order.

- There is no rt queue overflow, I have up to 2 active sockets at
the same time: one listener and one connected socket.

        What is the reason for this unexpected SIGIO ? Is the problem
near sys_accept() ? Is get_fd() called too late for the non-blocking
accept()? May be there is a problem where sock_wake_async() is sent
using fd=listening socket instead to the the connected socket in very
small time window: the connection is accepted, the data arrived but
the fd is still not setup for the connected socket from sys_accept().
Or the problem is near F_SETOWN ? May be this is a problem in the
fasync list management?

        Any ideas?

        I can send you ltrace -S output (6KB .gz), the test programs
and the output from the server program.

Regards

--
Julian Anastasov <uli@linux.tu-varna.acad.bg>

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Feb 23 2000 - 21:00:30 EST