From 579337c368d1a763a6c5786999c760d63b29cfd4 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Sat, 3 May 2014 00:52:43 +0100 Subject: [PATCH] [pxe] Profile all PXE API calls Signed-off-by: Michael Brown --- src/arch/i386/interface/pxe/pxe_call.c | 49 ++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/arch/i386/interface/pxe/pxe_call.c b/src/arch/i386/interface/pxe/pxe_call.c index a07433368..657d47b6c 100644 --- a/src/arch/i386/interface/pxe/pxe_call.c +++ b/src/arch/i386/interface/pxe/pxe_call.c @@ -21,6 +21,7 @@ FILE_LICENCE ( GPL2_OR_LATER ); #include #include +#include #include #include #include @@ -48,6 +49,26 @@ extern void pxe_int_1a ( void ); /** INT 1A hooked flag */ static int int_1a_hooked = 0; +/** PXENV_UNDI_TRANSMIT API call profiler */ +static struct profiler pxe_api_tx_profiler __profiler = + { .name = "pxeapi.tx" }; + +/** PXENV_UNDI_ISR API call profiler */ +static struct profiler pxe_api_isr_profiler __profiler = + { .name = "pxeapi.isr" }; + +/** PXE unknown API call profiler + * + * This profiler can be used to measure the overhead of a dummy PXE + * API call. + */ +static struct profiler pxe_api_unknown_profiler __profiler = + { .name = "pxeapi.unknown" }; + +/** Miscellaneous PXE API call profiler */ +static struct profiler pxe_api_misc_profiler __profiler = + { .name = "pxeapi.misc" }; + /** * Handle an unknown PXE API call * @@ -80,6 +101,27 @@ static struct pxe_api_call * find_pxe_api_call ( uint16_t opcode ) { return NULL; } +/** + * Determine applicable profiler (for debugging) + * + * @v opcode PXE opcode + * @ret profiler Profiler + */ +static struct profiler * pxe_api_profiler ( unsigned int opcode ) { + + /* Determine applicable profiler */ + switch ( opcode ) { + case PXENV_UNDI_TRANSMIT: + return &pxe_api_tx_profiler; + case PXENV_UNDI_ISR: + return &pxe_api_isr_profiler; + case PXENV_UNKNOWN: + return &pxe_api_unknown_profiler; + default: + return &pxe_api_misc_profiler; + } +} + /** * Dispatch PXE API call * @@ -90,10 +132,14 @@ static struct pxe_api_call * find_pxe_api_call ( uint16_t opcode ) { __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { uint16_t opcode = ix86->regs.bx; userptr_t uparams = real_to_user ( ix86->segs.es, ix86->regs.di ); + struct profiler *profiler = pxe_api_profiler ( opcode ); struct pxe_api_call *call; union u_PXENV_ANY params; PXENV_EXIT_t ret; + /* Start profiling */ + profile_start ( profiler ); + /* Locate API call */ call = find_pxe_api_call ( opcode ); if ( ! call ) { @@ -113,6 +159,9 @@ __asmcall void pxe_api_call ( struct i386_all_regs *ix86 ) { /* Copy modified parameter block back to caller and return */ copy_to_user ( uparams, 0, ¶ms, call->params_len ); ix86->regs.ax = ret; + + /* Stop profiling, if applicable */ + profile_stop ( profiler ); } /**