Skip to contentSkip to conversation

OT: problem with select() and RH 7.3

DISCUSSION Ben Greear 3 participants 3 messages May 12, 2002 – May 14, 2002

lore
Share & tools
lore

Ben Greear

author
#0 lore raw

Appologies for an OT post, but I am hoping someone here will have an answer.

It appears that the select() call as found in RH 7.3 waits too long before it returns. I come to this conclusion because I was dropping a large number of UDP packets when I allowed the
select timeout to be > 0. However, if I force the timeout to
be zero in all cases, almost no packets are dropped (but the packet generator/receiver uses all of the CPU) My traffic pattern is 10Mbps send + 10Mbps receive on 4 ports (of a DFE-570tx 4-port NIC, tulip driver), pkt size of 1200 to 1514.

If I understand select() correctly, it should work equally fast with a timeout of zero or 10 minutes, as long as the file descriptors are ready to be read from or written to.

I tried various kernels that I am sure have worked in the past, all with the same results. The only thing I can think of is that somehow glibc or whatever implements select is wierd in RH 7.3 (I'm installing RH 7.2 now to test that hypothesis.)

One interesting observation that sheds a bit of doubt on blaming glibc is that when the timeout is > 0 (ie I'm dropping packets), the ethernet driver is not receiving as many packets as the sender is sending. It also does not have any substantial amount of errors of any kind. The ports are connected via a loopback cable, and all 4 ports exhibit this behaviour. With a timeout of zero though, the send & receive counters are virtually identical.

If anyone has any ideas or suggestions, I'd love to hear them!

Signature · 3 lines
Ben Greear <[email protected]>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear
#1 lore raw
Quoted 12 lines · Ben Greear

Appologies for an OT post, but I am hoping someone here will have an answer.

It appears that the select() call as found in RH 7.3 waits too long before it returns. I come to this conclusion because I was dropping a large number of UDP packets when I allowed the
select timeout to be > 0. However, if I force the timeout to
be zero in all cases, almost no packets are dropped (but the packet generator/receiver uses all of the CPU) My traffic pattern is 10Mbps send + 10Mbps receive on 4 ports (of a DFE-570tx 4-port NIC, tulip driver), pkt size of 1200 to 1514.

Quoted 8 lines

If I understand select() correctly, it should work equally fast with a timeout of zero or 10 minutes, as long as the file descriptors are ready to be read from or written to.

I tried various kernels that I am sure have worked in the past, all with the same results. The only thing I can think of is that somehow glibc or whatever implements select is wierd in RH 7.3 (I'm installing RH 7.2 now to test that hypothesis.)

just try to exchange glibc

Quoted 7 lines

One interesting observation that sheds a bit of doubt on blaming glibc is that when the timeout is > 0 (ie I'm dropping packets), the ethernet driver is not receiving as many packets as the sender is sending. It also does not have any substantial amount of errors of any kind. The ports are connected via a loopback cable, and all 4 ports exhibit this behaviour. With a timeout of zero though, the send & receive counters are virtually identical.

...

Although that will not answer your question, just an idea, it will certanly improve things alot:

if ( select(...) > 0 ) {
    ...
    for ( ;; ) {
	if ( read(fd, buffer, size) != size )
	    break;
	... do something with your packet ...
    }
}

Besides, select(2) cannot be "fast", look at poll(2), async io, or just operate in blocking mode if your are in that critical timeline. And lookup kernel archives about poll vs. select benchmarks to find better explanation.

-alex

#2 lore raw
In reply to Ben Greear
Quoted 12 lines · Ben Greear

Appologies for an OT post, but I am hoping someone here will have an answer.

It appears that the select() call as found in RH 7.3 waits too long before it returns. I come to this conclusion because I was dropping a large number of UDP packets when I allowed the
select timeout to be > 0. However, if I force the timeout to
be zero in all cases, almost no packets are dropped (but the packet generator/receiver uses all of the CPU) My traffic pattern is 10Mbps send + 10Mbps receive on 4 ports (of a DFE-570tx 4-port NIC, tulip driver), pkt size of 1200 to 1514.

Quoted 3 lines

If I understand select() correctly, it should work equally fast with a timeout of zero or 10 minutes, as long as the file descriptors are ready to be read from or written to.

You don't understand select()/poll() correctly.
If you call select()/poll() with a timeout then every "event" has to
be added to a kernel wait queue, and then removed from the wait queue when any of those events happen or the timeout occurs.

[snip ... ]

Quoted 1 line

If anyone has any ideas or suggestions, I'd love to hear them!

Do a double poll() call, Eg. this code uses socket_poll and timer_q
from http://www.and.org/ ...

static int mypoll(void)
{
const struct timeval *tv = timer_q_first_timeval(); int ret = 0;
int msecs = -1;

  if (tv)
  {
    long diff = 0;
    struct timeval now_timeval;
    gettimeofday(&now_timeval, NULL);
    
    diff = timer_q_timeval_diff_msecs(tv, &now_timeval);
    
    if (diff > 0)
    {
      if (diff >= INT_MAX)
        msecs = INT_MAX - 1;
      else
        msecs = diff;
    }
    else
      msecs = 0;

}

  if (!(ret = socket_poll_update_all(0)) && msecs)
    return (socket_poll_update_all(msecs));

return (ret);
}

Signature · 4 lines
# James Antill -- [email protected]
:0:
* ^From: .*james@and\.org
/dev/null