tcpdump mailing list archives

Re: libpcap & poll()


From: Eloy Paris <peloy () chapus net>
Date: Thu, 13 Nov 2008 16:31:54 -0500

Hi Aaron,

On Thu, Nov 13, 2008 at 12:57:00PM -0800, Aaron Turner wrote:

I've been told by an end user under Linux 2.6.x at least that, he's
seeing very high CPU utilization numbers with tcpbridge which uses
libpcap to read packets.  Sounds like the cause of the issue is that
I'm using poll() to determine when to read from libpcap.  I'm using
poll() because my code listens on multiple interfaces, hence I need a
way to look at multiple pcap handles.

Questions basically boil down to:
1) Is this expected?
2) Is there a better way?

I am not aware of what you describe being expected behavior - poll() and
select() exist in part to prevent the high CPU utilization associated
with continously trying to read from multiple file descriptors that
don't have data ready to be read (doing that has basically the same
effect of a "while (1);" loop - high CPU.)

Your use of poll() seems the best way of handling multiple interfaces; I
don't think there's a better way, and if there is I'd love to know about
it too since I am not aware of it. In some of my code I use select()
instead of poll() but my understanding is that one is a wrapper around
the other (which one exactly is the function being wrapped depends on
the operating system.)

One possible reason for high CPU when using poll() or select() is
spurious readiness notifications - in this case the program is not
sleeping waiting for data but is instead running, causing high CPU.

Both the poll() and select() manual pages on Linux have the following
comment:

"Under Linux, select() may report a socket file descriptor as "ready
for reading", while nevertheless a subsequent read blocks. This could
for example happen when data has arrived but upon examination has wrong
checksum and is discarded. There may be other circumstances in which a
file descriptor is spuriously reported as ready. Thus it may be safer to
use O_NONBLOCK on sockets that should not block."

This has never been an issue for me although you could look into it.
This could cause high CPU only if you call pcap_setnonblock() for the
packet capture descriptors, and you experience the problem described
above, though.

Have you recreated the issue that the end-user reports? A very basic and
simple troubleshooting technique that has always been very helpful for
me is putting a "printf("select() returned %d\n", retval");" after a
"retval = select(...)" (in your case poll() ) call. You could tell your
user to do that to see how often you're coming back from poll().

If the network is pretty busy and there's lots of data to be read from
the packet capture descriptors then high CPU is obviously expected. has
the user indicated how busy the network is?

Cheers,

Eloy Paris.-
netexpect.org
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.


Current thread: