From 402ce65632843282c182a50415ad5b7cbb5fb5b0 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 3 May 2014 12:34:16 +0100 Subject: [PATCH] [undi] Profile transmit and receive datapaths Signed-off-by: Michael Brown --- src/arch/i386/drivers/net/undinet.c | 34 ++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/arch/i386/drivers/net/undinet.c b/src/arch/i386/drivers/net/undinet.c index e956b989..f83d4931 100644 --- a/src/arch/i386/drivers/net/undinet.c +++ b/src/arch/i386/drivers/net/undinet.c @@ -33,6 +33,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include +#include #include #include #include @@ -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 */