]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[undi] Profile transmit and receive datapaths
authorMichael Brown <mcb30@ipxe.org>
Sat, 3 May 2014 11:34:16 +0000 (12:34 +0100)
committerMichael Brown <mcb30@ipxe.org>
Sat, 3 May 2014 18:51:38 +0000 (19:51 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/arch/i386/drivers/net/undinet.c

index e956b989adfdd3034dfbbd61de3a0aab275776a9..f83d493111156984998d04be4244784d9f9ce2e7 100644 (file)
@@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/netdevice.h>
 #include <ipxe/if_ether.h>
 #include <ipxe/ethernet.h>
+#include <ipxe/profile.h>
 #include <undi.h>
 #include <undinet.h>
 #include <pxeparent.h>
@@ -79,6 +80,26 @@ static void undinet_close ( struct net_device *netdev );
 /** Address of UNDI entry point */
 static SEGOFF16_t undinet_entry;
 
+/** Transmit profiler */
+static struct profiler undinet_tx_profiler __profiler =
+       { .name = "undinet.tx" };
+
+/** Transmit call profiler */
+static struct profiler undinet_tx_call_profiler __profiler =
+       { .name = "undinet.tx_call" };
+
+/** IRQ profiler */
+static struct profiler undinet_irq_profiler __profiler =
+       { .name = "undinet.irq" };
+
+/** ISR call profiler */
+static struct profiler undinet_isr_call_profiler __profiler =
+       { .name = "undinet.isr_call" };
+
+/** Receive profiler */
+static struct profiler undinet_rx_profiler __profiler =
+       { .name = "undinet.rx" };
+
 /*****************************************************************************
  *
  * UNDI interrupt service routine
@@ -194,6 +215,9 @@ static int undinet_transmit ( struct net_device *netdev,
        size_t len;
        int rc;
 
+       /* Start profiling */
+       profile_start ( &undinet_tx_profiler );
+
        /* Technically, we ought to make sure that the previous
         * transmission has completed before we re-use the buffer.
         * However, many PXE stacks (including at least some Intel PXE
@@ -256,14 +280,16 @@ static int undinet_transmit ( struct net_device *netdev,
        undinet_tbd.Xmit.offset = __from_data16 ( basemem_packet );
 
        /* Issue PXE API call */
+       profile_start ( &undinet_tx_call_profiler );
        if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_TRANSMIT,
                                     &undi_transmit,
                                     sizeof ( undi_transmit ) ) ) != 0 )
                goto done;
+       profile_stop ( &undinet_tx_call_profiler );
 
        /* Free I/O buffer */
        netdev_tx_complete ( netdev, iobuf );
-
+       profile_stop ( &undinet_tx_profiler );
  done:
        return rc;
 }
@@ -316,10 +342,12 @@ static void undinet_poll ( struct net_device *netdev ) {
                 */
                if ( ! undinet_isr_triggered() ) {
                        /* Allow interrupt to occur */
+                       profile_start ( &undinet_irq_profiler );
                        __asm__ __volatile__ ( REAL_CODE ( "sti\n\t"
                                                           "nop\n\t"
                                                           "nop\n\t"
                                                           "cli\n\t" ) : : );
+                       profile_stop ( &undinet_irq_profiler );
 
                        /* If interrupts are known to be supported,
                         * then do nothing on this poll; wait for the
@@ -339,16 +367,19 @@ static void undinet_poll ( struct net_device *netdev ) {
 
        /* Run through the ISR loop */
        while ( 1 ) {
+               profile_start ( &undinet_isr_call_profiler );
                if ( ( rc = pxeparent_call ( undinet_entry, PXENV_UNDI_ISR,
                                             &undi_isr,
                                             sizeof ( undi_isr ) ) ) != 0 )
                        break;
+               profile_stop ( &undinet_isr_call_profiler );
                switch ( undi_isr.FuncFlag ) {
                case PXENV_UNDI_ISR_OUT_TRANSMIT:
                        /* We don't care about transmit completions */
                        break;
                case PXENV_UNDI_ISR_OUT_RECEIVE:
                        /* Packet fragment received */
+                       profile_start ( &undinet_rx_profiler );
                        len = undi_isr.FrameLength;
                        frag_len = undi_isr.BufferLength;
                        reserve_len = ( -undi_isr.FrameHeaderLength &
@@ -393,6 +424,7 @@ static void undinet_poll ( struct net_device *netdev ) {
                                if ( undinic->hacks & UNDI_HACK_EB54 )
                                        --last_trigger_count;
                        }
+                       profile_stop ( &undinet_rx_profiler );
                        break;
                case PXENV_UNDI_ISR_OUT_DONE:
                        /* Processing complete */