The profile utility can set the sprofiling mode

- profile --nmi | --rtc sets the profiling mode

- --rtc is default, uses BIOS RTC, cannot profile kernel the presetted
  frequency values apply

- --nmi is only available in APIC mode as it uses the NMI watchdog, -f
  allows any frequency in Hz

- both modes use compatible data structures
This commit is contained in:
Tomas Hruby 2010-09-23 10:49:42 +00:00
parent db12229ce3
commit 74c5cd7668
8 changed files with 45 additions and 12 deletions

View file

@ -48,6 +48,7 @@ int action = 0;
int mem_size = 0; int mem_size = 0;
int mem_used = 0; int mem_used = 0;
int freq = 0; int freq = 0;
int intr_type = PROF_RTC;
char *outfile = ""; char *outfile = "";
char *mem_ptr; char *mem_ptr;
int outfile_fd, npipe_fd; int outfile_fd, npipe_fd;
@ -104,15 +105,27 @@ int main(int argc, char *argv[])
break; break;
} }
/*
* Check the frequency when we know the intr type. Only selected values
* are correct for RTC
*/
if (action == START && intr_type == PROF_RTC &&
freq < MIN_FREQ || freq > MAX_FREQ) {
printf("Incorrect frequency.\n");
return 1;
}
printf("Statistical Profiling:\n"); printf("Statistical Profiling:\n");
printf(" profile start [-m memsize] [-o outfile] [-f frequency]\n"); printf(" profile start [--rtc | --nmi] "
"[-m memsize] [-o outfile] [-f frequency]\n");
printf(" profile stop\n\n"); printf(" profile stop\n\n");
printf(" --rtc is default, --nmi allows kernel profiling\n");
printf("Call Profiling:\n"); printf("Call Profiling:\n");
printf(" profile get [-m memsize] [-o outfile]\n"); printf(" profile get [-m memsize] [-o outfile]\n");
printf(" profile reset\n\n"); printf(" profile reset\n\n");
printf(" - memsize in MB, default: %u\n", DEF_MEMSIZE); printf(" - memsize in MB, default: %u\n", DEF_MEMSIZE);
printf(" - default output file: profile.{stat|call}.out\n"); printf(" - default output file: profile.{stat|call}.out\n");
printf( " - sample frequencies (default: %u):\n", DEF_FREQ); printf( " - sample frequencies for --rtc (default: %u):\n", DEF_FREQ);
printf(" 3 8192 Hz 10 64 Hz\n"); printf(" 3 8192 Hz 10 64 Hz\n");
printf(" 4 4096 Hz 11 32 Hz\n"); printf(" 4 4096 Hz 11 32 Hz\n");
printf(" 5 2048 Hz 12 16 Hz\n"); printf(" 5 2048 Hz 12 16 Hz\n");
@ -160,13 +173,19 @@ int handle_args(int argc, char *argv[])
} else } else
if (strcmp(*argv, "-f") == 0) { if (strcmp(*argv, "-f") == 0) {
if (--argc == 0) return ESYNTAX; if (--argc == 0) return ESYNTAX;
if (sscanf(*++argv, "%u", &freq) != 1 || if (sscanf(*++argv, "%u", &freq) != 1)
freq < MIN_FREQ || freq > MAX_FREQ) return EFREQ; return EFREQ;
} else } else
if (strcmp(*argv, "-o") == 0) { if (strcmp(*argv, "-o") == 0) {
if (--argc == 0) return ESYNTAX; if (--argc == 0) return ESYNTAX;
outfile = *++argv; outfile = *++argv;
} else } else
if (strcmp(*argv, "--rtc") == 0) {
intr_type = PROF_RTC;
} else
if (strcmp(*argv, "--nmi") == 0) {
intr_type = PROF_NMI;
} else
if (strcmp(*argv, "start") == 0) { if (strcmp(*argv, "start") == 0) {
if (action) return EACTION; if (action) return EACTION;
action = START; action = START;
@ -224,7 +243,7 @@ int start()
if (alloc_mem()) return 1; if (alloc_mem()) return 1;
if (sprofile(PROF_START, mem_size, freq, &sprof_info, mem_ptr)) { if (sprofile(PROF_START, mem_size, freq, intr_type, &sprof_info, mem_ptr)) {
perror("sprofile"); perror("sprofile");
printf("Error starting profiling.\n"); printf("Error starting profiling.\n");
return 1; return 1;
@ -280,7 +299,7 @@ int stop()
int n; int n;
char buf[BUFSIZE]; char buf[BUFSIZE];
if (sprofile(PROF_STOP, 0, 0, 0, 0)) { if (sprofile(PROF_STOP, 0, 0, 0, 0, 0)) {
perror("sprofile"); perror("sprofile");
printf("Error stopping profiling.\n"); printf("Error stopping profiling.\n");
return 1; return 1;

View file

@ -590,6 +590,7 @@
#define PROF_MEM_SIZE m7_i2 /* available memory for data */ #define PROF_MEM_SIZE m7_i2 /* available memory for data */
#define PROF_FREQ m7_i3 /* sample frequency */ #define PROF_FREQ m7_i3 /* sample frequency */
#define PROF_ENDPT m7_i4 /* endpoint of caller */ #define PROF_ENDPT m7_i4 /* endpoint of caller */
#define PROF_INTR_TYPE m7_i5 /* interrupt type */
#define PROF_CTL_PTR m7_p1 /* location of info struct */ #define PROF_CTL_PTR m7_p1 /* location of info struct */
#define PROF_MEM_PTR m7_p2 /* location of profiling data */ #define PROF_MEM_PTR m7_p2 /* location of profiling data */

View file

@ -22,7 +22,7 @@ typedef struct {long m4l1, m4l2, m4l3, m4l4, m4l5;} mess_4;
typedef struct {short m5s1, m5s2; int m5i1, m5i2; long m5l1, m5l2, m5l3;}mess_5; typedef struct {short m5s1, m5s2; int m5i1, m5i2; long m5l1, m5l2, m5l3;}mess_5;
typedef struct {long m6l1, m6l2, m6l3; short m6s1, m6s2, m6s3; char m6c1, m6c2; typedef struct {long m6l1, m6l2, m6l3; short m6s1, m6s2, m6s3; char m6c1, m6c2;
char *m6p1, *m6p2;} mess_6; char *m6p1, *m6p2;} mess_6;
typedef struct {int m7i1, m7i2, m7i3, m7i4; char *m7p1, *m7p2;} mess_7; typedef struct {int m7i1, m7i2, m7i3, m7i4, m7i5; char *m7p1, *m7p2;} mess_7;
typedef struct {int m8i1, m8i2; char *m8p1, *m8p2, *m8p3, *m8p4;} mess_8; typedef struct {int m8i1, m8i2; char *m8p1, *m8p2, *m8p3, *m8p4;} mess_8;
typedef struct {long m9l1, m9l2, m9l3, m9l4, m9l5; typedef struct {long m9l1, m9l2, m9l3, m9l4, m9l5;
short m9s1, m9s2, m9s3, m9s4; } mess_9; short m9s1, m9s2, m9s3, m9s4; } mess_9;
@ -94,6 +94,7 @@ typedef struct {
#define m7_i2 m_u.m_m7.m7i2 #define m7_i2 m_u.m_m7.m7i2
#define m7_i3 m_u.m_m7.m7i3 #define m7_i3 m_u.m_m7.m7i3
#define m7_i4 m_u.m_m7.m7i4 #define m7_i4 m_u.m_m7.m7i4
#define m7_i5 m_u.m_m7.m7i5
#define m7_p1 m_u.m_m7.m7p1 #define m7_p1 m_u.m_m7.m7p1
#define m7_p2 m_u.m_m7.m7p2 #define m7_p2 m_u.m_m7.m7p2

View file

@ -14,6 +14,9 @@
# define PROF_START 0 /* start statistical profiling */ # define PROF_START 0 /* start statistical profiling */
# define PROF_STOP 1 /* stop statistical profiling */ # define PROF_STOP 1 /* stop statistical profiling */
#define PROF_RTC 0 /* RTC based profiling */
#define PROF_NMI 1 /* NMI based profiling, profiles kernel too */
/* Info struct to be copied to from kernel to user program. */ /* Info struct to be copied to from kernel to user program. */
struct sprof_info_s { struct sprof_info_s {
int mem_used; int mem_used;
@ -101,7 +104,7 @@ struct cprof_tbl_s {
u64_t cycles; /* execution time of path, in cycles */ u64_t cycles; /* execution time of path, in cycles */
} cprof_tbl_inst; } cprof_tbl_inst;
_PROTOTYPE( int sprofile, (int action, int size, int freq, _PROTOTYPE( int sprofile, (int action, int size, int freq, int type,
void *ctl_ptr, void *mem_ptr) ); void *ctl_ptr, void *mem_ptr) );
_PROTOTYPE( int cprofile, (int action, int size, void *ctl_ptr, _PROTOTYPE( int cprofile, (int action, int size, void *ctl_ptr,

View file

@ -257,7 +257,7 @@ _PROTOTYPE( int pci_get_bar, (int devind, int port, u32_t *base,
u32_t *size, int *ioflag) ); u32_t *size, int *ioflag) );
/* Profiling. */ /* Profiling. */
_PROTOTYPE( int sys_sprof, (int action, int size, int freq, _PROTOTYPE( int sys_sprof, (int action, int size, int freq, int type,
endpoint_t endpt, void *ctl_ptr, void *mem_ptr) ); endpoint_t endpt, void *ctl_ptr, void *mem_ptr) );
_PROTOTYPE( int sys_cprof, (int action, int size, endpoint_t endpt, _PROTOTYPE( int sys_cprof, (int action, int size, endpoint_t endpt,
void *ctl_ptr, void *mem_ptr) ); void *ctl_ptr, void *mem_ptr) );

View file

@ -2,13 +2,19 @@
#define sprofile _sprofile #define sprofile _sprofile
PUBLIC int sprofile(int action, int size, int freq, char *ctl_ptr, int *mem_ptr) PUBLIC int sprofile(int action,
int size,
int freq,
int type,
char *ctl_ptr,
int *mem_ptr)
{ {
message m; message m;
m.PROF_ACTION = action; m.PROF_ACTION = action;
m.PROF_MEM_SIZE = size; m.PROF_MEM_SIZE = size;
m.PROF_FREQ = freq; m.PROF_FREQ = freq;
m.PROF_INTR_TYPE = type;
m.PROF_CTL_PTR = (void *) ctl_ptr; m.PROF_CTL_PTR = (void *) ctl_ptr;
m.PROF_MEM_PTR = (void *) mem_ptr; m.PROF_MEM_PTR = (void *) mem_ptr;

View file

@ -5,10 +5,11 @@
/*===========================================================================* /*===========================================================================*
* sys_sprof * * sys_sprof *
*===========================================================================*/ *===========================================================================*/
PUBLIC int sys_sprof(action, size, freq, endpt, ctl_ptr, mem_ptr) PUBLIC int sys_sprof(action, size, freq, type, endpt, ctl_ptr, mem_ptr)
int action; /* start/stop profiling */ int action; /* start/stop profiling */
int size; /* available profiling memory */ int size; /* available profiling memory */
int freq; /* sample frequency */ int freq; /* sample frequency */
int type;
endpoint_t endpt; /* caller endpoint */ endpoint_t endpt; /* caller endpoint */
void *ctl_ptr; /* location of info struct */ void *ctl_ptr; /* location of info struct */
void *mem_ptr; /* location of profiling memory */ void *mem_ptr; /* location of profiling memory */
@ -18,6 +19,7 @@ void *mem_ptr; /* location of profiling memory */
m.PROF_ACTION = action; m.PROF_ACTION = action;
m.PROF_MEM_SIZE = size; m.PROF_MEM_SIZE = size;
m.PROF_FREQ = freq; m.PROF_FREQ = freq;
m.PROF_INTR_TYPE = type;
m.PROF_ENDPT = endpt; m.PROF_ENDPT = endpt;
m.PROF_CTL_PTR = ctl_ptr; m.PROF_CTL_PTR = ctl_ptr;
m.PROF_MEM_PTR = mem_ptr; m.PROF_MEM_PTR = mem_ptr;

View file

@ -38,10 +38,11 @@ PUBLIC int do_sprofile(void)
return r; return r;
return sys_sprof(PROF_START, m_in.PROF_MEM_SIZE, m_in.PROF_FREQ, return sys_sprof(PROF_START, m_in.PROF_MEM_SIZE, m_in.PROF_FREQ,
m_in.PROF_INTR_TYPE,
who_e, m_in.PROF_CTL_PTR, m_in.PROF_MEM_PTR); who_e, m_in.PROF_CTL_PTR, m_in.PROF_MEM_PTR);
case PROF_STOP: case PROF_STOP:
return sys_sprof(PROF_STOP,0,0,0,0,0); return sys_sprof(PROF_STOP,0,0,0,0,0,0);
default: default:
return EINVAL; return EINVAL;