summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brown2014-05-03 01:52:43 +0200
committerMichael Brown2014-05-03 19:52:15 +0200
commit579337c368d1a763a6c5786999c760d63b29cfd4 (patch)
tree609d9929cfe2d94acd0293307c42167fb9c8fb1d /src
parent[librm] Add profiling self-tests for complete real_call and prot_call cycles (diff)
downloadipxe-579337c368d1a763a6c5786999c760d63b29cfd4.tar.gz
ipxe-579337c368d1a763a6c5786999c760d63b29cfd4.tar.xz
ipxe-579337c368d1a763a6c5786999c760d63b29cfd4.zip
[pxe] Profile all PXE API calls
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src')
-rw-r--r--src/arch/i386/interface/pxe/pxe_call.c49
1 files changed, 49 insertions, 0 deletions
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 <ipxe/uaccess.h>
#include <ipxe/init.h>
+#include <ipxe/profile.h>
#include <setjmp.h>
#include <registers.h>
#include <biosint.h>
@@ -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
*
@@ -81,6 +102,27 @@ static struct pxe_api_call * find_pxe_api_call ( uint16_t opcode ) {
}
/**
+ * 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
*
* @v bx PXE opcode
@@ -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, &params, call->params_len );
ix86->regs.ax = ret;
+
+ /* Stop profiling, if applicable */
+ profile_stop ( profiler );
}
/**