lkml.org 
[lkml]   [1998]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
Subjectselect()/poll() bug report
This is a Linux kernel v2.1.xxx bug report.  Linus says the bug has
been around forever and that it is unlikely to get fixed for v2.2
unless someone sends him a patch that is "obviously correct" and
reasonably clean and fast.

IMHO, this bug is quite serious because any web server allowing more
than 256 HTTP/1.1 connections will see at least serious performance
problems or even complete client lock outs (were a client can't
connect to the web server even though the machine is mostly idle).

Anyone have any cycles available to look into this? If not, maybe it
could at least be documented somewhere as a known bug?

Thanks,

--david
----
The following program demonstrates a bug in Linux v2.1.127. The
problem is that if a select or poll attempts to monitor more than 256
filedescriptors, all but the 256 first filedescriptors are silently
ignored. This has the potential to lead to performance bugs or
outright application failures. The problem is due to the fact one
page can hold only 256 "struct poll_table_entry" elements. Thus,
__MAX_POLL_TABLE_ENTRIES in include/linux/poll.h gets defined to 256.
When calling poll_wait() and the poll table is full, the passed file
pointer is sliently dropped.

The expected behavior of the program is that after starting it up, you
hit the Enter key and then see the output:

$ a.out

nfds=1
bit 256 is set

However, with Linux v2.1.127, entering an empty line will _not_ cause
the select() to return.

<---------------------------------------------------------------->
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/resource.h> /* grrr, must come after sys/types.h for BSD */

#define panic(foo) { perror (foo); exit (-1); }

#define NUM_FDS 257
#define THE_INDEX 256

int
main (int argc, char **argv)
{
int i, fd, nfds, max_fd = -1;
struct rlimit rlimit;
fd_set rdfds;

/* boost open file limit to the max: */
if (getrlimit (RLIMIT_NOFILE, &rlimit) < 0)
panic ("getrlimit");
rlimit.rlim_cur = rlimit.rlim_max;
if (setrlimit (RLIMIT_NOFILE, &rlimit) < 0)
panic ("setrlimit");

FD_ZERO (&rdfds);
for (i = 0; i < NUM_FDS; ++i)
{
if (i == THE_INDEX)
fd = dup (0);
else
{
fd = socket (AF_INET, SOCK_STREAM, 0);
if (fd < 0) panic ("socket");
}
if (fd < 0)
panic ("open");
if (fd > max_fd)
max_fd = fd;
FD_SET (fd, &rdfds);
}
nfds = select (max_fd + 1, &rdfds, 0, 0, 0);
printf ("nfds=%d\n", nfds);
for (i = 0; i < NUM_FDS; ++i)
if (FD_ISSET (i+3, &rdfds))
printf ("bit %d is set\n", i);
}

-
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/

\
 
 \ /
  Last update: 2005-03-22 13:45    [W:0.066 / U:0.056 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site