Changeset 47c4490


Ignore:
Timestamp:
12/15/16 17:06:24 (4 years ago)
Author:
Richard Sanger <rsanger@…>
Branches:
4.0.1-hotfixes, cachetimestamps, develop, dpdk-ndag, etsilive, master, ndag_format, rc-4.0.1, rc-4.0.2, rc-4.0.3, rc-4.0.4, ringdecrementfix, ringperformance, ringtimestampfixes
Children:
4edb310, ceba2b2, e47ab4d
Parents:
f8613e4
Message:

Second round of fixes for Issue #39

  1. Fixes a bug in the ring format where packets could be mistakenly read twice if the packet is not 'finished' before the ring loops. This was only a problem in the parallel API and for old kernels without FANOUT support, where packets are not always finished straight away.
  1. Only read a batch of 1 packet from live formats when falling back to FIFO locking. This reduces latency, and in the case of ring stops us from ending up in a loop polling 100% CPU. This occurs as the kernel tracks the most recent packet it has put in the ring, but this is still set to TP_STATUS_USER as it is still waiting in the batch.
  1. Move the trace_interrupt code to include the 100% poll loop case above. In normal cases we won't end up here but could if an application holds on to a packet.
Location:
lib
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • lib/format_linux_ring.c

    r5e3f16c r47c4490  
    447447#ifdef HAVE_NETPACKET_PACKET_H
    448448#define LIBTRACE_MIN(a,b) ((a)<(b) ? (a) : (b))
     449/* We use TP_STATUS_LIBTRACE to ensure we don't loop back on ourself
     450 * and read the same packet twice if an old packet has not yet been freed */
     451#define TP_STATUS_LIBTRACE 0xFFFFFFFF
     452
    449453inline static int linuxring_read_stream(libtrace_t *libtrace,
    450454                                        libtrace_packet_t *packet,
     
    470474         * ready for consumption.
    471475         */
    472         while (!(header->tp_status & TP_STATUS_USER)) {
     476        while (!(header->tp_status & TP_STATUS_USER) ||
     477               header->tp_status == TP_STATUS_LIBTRACE) {
     478                if ((ret=is_halted(libtrace)) != -1)
     479                        return ret;
    473480                pollset[0].fd = stream->fd;
    474481                pollset[0].events = POLLIN;
     
    509516                        }
    510517                } else {
    511                         /* Poll timed out - check if we should exit */
    512                         if ((ret=is_halted(libtrace)) != -1)
    513                                 return ret;
     518                        /* Poll timed out - check if we should exit on next loop */
    514519                        continue;
    515520                }
     
    518523        packet->buffer = header;
    519524        packet->trace = libtrace;
     525        header->tp_status = TP_STATUS_LIBTRACE;
    520526
    521527        /* If a snaplen was configured, automatically truncate the packet to
     
    574580        /* Fetch the current frame */
    575581        header = GET_CURRENT_BUFFER(FORMAT_DATA_FIRST);
    576         if (header->tp_status & TP_STATUS_USER) {
     582        if (header->tp_status & TP_STATUS_USER &&
     583            header->tp_status != TP_STATUS_LIBTRACE) {
    577584                /* We have a frame waiting */
    578585                event.size = trace_read_packet(libtrace, packet);
  • lib/trace_parallel.c

    r5e3f16c r47c4490  
    17331733                if (libtrace->perpkt_thread_count > 1)
    17341734                        libtrace->pread = trace_pread_packet_first_in_first_served;
     1735                        /* Don't wait for a burst of packets if the format is
     1736                         * live as this could block ring based formats and
     1737                         * introduces delay. */
     1738                        if (libtrace->format->info.live) {
     1739                                libtrace->config.burst_size = 1;
     1740                        }
    17351741                else
    17361742                        /* Use standard read_packet */
Note: See TracChangeset for help on using the changeset viewer.