tcpdump mailing list archives

[PATCH] Bugfix/improvement for linux mmap ring buffer


From: Dustin Spicuzza <dustin () virtualroadside com>
Date: Wed, 15 Jul 2009 15:40:51 -0400

Found this bug while trying to add the buffer statistics API. git
formatted patch attached:

- Fixed bug where create_ring would fail for particular snaplen and
buffer size combinations
- Changed ring allocation to retry with 5% less buffer size instead of 50%



-- 
Innovation is just a problem away
From 219c99d5830c79b336f63dcc10debab37a41ce1b Mon Sep 17 00:00:00 2001
From: Dustin Spicuzza <dustin () virtualroadside com>
Date: Wed, 15 Jul 2009 14:58:16 -0400
Subject: [PATCH] Bugfix/improvement for linux mmap ring buffer

- Fixed bug where create_ring would fail for particular snaplen and buffer size combinations
- Changed ring allocation to retry with 5% less buffer size instead of 50%
---
 pcap-linux.c |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/pcap-linux.c b/pcap-linux.c
index b1a00ce..c91cd6e 100644
--- a/pcap-linux.c
+++ b/pcap-linux.c
@@ -2599,20 +2599,27 @@ create_ring(pcap_t *handle)
                req.tp_block_size <<= 1;
 
        frames_per_block = req.tp_block_size/req.tp_frame_size;
-
+       
+       /* ask the kernel to create the ring */
+retry:
        req.tp_block_nr = req.tp_frame_nr / frames_per_block;
 
        /* req.tp_frame_nr is requested to match frames_per_block*req.tp_block_nr */
        req.tp_frame_nr = req.tp_block_nr * frames_per_block;
-
-       /* ask the kernel to create the ring */
-retry:
+       
        if (setsockopt(handle->fd, SOL_PACKET, PACKET_RX_RING,
                                        (void *) &req, sizeof(req))) {
                /* try to reduce requested ring size to prevent memory failure */
                if ((errno == ENOMEM) && (req.tp_block_nr > 1)) {
-                       req.tp_frame_nr >>= 1;
-                       req.tp_block_nr = req.tp_frame_nr/frames_per_block;
+                       /* used to reduce this by half -- do 5% instead. May result in
+                        * more iterations and longer startup, but the user will be much
+                        * happier with the resulting buffer size
+                        */
+                       if (req.tp_frame_nr < 20)
+                               req.tp_frame_nr -= 1;
+                       else
+                               req.tp_frame_nr -= req.tp_frame_nr/20;
+                       
                        goto retry;
                }
                if (errno == ENOPROTOOPT) {
-- 
1.6.0.4

Attachment: signature.asc
Description: OpenPGP digital signature


Current thread: