summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2014-05-03 13:34:16 +0200
committerMichael Brown2014-05-03 20:51:38 +0200
commit402ce65632843282c182a50415ad5b7cbb5fb5b0 (patch)
tree089cf3990cc536fab0d24279d8f6a966c7554544 /src
parent[undi] Profile all PXE API calls (diff)
downloadipxe-402ce65632843282c182a50415ad5b7cbb5fb5b0.tar.gz
ipxe-402ce65632843282c182a50415ad5b7cbb5fb5b0.tar.xz
ipxe-402ce65632843282c182a50415ad5b7cbb5fb5b0.zip
[undi] Profile transmit and receive datapaths
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/drivers/net/undinet.c34
1 files changed, 33 insertions, 1 deletions
diff --git a/src/arch/i386/drivers/net/undinet.c b/src/arch/i386/drivers/net/undinet.c
index e956b989a..f83d49311 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 <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 */