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:
parent
db12229ce3
commit
74c5cd7668
8 changed files with 45 additions and 12 deletions
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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) );
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue