You can subscribe to this list here.
2001 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(7) |
Aug
(50) |
Sep
(210) |
Oct
(93) |
Nov
(99) |
Dec
(101) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2002 |
Jan
(283) |
Feb
(42) |
Mar
(148) |
Apr
(94) |
May
(256) |
Jun
(206) |
Jul
(101) |
Aug
(28) |
Sep
(159) |
Oct
(102) |
Nov
(216) |
Dec
(159) |
2003 |
Jan
(112) |
Feb
(149) |
Mar
(332) |
Apr
(261) |
May
(528) |
Jun
(270) |
Jul
(231) |
Aug
(231) |
Sep
(338) |
Oct
(445) |
Nov
(212) |
Dec
(26) |
2004 |
Jan
(179) |
Feb
(109) |
Mar
(20) |
Apr
(20) |
May
(55) |
Jun
(11) |
Jul
(38) |
Aug
(13) |
Sep
(28) |
Oct
(13) |
Nov
(41) |
Dec
(30) |
2005 |
Jan
(17) |
Feb
(4) |
Mar
(62) |
Apr
(176) |
May
(44) |
Jun
(13) |
Jul
(16) |
Aug
(154) |
Sep
(6) |
Oct
(13) |
Nov
(4) |
Dec
(6) |
2006 |
Jan
(12) |
Feb
(11) |
Mar
(9) |
Apr
(1) |
May
(10) |
Jun
(6) |
Jul
(10) |
Aug
(10) |
Sep
(27) |
Oct
(25) |
Nov
(40) |
Dec
(18) |
2007 |
Jan
(13) |
Feb
(25) |
Mar
(6) |
Apr
(14) |
May
(52) |
Jun
(22) |
Jul
(20) |
Aug
(8) |
Sep
(2) |
Oct
(138) |
Nov
(152) |
Dec
(73) |
2008 |
Jan
(52) |
Feb
(31) |
Mar
(5) |
Apr
(48) |
May
(20) |
Jun
(14) |
Jul
(36) |
Aug
(16) |
Sep
(1) |
Oct
(19) |
Nov
(13) |
Dec
(4) |
2009 |
Jan
(2) |
Feb
(13) |
Mar
(10) |
Apr
(28) |
May
(46) |
Jun
(21) |
Jul
(21) |
Aug
(22) |
Sep
(8) |
Oct
(25) |
Nov
(15) |
Dec
(2) |
2010 |
Jan
(12) |
Feb
|
Mar
(8) |
Apr
(3) |
May
(2) |
Jun
(5) |
Jul
(11) |
Aug
(17) |
Sep
|
Oct
(12) |
Nov
(14) |
Dec
(10) |
2011 |
Jan
(6) |
Feb
|
Mar
(8) |
Apr
(6) |
May
(17) |
Jun
(8) |
Jul
(4) |
Aug
(9) |
Sep
(2) |
Oct
(3) |
Nov
(4) |
Dec
(2) |
2012 |
Jan
(4) |
Feb
(7) |
Mar
(16) |
Apr
(9) |
May
(15) |
Jun
(22) |
Jul
(30) |
Aug
(36) |
Sep
(6) |
Oct
(5) |
Nov
(9) |
Dec
(11) |
2013 |
Jan
(17) |
Feb
(11) |
Mar
(7) |
Apr
(8) |
May
(15) |
Jun
(19) |
Jul
(27) |
Aug
(3) |
Sep
(3) |
Oct
(8) |
Nov
(6) |
Dec
(10) |
2014 |
Jan
(15) |
Feb
(16) |
Mar
(4) |
Apr
(3) |
May
(10) |
Jun
(9) |
Jul
(9) |
Aug
(31) |
Sep
(11) |
Oct
(6) |
Nov
(4) |
Dec
(3) |
2015 |
Jan
(2) |
Feb
(1) |
Mar
(2) |
Apr
(3) |
May
(4) |
Jun
(5) |
Jul
(14) |
Aug
(2) |
Sep
(2) |
Oct
(1) |
Nov
(4) |
Dec
(4) |
2016 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
(4) |
May
(2) |
Jun
|
Jul
(2) |
Aug
(1) |
Sep
(1) |
Oct
(3) |
Nov
(1) |
Dec
|
2017 |
Jan
(4) |
Feb
|
Mar
(1) |
Apr
(3) |
May
|
Jun
(9) |
Jul
(11) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2018 |
Jan
(1) |
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(3) |
Jul
(10) |
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2019 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
(6) |
Jun
|
Jul
(2) |
Aug
(2) |
Sep
(1) |
Oct
|
Nov
|
Dec
(1) |
2020 |
Jan
|
Feb
|
Mar
(2) |
Apr
|
May
|
Jun
|
Jul
(4) |
Aug
|
Sep
(1) |
Oct
|
Nov
|
Dec
|
2021 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(1) |
Dec
|
From: John L. <mov...@us...> - 2001-09-15 20:55:48
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv30034/pp Modified Files: Makefile.in oprofpp.c Log Message: post-prof fixes for 4 counters, and some other changes. Philippe, please check. Index: Makefile.in =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/Makefile.in,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- Makefile.in 2001/09/02 00:32:28 1.16 +++ Makefile.in 2001/09/15 20:55:45 1.17 @@ -13,7 +13,7 @@ MKDIR_P=mkdir -p INSTALL_LIST=oprofpp oprof_convert opf_filter op_to_source -install: $(INSTALL_LIST) +install: all $(INSTALL_LIST) -$(MKDIR_P) $(BINDIR) for f in $(INSTALL_LIST); do \ cp $$f $(BINDIR)/$$f && chmod 755 $(BINDIR)/$$f; \ Index: oprofpp.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- oprofpp.c 2001/09/13 16:08:19 1.42 +++ oprofpp.c 2001/09/15 20:55:45 1.43 @@ -148,6 +148,19 @@ exit(EXIT_FAILURE); } + /* check only one major mode specified */ + if ((list_all_symbols_details + list_symbols + (gproffile != 0) + (symbol != 0)) > 1) { + fprintf(stderr, "oprofpp: must specify only one output type.\n"); + poptPrintHelp(optcon, stderr, 0); + exit(EXIT_FAILURE); + } + + if (output_linenr_info && !list_all_symbols_details && !symbol) { + fprintf(stderr, "oprofpp: cannot list debug info without -L or -s option.\n"); + poptPrintHelp(optcon, stderr, 0); + exit(EXIT_FAILURE); + } + /* non-option file, either a sample or binary image file */ file = poptGetArg(optcon); @@ -220,11 +233,12 @@ if (file_ctr_str) file_ctr_str[0] = '\0'; - if (ctr != -1 && (ctr < 0 || ctr >= (int)op_nr_counters)) { - ctr = 0; - - fprintf(stderr, "oprofpp: invalid counter number, using %d\n", ctr); - + /* yes, OP_MAX_COUNTERS. We should initially allow for seeing if + * there are samples for any counter + */ + if (ctr != -1 && (ctr < 0 || ctr >= OP_MAX_COUNTERS)) { + fprintf(stderr, "oprofpp: invalid counter number %u\n", ctr); + exit(EXIT_FAILURE); } } @@ -421,6 +435,45 @@ } /** + * translate_address - lookup and output linenr info from a vma address + * in a given section to standard output. + * @ibfd: the bfd + * @syms: pointer to array of symbol pointers + * @section: the section containing the vma + * @pc: the virtual memory address + * + * Do not change output format without changing the corresponding tools + * that work with output from oprofpp. + */ +static void +translate_address (bfd* ibfd, asymbol **syms, asection *section, bfd_vma pc) +{ + int found; + bfd_vma vma; + + const char *filename; + const char *functionname; + unsigned int line; + + if ((bfd_get_section_flags (ibfd, section) & SEC_ALLOC) == 0) + return; + + vma = bfd_get_section_vma (ibfd, section); + if (pc < vma) + return; + + found = bfd_find_nearest_line (ibfd, section, syms, pc - vma, + &filename, &functionname, &line); + + if (!found) { + printf ("??:0"); + } + else { + printf ("%s:%u", filename, line); + } +} + +/** * get_symbols - get symbols from bfd * @ibfd: bfd to read from * @symsp: pointer to array of symbol pointers @@ -568,11 +621,6 @@ } } - if (ctr == -1 || samples[ctr] == NULL) { - fprintf(stderr, " oprofpp: invalid counter %d before sort by count\n", ctr); - exit(EXIT_FAILURE); - } - qsort(scounts, num, sizeof(struct opp_count), countcomp); for (i=0; i < num; i++) { @@ -618,16 +666,25 @@ found: printf("Samples for symbol \"%s\" in image %s\n", symbol, ibfd->filename); get_symbol_range(syms[i], (i == num-1) ? NULL : syms[i+1], &start, &end); - for (j=start; j < end; j++) { + for (j=start; j < end; j++) { for (k = 0 ; k < op_nr_counters ; ++k) { - if (samples[k] && samples[k][j].count) { - printf("%s+%x/%x:", symbol, sym_offset(syms[i], j), end-start); + if (samples[k] && samples[k][j].count) break; - } } /* k != op_nr_counters <==> one of the counter is not empty */ if (k != op_nr_counters) { + bfd_vma vma, base_vma; + base_vma = syms[i]->value + syms[i]->section->vma; + vma = sym_offset(syms[i], j) + base_vma; + + if (output_linenr_info) { + translate_address(ibfd, syms, syms[i]->section, vma); + printf(" "); + } + + printf("%s+%x/%x:", symbol, sym_offset(syms[i], j), end-start); + for (k = 0 ; k < op_nr_counters ; ++k) { if (samples[k]) /* PHE: please keep this space a few @@ -734,45 +791,6 @@ } /** - * translate_address - lookup and output linenr info from a vma address - * in a given section to standard output. - * @ibfd: the bfd - * @syms: pointer to array of symbol pointers - * @section: the section containing the vma - * @pc: the virtual memory address - * - * Do not change output format without changing the corresponding tools - * that work with output from oprofpp. - */ -static void -translate_address (bfd* ibfd, asymbol **syms, asection *section, bfd_vma pc) -{ - int found; - bfd_vma vma; - - const char *filename; - const char *functionname; - unsigned int line; - - if ((bfd_get_section_flags (ibfd, section) & SEC_ALLOC) == 0) - return; - - vma = bfd_get_section_vma (ibfd, section); - if (pc < vma) - return; - - found = bfd_find_nearest_line (ibfd, section, syms, pc - vma, - &filename, &functionname, &line); - - if (!found) { - printf ("??:0"); - } - else { - printf ("%s:%u", filename, line); - } -} - -/** * accumulate_samples - lookup and output linenr info from a vma address * in a given section to standard output. * @counter: where to accumulate the samples @@ -1115,6 +1133,14 @@ verbprintf("nr_samples %d\n", nr_samples); + for (i = 0; i < OP_MAX_COUNTERS; ++i) { + if (fd[i] != -1) + break; + } + + if (footer[i]->cpu_type == CPU_ATHLON) + op_nr_counters = 4; + ibfd = open_image_file(samplefile, mtime); num = get_symbols(ibfd, &syms); @@ -1125,14 +1151,6 @@ fprintf(stderr, "oprofpp: couldn't get any symbols from image file.\n"); exit(EXIT_FAILURE); } - - for (i = 0; i < OP_MAX_COUNTERS; ++i) { - if (fd[i] != -1) - break; - } - - if (footer[i]->cpu_type == CPU_ATHLON) - op_nr_counters = 4; if (list_all_symbols_details) /* TODO: temporary hack to fix and easy life of opf_filter.cpp |
From: John L. <mov...@us...> - 2001-09-15 20:55:48
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv30034 Modified Files: ChangeLog Makefile.in Log Message: post-prof fixes for 4 counters, and some other changes. Philippe, please check. Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.112 retrieving revision 1.113 diff -u -d -r1.112 -r1.113 --- ChangeLog 2001/09/15 01:51:30 1.112 +++ ChangeLog 2001/09/15 20:55:45 1.113 @@ -1,3 +1,10 @@ +2001-09-15 John Levon <mo...@co...> + + * all Makefile.in: install should depend on all + + * oprofpp.c: fixes for Athlon 4 counters. Enable debug info + for list-symbol. Some stricter checking + 2001-09-15 Philippe Elie <ph...@cl...> * op_events.c: some static variable to global Index: Makefile.in =================================================================== RCS file: /cvsroot/oprofile/oprofile/Makefile.in,v retrieving revision 1.25 retrieving revision 1.26 diff -u -d -r1.25 -r1.26 --- Makefile.in 2001/09/01 02:03:34 1.25 +++ Makefile.in 2001/09/15 20:55:45 1.26 @@ -43,7 +43,7 @@ tags: ctags -R -install: oprofile.o +install: all oprofile.o -$(MKDIR_P) $(MODINSTALLDIR) cp oprofile.o $(MODINSTALLDIR) depmod -a |
From: Philippe E. <ph...@us...> - 2001-09-15 01:51:33
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv20163/oprofile/dae Modified Files: opd_proc.c Log Message: needed by oprof_start which come later Index: opd_proc.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/opd_proc.c,v retrieving revision 1.70 retrieving revision 1.71 diff -u -d -r1.70 -r1.71 --- opd_proc.c 2001/09/12 01:22:41 1.70 +++ opd_proc.c 2001/09/15 01:51:30 1.71 @@ -390,7 +390,7 @@ /* truncate to grow the file is ok on linux, and probably ok in POSIX. * I am unsure than don't touch the last page and un-sparse a little * what the samples file */ - if (ftruncate(sample_file->fd, image->len + sizeof(struct opd_footer) - 1) == -1) { + if (ftruncate(sample_file->fd, image->len + sizeof(struct opd_footer)) == -1) { fprintf(stderr, "oprofiled: ftruncate failed for \"%s\". %s\n", mangled, strerror(errno)); goto err2; } |
From: Philippe E. <ph...@us...> - 2001-09-15 01:51:33
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv20163/oprofile Modified Files: ChangeLog op_events.c op_user.h oprofile.c Log Message: needed by oprof_start which come later Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.111 retrieving revision 1.112 diff -u -d -r1.111 -r1.112 --- ChangeLog 2001/09/14 18:17:05 1.111 +++ ChangeLog 2001/09/15 01:51:30 1.112 @@ -1,3 +1,12 @@ +2001-09-15 Philippe Elie <ph...@cl...> + + * op_events.c: some static variable to global + * op_user.h: export these + + * oprofile.c: typo in comment + + * dae/opd_proc.c: fix size of samples files + 2001-09-13 Dave Jones <da...@su...> * doc/oprofile.1.in: Index: op_events.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_events.c,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- op_events.c 2001/09/12 02:54:30 1.24 +++ op_events.c 2001/09/15 01:51:30 1.25 @@ -31,33 +31,6 @@ #include "op_user.h" -enum unit_mask_type { - /* useless but required by the hardware */ - utm_mandatory, - /* only one of the values is allowed */ - utm_exclusive, - /* bitmask */ - utm_bitmask -}; - -struct op_event { - uint counter_mask; /* bitmask of allowed counter */ - u16 cpu_mask; /* bitmask of allowed cpu_type */ - u8 val; /* event number */ - u8 unit; /* which unit mask if any allowed */ - const char *name; - int min_count; /* minimum counter value allowed */ -}; - -struct op_unit_mask { - uint num; /* number of possible unit masks */ - enum unit_mask_type unit_type_mask; - /* only the gui use it */ - u8 default_mask; - /* up to seven allowed unit masks */ - u8 um[7]; -}; - static const char* cpu_type_str[MAX_CPU_TYPE] = { "Pentium Pro", "PII", @@ -65,9 +38,9 @@ "Athlon" }; -static struct op_unit_mask op_unit_masks[] = { - /* use by the gui */ - { 1, utm_mandatory, 0x0f, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, }, +struct op_unit_mask op_unit_masks[] = { + /* reserved empty entry */ + { 0, utm_mandatory, 0x00, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, }, /* MESI counters */ { 5, utm_bitmask, 0x0f, { 0x8, 0x4, 0x2, 0x1, 0xf, 0x0, 0x0 }, }, /* EBL self/any default to any transitions */ @@ -96,8 +69,8 @@ #define CTR_0 (1 << 0) #define CTR_1 (1 << 1) -/* Allowed, Event #, unit mask, name, minimum event value */ -static struct op_event op_events[] = { +/* ctr allowed, Event #, unit mask, name, minimum event value */ +struct op_event op_events[] = { /* Clocks */ { CTR_ALL, OP_IA_ALL, 0x79, 0, "CPU_CLK_UNHALTED", 6000 }, /* Data Cache Unit (DCU) */ @@ -227,7 +200,8 @@ { CTR_ALL, OP_ATHLON, 0xcf, 0, "HARDWARE_INTERRUPTS", 500,}, }; -#define op_nr_events (sizeof(op_events)/sizeof(op_events[0])) +/* the total number of events for all processor type */ +uint op_nr_events = (sizeof(op_events)/sizeof(op_events[0])); /** * op_check_unit_mask - sanity check unit mask value @@ -505,11 +479,8 @@ #endif /* !defined(MODULE) */ #ifdef OP_EVENTS_DESC -struct op_unit_desc { - char *desc[7]; -}; -static struct op_unit_desc op_unit_descs[] = { +struct op_unit_desc op_unit_descs[] = { { { NULL, NULL, NULL, NULL, NULL, NULL, NULL, }, }, { { "(M)odified cache state", "(E)xclusive cache state", @@ -549,7 +520,7 @@ "all MOESI cache state", NULL, }, }, }; -static char *op_event_descs[] = { +char *op_event_descs[] = { "clocks processor is not halted", /* Data Cache Unit (DCU) */ "all memory references, cachable and non", Index: op_user.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_user.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- op_user.h 2001/09/12 05:21:57 1.8 +++ op_user.h 2001/09/15 01:51:30 1.9 @@ -156,6 +156,10 @@ /* size of hash map in bytes */ #define OP_HASH_MAP_SIZE (OP_HASH_MAP_NR * sizeof(struct op_hash)) +#ifdef __cplusplus +extern "C" { +#endif + /* op_events.c */ int op_min_count(u8 ctr_type, int cpu_type); int op_check_events(int ctr, u8 ctr_type, u8 ctr_um, int cpu_type); @@ -164,5 +168,49 @@ int op_check_events_str(int ctr, char *ctr_type, u8 ctr_um, int cpu_type, u8 *ctr_t); void op_get_event_desc(int cpu_type, u8 type, u8 um, char **typenamep, char **typedescp, char **umdescp); int op_get_cpu_type(void); + +#ifdef __cplusplus +} +#endif + +/* op_events.c: stuff needed by oprof_start and opf_filter.cpp */ + +enum unit_mask_type { + /* useless but required by the hardware */ + utm_mandatory, + /* only one of the values is allowed */ + utm_exclusive, + /* bitmask */ + utm_bitmask +}; + +struct op_event { + uint counter_mask; /* bitmask of allowed counter */ + u16 cpu_mask; /* bitmask of allowed cpu_type */ + u8 val; /* event number */ + u8 unit; /* which unit mask if any allowed */ + const char *name; + int min_count; /* minimum counter value allowed */ +}; + +struct op_unit_mask { + uint num; /* number of possible unit masks */ + enum unit_mask_type unit_type_mask; + /* only the gui use it */ + u8 default_mask; + /* up to seven allowed unit masks */ + u8 um[7]; +}; + +struct op_unit_desc { + char *desc[7]; +}; + +extern struct op_unit_mask op_unit_masks[]; +extern struct op_unit_desc op_unit_descs[]; +extern char *op_event_descs[]; +extern struct op_event op_events[]; +/* the total number of events for all processor type */ +extern uint op_nr_events; #endif /* OP_USER_H */ Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.87 retrieving revision 1.88 diff -u -d -r1.87 -r1.88 --- oprofile.c 2001/09/12 14:30:20 1.87 +++ oprofile.c 2001/09/15 01:51:30 1.88 @@ -215,7 +215,7 @@ } } - /* Here all setup is made except the start/stop bit 21), counter + /* Here all setup is made except the start/stop bit 22, counter * disabled contains zeros in the eventsel msr except the reserved bit * 21 */ } |
From: Dave J. <da...@us...> - 2001-09-14 18:17:08
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv2570 Modified Files: ChangeLog Log Message: oops, forgot yesterdays changelog Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.110 retrieving revision 1.111 diff -u -d -r1.110 -r1.111 --- ChangeLog 2001/09/12 22:22:40 1.110 +++ ChangeLog 2001/09/14 18:17:05 1.111 @@ -1,3 +1,10 @@ +2001-09-13 Dave Jones <da...@su...> + + * doc/oprofile.1.in: + Update so it doesn't say 'Intel only' + * dae/op_start: + Fix output so that it prints [0-3] instead of [0-4[ + 2001-09-12 Philippe Elie <ph...@cl...> * pp/oprofpp.c: fix cpu type output for opf_filter |
From: Dave J. <da...@us...> - 2001-09-13 17:14:45
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv16702 Added Files: op_start Log Message: Executable bit on op_start set. |
From: Dave J. <da...@us...> - 2001-09-13 17:14:19
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv16571 Removed Files: op_start Log Message: remove op_start (Will re-add in a minute to see if it'll become +x) --- op_start DELETED --- |
From: Dave J. <da...@us...> - 2001-09-13 17:10:00
|
Update of /cvsroot/oprofile/oprofile/doc In directory usw-pr-cvs1:/tmp/cvs-serv15275/doc Modified Files: oprofile.1.in Log Message: Update so that it doesn't say Intel only. Index: oprofile.1.in =================================================================== RCS file: /cvsroot/oprofile/oprofile/doc/oprofile.1.in,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- oprofile.1.in 2001/09/08 21:46:04 1.7 +++ oprofile.1.in 2001/09/13 17:09:57 1.8 @@ -27,10 +27,10 @@ .B oprof_convert .br .SH DESCRIPTION -oprofile is a profiling system for Intel x86 systems running Linux 2.4. Profiling runs +oprofile is a profiling system for x86 systems running Linux 2.4. Profiling runs transparently during the background, and profile data can be collected at any time. oprofile -makes use of the hardware performance counters provided on Intel P6 processors. See the HTML -documentation for further details. +makes use of the hardware performance counters provided on Intel P6, and AMD Athlon family processors. +See the HTML documentation for further details. .SH OPTIONS .br |
From: Dave J. <da...@us...> - 2001-09-13 16:08:22
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv28914/pp Modified Files: oprofpp.c Log Message: Hmm, oprofpp needs to support 4 counters where available. Index: oprofpp.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- oprofpp.c 2001/09/12 22:22:40 1.41 +++ oprofpp.c 2001/09/13 16:08:19 1.42 @@ -66,6 +66,7 @@ { "dump-gprof-file", 'g', POPT_ARG_STRING, &gproffile, 0, "dump gprof format file", "file", }, { "list-symbol", 's', POPT_ARG_STRING, &symbol, 0, "give detailed samples for a symbol", "symbol", }, { "demangle", 'd', POPT_ARG_NONE, &demangle, 0, "demangle GNU C++ symbol names", NULL, }, + /* DJ FIXME: --counter should show max-counter.*/ { "counter", 'c', POPT_ARG_INT, &ctr, 0, "which counter to use", "0|1", }, { "version", 'v', POPT_ARG_NONE, &showvers, 0, "show version", NULL, }, { "verbose", 'V', POPT_ARG_NONE, &verbose, 0, "verbose output", NULL, }, |
From: Dave J. <da...@us...> - 2001-09-13 16:02:55
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv26902/dae Modified Files: op_start Log Message: op_help was printing out... Allowed range for N is [0-4[ now prints out... Allowed range for N is [0-3] Index: op_start =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_start,v retrieving revision 1.42 retrieving revision 1.43 diff -u -d -r1.42 -r1.43 --- op_start 2001/09/12 17:10:50 1.42 +++ op_start 2001/09/13 16:02:53 1.43 @@ -77,7 +77,7 @@ --ctrN-unit-mask=val unit mask for ctr N --ctrN-kernel=[0|1] whether to count kernel events for ctr N --ctrN-user=[0|1] whether to count user events for ctr N - Allowed range for N is [0-$OP_MAX_COUNTERS[ + Allowed range for N is [0-$MAX_COUNTER] --pid-filter=pid Only profile process pid --pgrp-filter=pgrp Only profile process group pgrp @@ -118,9 +118,11 @@ case "$CPUTYPE" in 0|1|2) OP_MAX_COUNTERS=2 + MAX_COUNTER=1 ;; 3) OP_MAX_COUNTERS=4 + MAX_COUNTER=3 ;; *) echo "Unknown cpu type \"$CPUTYPE\"" |
From: Philippe E. <ph...@us...> - 2001-09-12 22:22:44
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv12635/oprofile Modified Files: ChangeLog Log Message: -m Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.109 retrieving revision 1.110 diff -u -d -r1.109 -r1.110 --- ChangeLog 2001/09/12 17:10:50 1.109 +++ ChangeLog 2001/09/12 22:22:40 1.110 @@ -1,3 +1,9 @@ +2001-09-12 Philippe Elie <ph...@cl...> + + * pp/oprofpp.c: fix cpu type output for opf_filter + + * dae/op_stop: return error code properly + 2001-09-12 John Levon <mo...@co...> * pp/oprofpp.c: print name of cpu type |
From: Philippe E. <ph...@us...> - 2001-09-12 22:22:44
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv12635/oprofile/pp Modified Files: oprofpp.c Log Message: -m Index: oprofpp.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- oprofpp.c 2001/09/12 17:10:51 1.40 +++ oprofpp.c 2001/09/12 22:22:40 1.41 @@ -1133,7 +1133,12 @@ if (footer[i]->cpu_type == CPU_ATHLON) op_nr_counters = 4; - printf("Cpu type: %s\n", op_get_cpu_type_str(footer[i]->cpu_type)); + if (list_all_symbols_details) + /* TODO: temporary hack to fix and easy life of opf_filter.cpp + * Will be cleanup when linking opf_filter with oprofpp. */ + printf("Cpu type: %d\n", footer[i]->cpu_type); + else + printf("Cpu type: %s\n", op_get_cpu_type_str(footer[i]->cpu_type)); printf("Cpu speed was (MHz estimation) : %f\n", footer[i]->cpu_speed); |
From: Philippe E. <ph...@us...> - 2001-09-12 22:22:44
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv12635/oprofile/dae Modified Files: op_stop Log Message: -m Index: op_stop =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_stop,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- op_stop 2001/09/12 17:10:50 1.8 +++ op_stop 2001/09/12 22:22:40 1.9 @@ -21,4 +21,8 @@ then echo "Stopping profiling and killing daemon" kill $PID + exit fi + +# if profiler is not started consider as ok to try to stop it. +exit 0 |
From: John L. <mov...@us...> - 2001-09-12 17:10:54
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv29164 Modified Files: ChangeLog TODO Log Message: code tidies Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.108 retrieving revision 1.109 diff -u -d -r1.108 -r1.109 --- ChangeLog 2001/09/12 14:30:20 1.108 +++ ChangeLog 2001/09/12 17:10:50 1.109 @@ -1,5 +1,12 @@ 2001-09-12 John Levon <mo...@co...> + * pp/oprofpp.c: print name of cpu type + + * dae/op_stop: + * dae/op_start: re-organise, tidy + +2001-09-12 John Levon <mo...@co...> + * oprofile.c: fix small but triggerable SMP dump race Index: TODO =================================================================== RCS file: /cvsroot/oprofile/oprofile/TODO,v retrieving revision 1.12 retrieving revision 1.13 diff -u -d -r1.12 -r1.13 --- TODO 2001/08/19 20:09:17 1.12 +++ TODO 2001/09/12 17:10:50 1.13 @@ -2,8 +2,6 @@ ----------- o Save counter state and restore on a finish -o Athlon: bit 22 is per-counter, determine working event types, support 4 counters, documentation -o SMP mappings - place in all buffers perhaps ? o check chroot() processes and the path hash stuff o There is no need for the daemon to run as root as long as every binary image is readable ... @@ -14,17 +12,18 @@ Performance ----------- -o The note spinlock and stop/start should be grouped into one for multiple map adding. +o SMP algo can be totally re-worked to use a separate map device +o I think we can drop the thread if we are careful about locking/ints in the NMI handler o investigate eviction strategy o the interrupt handler code could probably be improved by moving into asm o can we fold in the "untouched sample entry" case in hash table to another case ? o change the path component hash to be pointer-parent pairs, and allocate the strings in a pool - prolly saving locality for the hash map +o daemon should not compose the path each time. use head component as lookup value WBNI ---- o good support for determining changed profiles -o compile-time interrupt accounting (sysctl-read/writeable) - then re-do results/rates/ o we don't really need a vmlinux file during profiling ... o Other x86 processors |
From: John L. <mov...@us...> - 2001-09-12 17:10:54
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv29164/dae Modified Files: op_start op_stop Log Message: code tidies Index: op_start =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_start,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- op_start 2001/09/08 21:46:04 1.41 +++ op_start 2001/09/12 17:10:50 1.42 @@ -21,69 +21,6 @@ SYSCTL=do_sysctl -BUF_SIZE=262144 -HASH_SIZE=65536 -KERNEL_ONLY=0 -IGNORE_MYSELF=0 -DIR="/var/opd" -MAP_FILE= -VMLINUX= -PID_FILTER=0 -PGRP_FILTER=0 -VERBOSE=0 - -CPUTYPE=`op_help --get-cpu-type` - -case $CPUTYPE in - 0|1|2) - OP_MAX_COUNTERS=2 - ;; - 3) - OP_MAX_COUNTERS=4 - ;; -esac - -# we can now default define individual counter setup variable. -f=0 -while (( $f < $OP_MAX_COUNTERS )); do - CTR_USER[$f]=1 - CTR_KERNEL[$f]=1 - f=$(($f+1)) -done - -do_help() { -echo "op_start: usage: -Module options - --buffer-size=num number of samples in kernel buffer - --hash-table-size=num number of entries in kernel hash table - --kernel-only=[0|1] profile only the kernel - --ctrN-event=name symbolic event name for ctr N - --ctrN-count=val number of events between samples for ctr N - --ctrN-unit-mask=val unit mask for ctr N - --ctrN-kernel=[0|1] whether to count kernel events for ctr N - --ctrN-user=[0|1] whether to count user events for ctr N -Allowed range for N is [0-$OP_MAX_COUNTERS[ - --pid-filter=pid Only profile process pid - --pgrp-filter=pgrp Only profile process group pgrp - -Daemon options - --ignore-myself=[0|1] ignore samples for oprofiled - --log-file=file log file - --base-dir=dir base directory of daemon - --samples-dir=file output samples directory - --device-file=file profile device file - --hash-map-device-file=file profile hash map device file - --map-file=file System.map for running kernel file - --vmlinux=file vmlinux kernel image - --verbose be verbose in the daemon log - -General options - --list-events list event types and unit masks - --help this message" -} - -# utilities functions. - # A replacement function for the sysctl (procps package) utility which is # missing on some distribution (e.g. slack 7.0). # Handle only the -w option of sysctl. @@ -115,329 +52,410 @@ if (($val >= $OP_MAX_COUNTERS || $val < 0)); then echo "invalid argument $1: bad counter number" + exit 1 fi echo $val } -LOG_FILE= -SAMPLES_DIR= -DEVICE_FILE= +# verbose echo +vecho() { + if [ "$VERBOSE" == "0" ]; then + return; + fi + echo $@ +} + +# print help message +do_help() { + echo "op_start: usage: + Module options + --buffer-size=num number of samples in kernel buffer + --hash-table-size=num number of entries in kernel hash table + --kernel-only=[0|1] profile only the kernel + --ctrN-event=name symbolic event name for ctr N + --ctrN-count=val number of events between samples for ctr N + --ctrN-unit-mask=val unit mask for ctr N + --ctrN-kernel=[0|1] whether to count kernel events for ctr N + --ctrN-user=[0|1] whether to count user events for ctr N + Allowed range for N is [0-$OP_MAX_COUNTERS[ + --pid-filter=pid Only profile process pid + --pgrp-filter=pgrp Only profile process group pgrp -# get specified options + Daemon options + --ignore-myself=[0|1] ignore samples for oprofiled + --log-file=file log file + --base-dir=dir base directory of daemon + --samples-dir=file output samples directory + --device-file=file profile device file + --hash-map-device-file=file profile hash map device file + --map-file=file System.map for running kernel file + --vmlinux=file vmlinux kernel image + --verbose be verbose in the daemon log -while [ "$#" -ne 0 ] -do - arg=`echo $1 | awk -F= '{print $1}'` - val=`echo $1 | awk -F= '{print $2}'` - case "$arg" in - --ignore-myself) - if [ "$val" != "" ]; then - IGNORE_MYSELF=$val - else - IGNORE_MYSELF=1 - fi - ;; - --buffer-size) - BUF_SIZE=$val - ;; - --hash-table-size) - HASH_SIZE=$val - ;; - --kernel-only) - if [ "$val" != "" ]; then - KERNEL_ONLY=$val - else - KERNEL_ONLY=1 - fi - ;; - --ctr*-unit-mask) - CTR_UM[`extract_int $arg`]=$val - ;; - --ctr*-event) - CTR_EVENT[`extract_int $arg`]=$val - ;; - --ctr*-count) - CTR_COUNT[`extract_int $arg`]=$val - ;; - --ctr*-user) - CTR_USER[`extract_int $arg`]=$val - ;; - --ctr*-kernel) - CTR_KERNEL[`extract_int $arg`]=$val - ;; - --base-dir) - DIR=$val - ;; - --samples-dir) - SAMPLES_DIR=$val - ;; - --log-file) - LOG_FILE=$val - ;; - --device-file) - DEVICE_FILE=$val - ;; - --hash-map-device-file) - HASH_MAP_DEVICE_FILE=$val - ;; - --map-file) - MAP_FILE=$val - ;; - --vmlinux) - VMLINUX=$val - ;; - --pid-filter) - PID_FILTER=$val - ;; - --pgrp-filter) - PGRP_FILTER=$val - ;; - --verbose) - VERBOSE=1 - ;; - --help) - do_help - exit 0 - ;; + General options + --list-events list event types and unit masks + --help this message" +} - --list-events) - exec op_help +# initialise parameters +do_init() { + LOG_FILE= + SAMPLES_DIR= + DEVICE_FILE= + BUF_SIZE=262144 + HASH_SIZE=65536 + KERNEL_ONLY=0 + IGNORE_MYSELF=0 + DIR="/var/opd" + MAP_FILE= + VMLINUX= + PID_FILTER=0 + PGRP_FILTER=0 + VERBOSE=0 + + CPUTYPE=`op_help --get-cpu-type` + + case "$CPUTYPE" in + 0|1|2) + OP_MAX_COUNTERS=2 ;; + 3) + OP_MAX_COUNTERS=4 + ;; *) - echo "Unknown option \"$arg\". See op_start --help" + echo "Unknown cpu type \"$CPUTYPE\"" exit 1 - ;; + ;; esac - shift -done -if [[ ${#CTR_EVENT[*]} == 0 ]]; then - echo "You haven't specified what events you would like to count, e.g." - echo "op_start ... --ctr0-event=CPU_CLK_UNHALTED --ctr0-count=600000" - echo "Enter op_start --help for full options" - exit 1 -fi + # we can now default define individual counter setup variable. + f=0 + while (( $f < $OP_MAX_COUNTERS )); do + CTR_USER[$f]=1 + CTR_KERNEL[$f]=1 + f=$(($f+1)) + done +} -f=0 -while (( $f < $OP_MAX_COUNTERS )); do - if [[ ${#CTR_EVENT[$f]} != 0 ]]; then - if [ -z "${CTR_COUNT[$f]}" ]; then - echo "Event but no count specified for counter $f" - exit 1 - fi - CTR_EVENT_VAL[$f]=`op_help ${CTR_EVENT[$f]}` - if [ -z "${CTR_EVENT_VAL[$f]}" -a ! -z "${CTR_EVENT[$f]}" ]; then - echo "Unknown event \"${CTR_EVENT[$f]}\"" - exit 1 - fi - else - if [ ! -z "${CTR_COUNT[$f]}" ]; then - echo "Count but no event specified for counter $f" - exit 1 + +# get and check specified options +do_options() { + while [ "$#" -ne 0 ] + do + arg=`echo $1 | awk -F= '{print $1}'` + val=`echo $1 | awk -F= '{print $2}'` + case "$arg" in + --ignore-myself) + if [ "$val" != "" ]; then + IGNORE_MYSELF=$val + else + IGNORE_MYSELF=1 + fi + ;; + --buffer-size) + BUF_SIZE=$val + ;; + --hash-table-size) + HASH_SIZE=$val + ;; + --kernel-only) + if [ "$val" != "" ]; then + KERNEL_ONLY=$val + else + KERNEL_ONLY=1 + fi + ;; + --ctr*-unit-mask) + CTR_UM[`extract_int $arg`]=$val + ;; + --ctr*-event) + CTR_EVENT[`extract_int $arg`]=$val + ;; + --ctr*-count) + CTR_COUNT[`extract_int $arg`]=$val + ;; + --ctr*-user) + CTR_USER[`extract_int $arg`]=$val + ;; + --ctr*-kernel) + CTR_KERNEL[`extract_int $arg`]=$val + ;; + --base-dir) + DIR=$val + ;; + --samples-dir) + SAMPLES_DIR=$val + ;; + --log-file) + LOG_FILE=$val + ;; + --device-file) + DEVICE_FILE=$val + ;; + --hash-map-device-file) + HASH_MAP_DEVICE_FILE=$val + ;; + --map-file) + MAP_FILE=$val + ;; + --vmlinux) + VMLINUX=$val + ;; + --pid-filter) + PID_FILTER=$val + ;; + --pgrp-filter) + PGRP_FILTER=$val + ;; + --verbose) + VERBOSE=1 + ;; + --help) + do_help + exit 0 + ;; + + --list-events) + exec op_help + ;; + *) + echo "Unknown option \"$arg\". See op_start --help" + exit 1 + ;; + esac + shift + done + + one_enabled=0 + f=0 + while (( $f < $OP_MAX_COUNTERS )); do + if [[ ${#CTR_EVENT[$f]} != 0 ]]; then + CTR_EVENT_VAL[$f]=`op_help ${CTR_EVENT[$f]}` + if [ -z "${CTR_EVENT_VAL[$f]}" -a ! -z "${CTR_EVENT[$f]}" ]; then + echo "Unknown event \"${CTR_EVENT[$f]}\"" + exit 1 + fi + if [ -z "${CTR_COUNT[$f]}" ]; then + echo "Event but no count specified for counter $f" + exit 1 + fi + one_enabled=1 + else + if [ ! -z "${CTR_COUNT[$f]}" ]; then + echo "Count but no event specified for counter $f" + exit 1 + fi fi + f=$(($f+1)) + done + + if [ "$one_enabled" == "0" ]; then + echo "You haven't specified what events you would like to count, e.g." + echo "op_start ... --ctr0-event=CPU_CLK_UNHALTED --ctr0-count=600000" + echo "Enter op_start --help for full options" + exit 1 fi - f=$(($f+1)) -done - -# stop any existing daemon + if [ "$LOG_FILE" = "" ]; then + LOG_FILE="$DIR/oprofiled.log" + fi + if [ "$SAMPLES_DIR" = "" ]; then + SAMPLES_DIR="$DIR/samples/" + fi + if [ "$DEVICE_FILE" = "" ]; then + DEVICE_FILE="$DIR/opdev" + fi + if [ "$HASH_MAP_DEVICE_FILE" = "" ]; then + HASH_MAP_DEVICE_FILE="$DIR/ophashmapdev" + fi -op_stop >/dev/null + vecho "Parameters used:" + vecho "BUF_SIZE $BUF_SIZE" + vecho "HASH_SIZE $HASH_SIZE" + f=0 + while (( $f < $OP_MAX_COUNTERS )); do + vecho "CTR${f}_EVENT ${CTR_EVENT[$f]}" + vecho "CTR${f}_COUNT ${CTR_COUNT[$f]}" + vecho "CTR${f}_UM ${CTR_UM[$f]}" + vecho "CTR${f}_USER ${CTR_USER[$f]}" + vecho "CTR${f}_KERNEL ${CTR_KERNEL[$f]}" + f=$(($f+1)) + done + vecho "CPUTYPE $CPUTYPE" + vecho "IGNORE_MYSELF $IGNORE_MYSELF" + vecho "DIR $DIR" + vecho "LOG_FILE $LOG_FILE" + vecho "SAMPLES_DIR $SAMPLES_DIR" + vecho "DEVICE_FILE $DEVICE_FILE" + vecho "MAP_FILE $MAP_FILE" + vecho "VMLINUX $VMLINUX" -grep oprof /proc/devices >/dev/null -if [ "$?" -ne 0 ]; then - modprobe oprofile expected_cpu_type=$CPUTYPE - if [ "$?" != "0" ] - then - echo "Couldn't load oprofile.o module" + if [ -z "$MAP_FILE" ]; then + echo "No map file specified. You must specify the correct System.map and vmlinux files, e.g." + echo "op_start --map-file=/path/to/System.map --vmlinux=/path/to/vmlinux" + echo "Enter op_start --help for full options" exit 1 fi - grep oprofile /proc/modules >/dev/null - if [ "$?" != "0" ] - then - echo "Couldn't load oprofile.o module" + + if [ -z "$VMLINUX" ]; then + echo "No vmlinux file specified. You must specify the correct System.map and vmlinux files, e.g." + echo "op_start --map-file=/path/to/System.map --vmlinux=/path/to/vmlinux" + echo "Enter op_start --help for full options" exit 1 fi -fi -if [ ! -d "$DIR" ]; then - mkdir -p "$DIR" - if [ "$?" != "0" ] - then - echo "Couldn't mkdir -p $DIR" - exit 1 - fi - chmod 755 "$DIR" -fi + if [ ! -f "$MAP_FILE" ]; then + echo "The specified map file \"$MAP_FILE\" doesn't exist." + exit 1 + fi -if [ "$LOG_FILE" = "" ]; then - LOG_FILE="$DIR/oprofiled.log" -fi -if [ "$SAMPLES_DIR" = "" ]; then - SAMPLES_DIR="$DIR/samples/" -fi -if [ "$DEVICE_FILE" = "" ]; then - DEVICE_FILE="$DIR/opdev" -fi -if [ "$HASH_MAP_DEVICE_FILE" = "" ]; then - HASH_MAP_DEVICE_FILE="$DIR/ophashmapdev" -fi + if [ ! -f "$VMLINUX" ]; then + echo "The specified vmlinux file \"$VMLINUX\" doesn't exist." + exit 1 + fi +} -if [ "$VERBOSE" = "1" ]; then - echo "Parameters used:" - echo "BUF_SIZE $BUF_SIZE" - echo "HASH_SIZE $HASH_SIZE" - f=0 - while (( $f < $OP_MAX_COUNTERS )); do - echo "CTR${f}_EVENT ${CTR_EVENT[$f]}" - echo "CTR${f}_COUNT ${CTR_COUNT[$f]}" - echo "CTR${f}_UM ${CTR_UM[$f]}" - echo "CTR${f}_USER ${CTR_USER[$f]}" - echo "CTR${f}_KERNEL ${CTR_KERNEL[$f]}" - f=$(($f+1)) - done - echo "CPUTYPE $CPUTYPE" - echo "IGNORE_MYSELF $IGNORE_MYSELF" - echo "DIR $DIR" - echo "LOG_FILE $LOG_FILE" - echo "SAMPLES_DIR $SAMPLES_DIR" - echo "DEVICE_FILE $DEVICE_FILE" - echo "MAP_FILE $MAP_FILE" - echo "VMLINUX $VMLINUX" -fi +# stop any existing daemon +do_stop() { + op_stop +} ->$LOG_FILE +# setup and start module +do_setup() { + grep oprof /proc/devices >/dev/null + if [ "$?" -ne 0 ]; then + modprobe oprofile expected_cpu_type=$CPUTYPE + if [ "$?" != "0" ]; then + echo "Couldn't load oprofile.o module" + exit 1 + fi + grep oprofile /proc/modules >/dev/null + if [ "$?" != "0" ]; then + echo "Couldn't load oprofile.o module" + exit 1 + fi + fi -if [ -z "$MAP_FILE" ]; then - echo "No map file specified. You must specify the correct System.map and vmlinux files, e.g." - echo "op_start --map-file=/path/to/System.map --vmlinux=/path/to/vmlinux" - echo "Enter op_start --help for full options" - exit 1 -fi + if [ ! -d "$DIR" ]; then + mkdir -p "$DIR" + if [ "$?" != "0" ]; then + echo "Couldn't mkdir -p $DIR" + exit 1 + fi + chmod 755 "$DIR" + fi -if [ -z "$VMLINUX" ]; then - echo "No vmlinux file specified. You must specify the correct System.map and vmlinux files, e.g." - echo "op_start --map-file=/path/to/System.map --vmlinux=/path/to/vmlinux" - echo "Enter op_start --help for full options" - exit 1 -fi + >$LOG_FILE -if [ ! -f "$MAP_FILE" ]; then - echo "The specified map file \"$MAP_FILE\" doesn't exist." - exit 1 -fi + if [ -c "$DEVICE_FILE" ]; then + vecho "Removing $DEVICE_FILE" + rm "$DEVICE_FILE" + fi -if [ ! -f "$VMLINUX" ]; then - echo "The specified vmlinux file \"$VMLINUX\" doesn't exist." - exit 1 -fi + if [ -c "$HASH_MAP_DEVICE_FILE" ]; then + vecho "Removing $HASH_MAP_DEVICE_FILE" + rm "$HASH_MAP_DEVICE_FILE" + fi -if [ -c "$DEVICE_FILE" ]; then - if [ "$VERBOSE" = "1" ]; then - echo "Removing $DEVICE_FILE" - fi - rm "$DEVICE_FILE" -fi + if [ ! -d "$SAMPLES_DIR" ]; then + mkdir -p "$SAMPLES_DIR" + if [ "$?" != "0" ]; then + echo "Couldn't mkdir -p $SAMPLES_DIR" + exit 1 + fi + chmod 755 "$SAMPLES_DIR" + fi -if [ -c "$HASH_MAP_DEVICE_FILE" ]; then - if [ "$VERBOSE" = "1" ]; then - echo "Removing $HASH_MAP_DEVICE_FILE" - fi - rm "$HASH_MAP_DEVICE_FILE" -fi + MAJOR_NR=`grep oprof /proc/devices | awk '{print $1}'` -if [ ! -d "$SAMPLES_DIR" ]; then - mkdir -p "$SAMPLES_DIR" - if [ "$?" != "0" ] - then - echo "Couldn't mkdir -p $SAMPLES_DIR" + vecho "Doing mknod $DEVICE_FILE" + mknod "$DEVICE_FILE" c $MAJOR_NR 0 + if [ "$?" != "0" ]; then + echo "Couldn't mknod $DEVICE_FILE" exit 1 fi - chmod 755 "$SAMPLES_DIR" -fi - -MAJOR_NR=`grep oprof /proc/devices | awk '{print $1}'` - -if [ "$VERBOSE" = "1" ]; then -echo "Doing mknod $DEVICE_FILE" -fi -mknod "$DEVICE_FILE" c $MAJOR_NR 0 -if [ "$?" != "0" ] -then - echo "Couldn't mknod $DEVICE_FILE" - exit 1 -fi -chmod 700 "$DEVICE_FILE" + chmod 700 "$DEVICE_FILE" + + vecho "Doing mknod $HASH_MAP_DEVICE_FILE" + mknod "$HASH_MAP_DEVICE_FILE" c $MAJOR_NR 1 + if [ "$?" != "0" ]; then + echo "Couldn't mknod $HASH_MAP_DEVICE_FILE" + exit 1 + fi + chmod 700 "$HASH_MAP_DEVICE_FILE" +} -if [ "$VERBOSE" = "1" ]; then -echo "Doing mknod $HASH_MAP_DEVICE_FILE" -fi -mknod "$HASH_MAP_DEVICE_FILE" c $MAJOR_NR 1 -if [ "$?" != "0" ] -then - echo "Couldn't mknod $HASH_MAP_DEVICE_FILE" - exit 1 -fi -chmod 700 "$HASH_MAP_DEVICE_FILE" +# initialise sysctl parameters +do_sysctl_setup() { + # Necessary in this case : + # op_start ctr0-on ctr1-on then op_start ctr0-on + f=0 + while (( $f < $OP_MAX_COUNTERS )); do + $SYSCTL -w dev.oprofile.$f.enabled=0 >/dev/null + $SYSCTL -w dev.oprofile.$f.event=0 >/dev/null + f=$(($f+1)) + done -# Necessary in this case : -# op_start ctr0-on ctr1-on then op_start ctr0-on -f=0 -while (( $f < $OP_MAX_COUNTERS )); do - $SYSCTL -w dev.oprofile.$f.enabled=0 >/dev/null - $SYSCTL -w dev.oprofile.$f.event=0 >/dev/null - f=$(($f+1)) -done + $SYSCTL -w dev.oprofile.hashsize=$HASH_SIZE + $SYSCTL -w dev.oprofile.bufsize=$BUF_SIZE + $SYSCTL -w dev.oprofile.kernel_only=$KERNEL_ONLY + $SYSCTL -w dev.oprofile.pid_filter=$PID_FILTER + $SYSCTL -w dev.oprofile.pgrp_filter=$PGRP_FILTER -$SYSCTL -w dev.oprofile.hashsize=$HASH_SIZE -$SYSCTL -w dev.oprofile.bufsize=$BUF_SIZE -$SYSCTL -w dev.oprofile.kernel_only=$KERNEL_ONLY -$SYSCTL -w dev.oprofile.pid_filter=$PID_FILTER -$SYSCTL -w dev.oprofile.pgrp_filter=$PGRP_FILTER + f=0 + while (( $f < $OP_MAX_COUNTERS )); do + if [ "${CTR_EVENT[$f]}" != "" ]; then + $SYSCTL -w dev.oprofile.$f.enabled=1 + $SYSCTL -w dev.oprofile.$f.count=${CTR_COUNT[$f]} + $SYSCTL -w dev.oprofile.$f.kernel=${CTR_KERNEL[$f]} + $SYSCTL -w dev.oprofile.$f.user=${CTR_USER[$f]} + $SYSCTL -w dev.oprofile.$f.unit_mask=${CTR_UM[$f]} + $SYSCTL -w dev.oprofile.$f.event=${CTR_EVENT_VAL[$f]} + fi + f=$(($f+1)) + done +} + +# start the daemon +do_start() { + OPD_ARGS="--buffer-size=$BUF_SIZE --ignore-myself=$IGNORE_MYSELF \ + --log-file=$LOG_FILE --base-dir=$DIR --samples-dir=$SAMPLES_DIR \ + --device-file=$DEVICE_FILE --kernel-only=$KERNEL_ONLY \ + --hash-map-device-file=$HASH_MAP_DEVICE_FILE --vmlinux=$VMLINUX \ + --map-file=$MAP_FILE" -f=0 -while (( $f < $OP_MAX_COUNTERS )); do - if [ "${CTR_EVENT[$f]}" != "" ]; then - $SYSCTL -w dev.oprofile.$f.enabled=1 - $SYSCTL -w dev.oprofile.$f.count=${CTR_COUNT[$f]} - $SYSCTL -w dev.oprofile.$f.kernel=${CTR_KERNEL[$f]} - $SYSCTL -w dev.oprofile.$f.user=${CTR_USER[$f]} - $SYSCTL -w dev.oprofile.$f.unit_mask=${CTR_UM[$f]} - $SYSCTL -w dev.oprofile.$f.event=${CTR_EVENT_VAL[$f]} + if [ "$VERBOSE" = "1" ]; then + OPD_ARGS="$OPD_ARGS --verbose" fi - f=$(($f+1)) -done - -OPD_ARGS="--buffer-size=$BUF_SIZE --ignore-myself=$IGNORE_MYSELF \ - --log-file=$LOG_FILE --base-dir=$DIR --samples-dir=$SAMPLES_DIR \ - --device-file=$DEVICE_FILE --kernel-only=$KERNEL_ONLY \ - --hash-map-device-file=$HASH_MAP_DEVICE_FILE --vmlinux=$VMLINUX" -if [ "$MAP_FILE" != "" ]; then - OPD_ARGS="$OPD_ARGS --map-file=$MAP_FILE" -fi + cpu_speed=`grep "cpu MHz" /proc/cpuinfo | tail -1 | awk -F": " '{print $2}'` + OPD_ARGS="$OPD_ARGS --cpu-speed=$cpu_speed" -if [ "$VERBOSE" = "1" ]; then - OPD_ARGS="$OPD_ARGS --verbose" -fi + vecho "cpu speed (estimation) : $cpu_speed" -cpu_speed=`grep "cpu MHz" /proc/cpuinfo | tail -1 | awk -F": " '{print $2}'` -OPD_ARGS="$OPD_ARGS --cpu-speed=$cpu_speed" + oprofiled $OPD_ARGS + sleep 4 + PID=`ps x | grep oprofiled | grep -v grep | awk '{print $1}'` + if [ "$PID" = "" ]; then + echo "Couldn't start oprofiled." + echo "Check the log file \"$LOG_FILE\" and /var/log/messages" + exit 1 + fi -if [ "$VERBOSE" = "1" ]; then - echo "cpu speed (estimation) : $cpu_speed" -fi + echo "Daemon started. Remember you may need to use op_dump" + echo "to retrieve profile data" +} + +# main -oprofiled $OPD_ARGS -sleep 4 -PID=`ps x | grep oprofiled | grep -v grep | awk '{print $1}'` -if [ "$PID" = "" ] -then - echo "Couldn't start oprofiled." - echo "Check the log file \"$LOG_FILE\" and /var/log/messages" +if [ "$UID" != "0" ]; then + echo "Must be root to start oprofile." exit 1 fi - -echo "Daemon started. Remember you may need to use" -echo "op_dump" -echo "to get or flush profiling data ..." + +do_init +do_options $@ +do_stop +do_setup +do_sysctl_setup +do_start Index: op_stop =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_stop,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- op_stop 2001/06/24 23:52:47 1.7 +++ op_stop 2001/09/12 17:10:50 1.8 @@ -16,9 +16,9 @@ # Place - Suite 330, Boston, MA 02111-1307, USA. # -echo "Stopping profiling and killing daemon" PID=`ps x | grep oprofiled | grep -v grep | awk '{print $1}'` if [ "$PID" != "" ] then + echo "Stopping profiling and killing daemon" kill $PID fi |
From: John L. <mov...@us...> - 2001-09-12 17:10:54
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv29164/pp Modified Files: oprofpp.c Log Message: code tidies Index: oprofpp.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp.c,v retrieving revision 1.39 retrieving revision 1.40 diff -u -d -r1.39 -r1.40 --- oprofpp.c 2001/09/08 21:46:04 1.39 +++ oprofpp.c 2001/09/12 17:10:51 1.40 @@ -1133,7 +1133,7 @@ if (footer[i]->cpu_type == CPU_ATHLON) op_nr_counters = 4; - printf("Cpu type: %d\n", footer[i]->cpu_type); + printf("Cpu type: %s\n", op_get_cpu_type_str(footer[i]->cpu_type)); printf("Cpu speed was (MHz estimation) : %f\n", footer[i]->cpu_speed); |
From: John L. <mov...@us...> - 2001-09-12 14:30:23
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv15522 Modified Files: ChangeLog oprofile.c Log Message: fix race leading to oops ! Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.107 retrieving revision 1.108 diff -u -d -r1.107 -r1.108 --- ChangeLog 2001/09/12 05:21:57 1.107 +++ ChangeLog 2001/09/12 14:30:20 1.108 @@ -1,5 +1,10 @@ 2001-09-12 John Levon <mo...@co...> + * oprofile.c: fix small but triggerable + SMP dump race + +2001-09-12 John Levon <mo...@co...> + * oprofile.h: * oprofile.c: * op_x86.c: move some code about Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.86 retrieving revision 1.87 diff -u -d -r1.86 -r1.87 --- oprofile.c 2001/09/12 05:21:57 1.86 +++ oprofile.c 2001/09/12 14:30:20 1.87 @@ -721,12 +721,13 @@ static int oprof_stop(void) { uint i; - - if (!prof_on) - return -EINVAL; + int err = -EINVAL; down(&sysctlsem); + if (!prof_on) + goto out; + /* here we need to : * bring back the old system calls * stop the wake-up thread @@ -760,9 +761,11 @@ spin_unlock(¬e_lock); spin_unlock(&map_lock); + err = 0; +out: up(&sysctlsem); - return 0; + return err; } static struct file_operations oprof_fops = { @@ -831,11 +834,11 @@ int err = -EINVAL; int i,j; - if (!prof_on) - return err; - down(&sysctlsem); + if (!prof_on) + goto out; + for (cpu=0; cpu < smp_num_cpus; cpu++) printk("oprofile: CPU%u: %u interrupts\n", cpu, op_irq_stats[cpu]); @@ -844,8 +847,6 @@ goto out; } - err = 0; - /* clean out the hash table as far as possible */ for (cpu=0; cpu < smp_num_cpus; cpu++) { struct _oprof_data * data = &oprof_data[cpu]; @@ -860,7 +861,7 @@ pmc_select_start(cpu); } wake_up(&oprof_wait); - + err = 0; out: up(&sysctlsem); return err; |
From: John L. <mov...@us...> - 2001-09-12 05:22:02
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv25642 Modified Files: ChangeLog op_syscalls.c op_user.h op_x86.c oprofile.c oprofile.h Log Message: move some code, remove some stale comments Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.106 retrieving revision 1.107 diff -u -d -r1.106 -r1.107 --- ChangeLog 2001/09/12 02:54:30 1.106 +++ ChangeLog 2001/09/12 05:21:57 1.107 @@ -1,5 +1,13 @@ 2001-09-12 John Levon <mo...@co...> + * oprofile.h: + * oprofile.c: + * op_x86.c: move some code about + + * op_syscalls.c: add comment + +2001-09-12 John Levon <mo...@co...> + * configure.in: remove warning * op_user.h: Index: op_syscalls.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_syscalls.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- op_syscalls.c 2001/08/14 18:02:33 1.16 +++ op_syscalls.c 2001/09/12 05:21:57 1.17 @@ -604,6 +604,10 @@ goto out; out: + /* this looks UP-dangerous, as the exit sleeps and we don't + * have a use count, but in fact its ok as sys_exit is noreturn, + * so we can never come back to this non-existent exec page + */ MOD_DEC_USE_COUNT; return old_sys_exit(error_code); } Index: op_user.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_user.h,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- op_user.h 2001/09/12 02:54:30 1.7 +++ op_user.h 2001/09/12 05:21:57 1.8 @@ -70,12 +70,9 @@ /* kernel image entries are offset by this many entries */ #define OPD_KERNEL_OFFSET 524288 -/* FIXME ATHLON: four next #define can be tuned for full support to Athlon */ -/* PHE: I don't fix the problem "is these should be autoconf and/or runtime - * settings" so hack it at hand for now */ /* maximum nr. of counters, up to 4 for Athlon (18 for P4). The primary use * of this variable is for static/local array dimension. Never use it in loop - * or in array index acccess/index checking. Don't change it without updating + * or in array index access/index checking. Don't change it without updating * OP_BITS_CTR! */ #define OP_MAX_COUNTERS 4 Index: op_x86.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_x86.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- op_x86.c 2001/08/31 17:16:35 1.1 +++ op_x86.c 2001/09/12 05:21:57 1.2 @@ -14,6 +14,255 @@ #include <asm/mpspec.h> #include <asm/io.h> +#include "oprofile.h" + +/* ---------------- NMI handler setup ------------ */ + +static ulong idt_addr; +static ulong kernel_nmi; +static ulong lvtpc_masked; + +/* this masking code is unsafe and nasty but might deal with the small + * race when installing the NMI entry into the IDT + */ +static void mask_lvtpc(void * e) +{ + ulong v = apic_read(APIC_LVTPC); + lvtpc_masked = v & APIC_LVT_MASKED; + apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); +} + +static void unmask_lvtpc(void * e) +{ + if (!lvtpc_masked) + apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); +} + +void install_nmi(void) +{ + volatile struct _descr descr = { 0, 0,}; + volatile struct _idt_descr *de; + + store_idt(descr); + idt_addr = descr.base; + de = (struct _idt_descr *)idt_addr; + /* NMI handler is at idt_table[2] */ + de += 2; + /* see Intel Vol.3 Figure 5-2, interrupt gate */ + kernel_nmi = (de->a & 0xffff) | (de->b & 0xffff0000); + + smp_call_function(mask_lvtpc, NULL, 0, 1); + mask_lvtpc(NULL); + _set_gate(de, 14, 0, &op_nmi); + smp_call_function(unmask_lvtpc, NULL, 0, 1); + unmask_lvtpc(NULL); +} + +void restore_nmi(void) +{ + smp_call_function(mask_lvtpc, NULL, 0, 1); + mask_lvtpc(NULL); + _set_gate(((char *)(idt_addr)) + 16, 14, 0, kernel_nmi); + smp_call_function(unmask_lvtpc, NULL, 0, 1); + unmask_lvtpc(NULL); +} + +/* ---------------- APIC setup ------------------ */ + +static int smp_hardware; + +/* PHE : this would be probably an unconditionnaly restore state from a saved + *state + */ +void disable_local_P6_APIC(void *dummy) +{ +#ifndef CONFIG_X86_UP_APIC + ulong v; + uint l; + uint h; + + /* FIXME: maybe this should go at end of function ? */ + /* PHE I think when the doc says : -if you disable the apic the bits + * of LVT cannot be reset- it talk about the SW disable through bit 8 + * of SPIV see 7.4.14 (7.5.14) not the hardware disable, so it is ok + * but perhaps we need a software disable of the APIC at the end + */ + /* first disable via MSR */ + /* IA32 V3, 7.4.2 */ + rdmsr(MSR_IA32_APICBASE, l, h); + wrmsr(MSR_IA32_APICBASE, l & ~(1<<11), h); + + /* + * Careful: we have to set masks only first to deassert + * any level-triggered sources. + */ + v = apic_read(APIC_LVTT); + apic_write(APIC_LVTT, v | APIC_LVT_MASKED); + v = apic_read(APIC_LVT0); + apic_write(APIC_LVT0, v | APIC_LVT_MASKED); + v = apic_read(APIC_LVT1); + apic_write(APIC_LVT1, v | APIC_LVT_MASKED); + v = apic_read(APIC_LVTERR); + apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); + v = apic_read(APIC_LVTPC); + apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); + + /* + * Clean APIC state for other OSs: + */ + apic_write(APIC_LVTT, APIC_LVT_MASKED); + apic_write(APIC_LVT0, APIC_LVT_MASKED); + apic_write(APIC_LVT1, APIC_LVT_MASKED); + apic_write(APIC_LVTERR, APIC_LVT_MASKED); + apic_write(APIC_LVTPC, APIC_LVT_MASKED); + + v = apic_read(APIC_SPIV); + v &= ~APIC_SPIV_APIC_ENABLED; + apic_write(APIC_SPIV, v); + + printk(KERN_INFO "oprofile: disabled local APIC.\n"); +#endif +} + +static uint lvtpc_old_mask[NR_CPUS]; +static uint lvtpc_old_mode[NR_CPUS]; + +void __init lvtpc_apic_setup(void *dummy) +{ + uint val; + + /* set up LVTPC as we need it */ + /* IA32 V3, Figure 7.8 */ + val = apic_read(APIC_LVTPC); + lvtpc_old_mask[op_cpu_id()] = val & APIC_LVT_MASKED; + /* allow PC overflow interrupts */ + val &= ~APIC_LVT_MASKED; + /* set delivery to NMI */ + lvtpc_old_mode[op_cpu_id()] = GET_APIC_DELIVERY_MODE(val); + val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_NMI); + apic_write(APIC_LVTPC, val); +} + +void __exit lvtpc_apic_restore(void *dummy) +{ + uint val = apic_read(APIC_LVTPC); + // FIXME: this gives APIC errors on SMP hardware. + // val = SET_APIC_DELIVERY_MODE(val, lvtpc_old_mode[op_cpu_id()]); + if (lvtpc_old_mask[op_cpu_id()]) + val |= APIC_LVT_MASKED; + else + val &= ~APIC_LVT_MASKED; + apic_write(APIC_LVTPC, val); +} + +static int __init apic_needs_setup(void) +{ + return +/* if enabled, the kernel has already set it up */ +#ifdef CONFIG_X86_UP_APIC + 0 && +#else +/* otherwise, we detect SMP hardware via the MP table */ + !smp_hardware && +#endif + smp_num_cpus == 1; +} + +int __init apic_setup(void) +{ + uint msr_low, msr_high; + uint val; + + if (!apic_needs_setup()) { + printk(KERN_INFO "oprofile: no APIC setup needed.\n"); + lvtpc_apic_setup(NULL); + return 0; + } + + printk(KERN_INFO "oprofile: setting up APIC.\n"); + + /* ugly hack */ + my_set_fixmap(); + + /* enable local APIC via MSR. Forgetting this is a fun way to + * lock the box */ + /* IA32 V3, 7.4.2 */ + rdmsr(MSR_IA32_APICBASE, msr_low, msr_high); + wrmsr(MSR_IA32_APICBASE, msr_low | (1<<11), msr_high); + + /* check for a good APIC */ + /* IA32 V3, 7.4.15 */ + val = apic_read(APIC_LVR); + if (!APIC_INTEGRATED(GET_APIC_VERSION(val))) + goto not_local_p6_apic; + + /* LVT0,LVT1,LVTT,LVTPC */ + if (GET_APIC_MAXLVT(apic_read(APIC_LVR)) != 4) + goto not_local_p6_apic; + + __cli(); + + /* enable APIC locally */ + /* IA32 V3, 7.4.14.1 */ + val = apic_read(APIC_SPIV); + apic_write(APIC_SPIV, val | APIC_SPIV_APIC_ENABLED); + + /* FIXME: the below code should be ruthlessly trimmed ! used on UP only */ + + val = APIC_LVT_LEVEL_TRIGGER; + val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_EXINT); + apic_write(APIC_LVT0, val); + + /* edge triggered, IA 7.4.11 */ + val = SET_APIC_DELIVERY_MODE(0, APIC_MODE_NMI); + apic_write(APIC_LVT1, val); + + /* clear error register */ + /* IA32 V3, 7.4.17 */ + /* PHE must be cleared after unmasking by a back-to-back write, + * but it is probably ok because we mask only, the ESR is not updated + * is this a real problem ? + */ + apic_write(APIC_ESR, 0); + + /* mask error interrupt */ + /* IA32 V3, Figure 7.8 */ + val = apic_read(APIC_LVTERR); + val |= APIC_LVT_MASKED; + apic_write(APIC_LVTERR, val); + + /* setup timer vector */ + /* IA32 V3, 7.4.8 */ + /* PHE actually it is ok but kernel change can hang up the machine + * after this point. + */ + apic_write(APIC_LVTT, APIC_SEND_PENDING | 0x31); + + /* Divide configuration register */ + /* PHE the apic clock is based on the FSB. This should only changed + * with a calibration method. + */ + val = APIC_TDR_DIV_1; + apic_write(APIC_TDCR, val); + + __sti(); + + lvtpc_apic_setup(NULL); + + printk(KERN_INFO "oprofile: enabled local APIC\n"); + + return 0; + +not_local_p6_apic: + printk(KERN_ERR "oprofile: no local P6 APIC. Your laptop doesn't have one !\n"); + /* IA32 V3, 7.4.2 */ + rdmsr(MSR_IA32_APICBASE, msr_low, msr_high); + wrmsr(MSR_IA32_APICBASE, msr_low & ~(1<<11), msr_high); + return -ENODEV; +} + +/* ---------------- MP table code ------------------ */ + static int __init mpf_checksum(unsigned char *mp, int len) { int sum = 0; @@ -51,7 +300,7 @@ return 0; } -int __init find_intel_smp (void) +void __init find_intel_smp (void) { unsigned int address; @@ -65,8 +314,10 @@ */ if (smp_scan_config(0x0,0x400) || smp_scan_config(639*0x400,0x400) || - smp_scan_config(0xF0000,0x10000)) - return 1; + smp_scan_config(0xF0000,0x10000)) { + smp_hardware = 1; + return; + } /* * If it is an SMP machine we should know now, unless the * configuration is in an EISA/MCA bus machine with an @@ -84,5 +335,5 @@ address = *(unsigned short *)phys_to_virt(0x40E); address <<= 4; - return smp_scan_config(address, 0x1000); + smp_hardware = smp_scan_config(address, 0x1000); } Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.85 retrieving revision 1.86 diff -u -d -r1.85 -r1.86 --- oprofile.c 2001/09/12 02:54:30 1.85 +++ oprofile.c 2001/09/12 05:21:57 1.86 @@ -57,7 +57,6 @@ static u32 prof_on __cacheline_aligned; -static int smp_hardware; static int op_major; int cpu_type; @@ -145,271 +144,6 @@ } } -/* ---------------- NMI handler setup ------------ */ - -static ulong idt_addr; -static ulong kernel_nmi; -static ulong lvtpc_masked; - -/* this masking code is unsafe and nasty but might deal with the small - * race when installing the NMI entry into the IDT - */ -static void mask_lvtpc(void * e) -{ - ulong v = apic_read(APIC_LVTPC); - lvtpc_masked = v & APIC_LVT_MASKED; - apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); -} - -static void unmask_lvtpc(void * e) -{ - if (!lvtpc_masked) - apic_write(APIC_LVTPC, apic_read(APIC_LVTPC) & ~APIC_LVT_MASKED); -} - -static void install_nmi(void) -{ - volatile struct _descr descr = { 0, 0,}; - volatile struct _idt_descr *de; - - store_idt(descr); - idt_addr = descr.base; - de = (struct _idt_descr *)idt_addr; - /* NMI handler is at idt_table[2] */ - de += 2; - /* see Intel Vol.3 Figure 5-2, interrupt gate */ - kernel_nmi = (de->a & 0xffff) | (de->b & 0xffff0000); - - smp_call_function(mask_lvtpc, NULL, 0, 1); - mask_lvtpc(NULL); - _set_gate(de, 14, 0, &op_nmi); - smp_call_function(unmask_lvtpc, NULL, 0, 1); - unmask_lvtpc(NULL); -} - -static void restore_nmi(void) -{ - smp_call_function(mask_lvtpc, NULL, 0, 1); - mask_lvtpc(NULL); - _set_gate(((char *)(idt_addr)) + 16, 14, 0, kernel_nmi); - smp_call_function(unmask_lvtpc, NULL, 0, 1); - unmask_lvtpc(NULL); -} - -/* ---------------- APIC setup ------------------ */ - -/* PHE : this would be probably an unconditionnaly restore state from a saved - *state - */ -static void disable_local_P6_APIC(void *dummy) -{ -#ifndef CONFIG_X86_UP_APIC - ulong v; - uint l; - uint h; - - /* FIXME: maybe this should go at end of function ? */ - /* PHE I think when the doc says : -if you disable the apic the bits - * of LVT cannot be reset- it talk about the SW disable through bit 8 - * of SPIV see 7.4.14 (7.5.14) not the hardware disable, so it is ok - * but perhaps we need a software disable of the APIC at the end - */ - /* first disable via MSR */ - /* IA32 V3, 7.4.2 */ - rdmsr(MSR_IA32_APICBASE, l, h); - wrmsr(MSR_IA32_APICBASE, l & ~(1<<11), h); - - /* - * Careful: we have to set masks only first to deassert - * any level-triggered sources. - */ - v = apic_read(APIC_LVTT); - apic_write(APIC_LVTT, v | APIC_LVT_MASKED); - v = apic_read(APIC_LVT0); - apic_write(APIC_LVT0, v | APIC_LVT_MASKED); - v = apic_read(APIC_LVT1); - apic_write(APIC_LVT1, v | APIC_LVT_MASKED); - v = apic_read(APIC_LVTERR); - apic_write(APIC_LVTERR, v | APIC_LVT_MASKED); - v = apic_read(APIC_LVTPC); - apic_write(APIC_LVTPC, v | APIC_LVT_MASKED); - - /* - * Clean APIC state for other OSs: - */ - apic_write(APIC_LVTT, APIC_LVT_MASKED); - apic_write(APIC_LVT0, APIC_LVT_MASKED); - apic_write(APIC_LVT1, APIC_LVT_MASKED); - apic_write(APIC_LVTERR, APIC_LVT_MASKED); - apic_write(APIC_LVTPC, APIC_LVT_MASKED); - - v = apic_read(APIC_SPIV); - v &= ~APIC_SPIV_APIC_ENABLED; - apic_write(APIC_SPIV, v); - - printk(KERN_INFO "oprofile: disabled local APIC.\n"); -#endif -} - -static uint lvtpc_old_mask[NR_CPUS]; -static uint lvtpc_old_mode[NR_CPUS]; - -static void __init lvtpc_apic_setup(void *dummy) -{ - uint val; - - /* set up LVTPC as we need it */ - /* IA32 V3, Figure 7.8 */ - val = apic_read(APIC_LVTPC); - lvtpc_old_mask[op_cpu_id()] = val & APIC_LVT_MASKED; - /* allow PC overflow interrupts */ - val &= ~APIC_LVT_MASKED; - /* set delivery to NMI */ - lvtpc_old_mode[op_cpu_id()] = GET_APIC_DELIVERY_MODE(val); - val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_NMI); - apic_write(APIC_LVTPC, val); -} - -static void __exit lvtpc_apic_restore(void *dummy) -{ - uint val = apic_read(APIC_LVTPC); - // FIXME: this gives APIC errors on SMP hardware. - // val = SET_APIC_DELIVERY_MODE(val, lvtpc_old_mode[op_cpu_id()]); - if (lvtpc_old_mask[op_cpu_id()]) - val |= APIC_LVT_MASKED; - else - val &= ~APIC_LVT_MASKED; - apic_write(APIC_LVTPC, val); -} - -static int __init apic_needs_setup(void) -{ - return -/* if enabled, the kernel has already set it up */ -#ifdef CONFIG_X86_UP_APIC - 0 && -#else -/* otherwise, we detect SMP hardware via the MP table */ - !smp_hardware && -#endif - smp_num_cpus == 1; -} - -/* PHE, would : save all state change for later restoration, minimalise the - * amount of change. Basically we need to test if apic is HW disable, SW - * disable, and change only the LVTPC setup, all other must be keep as it - * (except the LINT1 for bsp ?) We must rely on the kernel to setup all things. - * also : do we need write_apic --> write_apic_around to support - * GOOD_APIC/BAD_APIC ? - */ -static int __init apic_setup(void) -{ - uint msr_low, msr_high; - uint val; - - if (!apic_needs_setup()) { - printk(KERN_INFO "oprofile: no APIC setup needed.\n"); - lvtpc_apic_setup(NULL); - return 0; - } - - printk(KERN_INFO "oprofile: setting up APIC.\n"); - - /* ugly hack */ - my_set_fixmap(); - - /* enable local APIC via MSR. Forgetting this is a fun way to - lock the box */ - /* IA32 V3, 7.4.2 */ - rdmsr(MSR_IA32_APICBASE, msr_low, msr_high); - wrmsr(MSR_IA32_APICBASE, msr_low | (1<<11), msr_high); - - /* check for a good APIC */ - /* IA32 V3, 7.4.15 */ - val = apic_read(APIC_LVR); - if (!APIC_INTEGRATED(GET_APIC_VERSION(val))) - goto not_local_p6_apic; - - /* LVT0,LVT1,LVTT,LVTPC */ - if (GET_APIC_MAXLVT(apic_read(APIC_LVR)) != 4) - goto not_local_p6_apic; - - /* __global_cli(); ? an IPI can occur inside this stuff ? */ - __cli(); - - /* enable APIC locally */ - /* IA32 V3, 7.4.14.1 */ - val = apic_read(APIC_SPIV); - apic_write(APIC_SPIV, val | APIC_SPIV_APIC_ENABLED); - - /* FIXME: examine this stuff */ - val = APIC_LVT_LEVEL_TRIGGER; - val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_EXINT); - apic_write(APIC_LVT0, val); - - /* edge triggered, IA 7.4.11 */ - /* PHE SMP: only the BSP must see the LINT1 IRQ (from kernel source) - * recheck this later - */ - val = SET_APIC_DELIVERY_MODE(0, APIC_MODE_NMI); - apic_write(APIC_LVT1, val); - - /* clear error register */ - /* IA32 V3, 7.4.17 */ - /* PHE must be cleared after unmasking by a back-to-back write, - * but it is probably ok because we mask only, the ESR is not updated - * is this a real problem ? - */ - apic_write(APIC_ESR, 0); - - /* mask error interrupt */ - /* IA32 V3, Figure 7.8 */ - val = apic_read(APIC_LVTERR); - val |= APIC_LVT_MASKED; - apic_write(APIC_LVTERR, val); - - /* setup timer vector */ - /* IA32 V3, 7.4.8 */ - /* PHE actually it is ok but kernel change can hang up the machine - * after this point. - */ - apic_write(APIC_LVTT, APIC_SEND_PENDING | 0x31); - - /* Divide configuration register */ - /* PHE the apic clock is based on the FSB. This should only changed - * with a calibration method. - */ - val = APIC_TDR_DIV_1; - apic_write(APIC_TDCR, val); - - - /* PHE __global_sti() probably */ - __sti(); - - /* If the local APIC NMI watchdog has been disabled, we'll need - * to set up NMI delivery anyway ... - */ - /* PHE : ? why not use a FixedMode rather than NMI mode for profiling, - * this avoid all problem with parity error nmi and watchdog, but this - * implies than the actual nmi handler must be hardware interruptible, - * basically this is better at my eyes but there is a few visible - * (and hidden) problem with this issue. This can probably wait unless - * hidden problem occur on SMP, recheck doc about NMI - */ - lvtpc_apic_setup(NULL); - - printk(KERN_INFO "oprofile: enabled local APIC\n"); - - return 0; - -not_local_p6_apic: - printk(KERN_ERR "oprofile: no local P6 APIC. Your laptop doesn't have one !\n"); - /* IA32 V3, 7.4.2 */ - rdmsr(MSR_IA32_APICBASE, msr_low, msr_high); - wrmsr(MSR_IA32_APICBASE, msr_low & ~(1<<11), msr_high); - return -ENODEV; -} - /* ---------------- PMC setup ------------------ */ static void pmc_fill_in(uint *val, u8 kernel, u8 user, u8 event, u8 um) @@ -453,10 +187,6 @@ break; } - /* FIXME ATHLON: use #if 0 to get the old code, which would work on - * athlon. The new code would work but I had get a painfull debug so - * I prefer to keep the old code until Athlon tests are available. */ -#if 1 /* IA Vol. 3 Figure 15-3 */ /* Stop and clear all counter: IA32 use bit 22 of eventsel_msr0 to @@ -479,7 +209,7 @@ set_perfctr(op_ctr_count[i], i); pmc_fill_in(&low, op_ctr_kernel[i], op_ctr_user[i], - op_ctr_val[i], op_ctr_um[i]); + op_ctr_val[i], op_ctr_um[i]); wrmsr(eventsel_msr[i], low, high); } @@ -488,33 +218,6 @@ /* Here all setup is made except the start/stop bit 21), counter * disabled contains zeros in the eventsel msr except the reserved bit * 21 */ -#else - rdmsr(eventsel_msr[0], low, high); - // FIXME: enable bit is per-counter on athlon - wrmsr(eventsel_msr[0], low & ~(1<<22), high); - /* clear */ - low &= (1<<21); - - /* IA Vol. 3 Figure 15-3 */ - - if (op_ctr_val[0]) { - set_perfctr(op_ctr_count[0], 0); - pmc_fill_in(&low, op_ctr_kernel[0], op_ctr_user[0], op_ctr_val[0], op_ctr_um[0]); - } - - wrmsr(eventsel_msr[0], low, 0); - - rdmsr(eventsel_msr[1], low, high); - /* clear */ - low &= (3<<21); - - if (op_ctr_val[1]) { - set_perfctr(op_ctr_count[1], 1); - pmc_fill_in(&low, op_ctr_kernel[1], op_ctr_user[1], op_ctr_val[1], op_ctr_um[1]); - - wrmsr(eventsel_msr[1], low, high); - } -#endif } inline static void pmc_start_P6(void) @@ -605,8 +308,8 @@ /* ---------------- driver routines ------------------ */ -u32 diethreaddie; -pid_t threadpid; +static u32 diethreaddie; +static pid_t threadpid; DECLARE_COMPLETION(threadstop); @@ -617,7 +320,6 @@ { int i; - // FIXME: kernel lock ? daemonize(); sprintf(current->comm, "oprof-thread"); siginitsetinv(¤t->blocked, sigmask(SIGKILL)); @@ -636,7 +338,6 @@ /* FIXME: determine best value here */ schedule_timeout(HZ/10); - // FIXME: signal pending if (diethreaddie) break; } @@ -649,8 +350,11 @@ { init_completion(&threadstop); diethreaddie = 0; - if ((threadpid = kernel_thread(oprof_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND)) < 0) + threadpid = kernel_thread(oprof_thread, NULL, CLONE_FS|CLONE_FILES|CLONE_SIGHAND); + if (threadpid < 0) { printk(KERN_ERR "oprofile: couldn't spawn wakeup thread.\n"); + threadpid = 0; + } } static void oprof_stop_thread(void) @@ -903,19 +607,24 @@ struct _oprof_data *data; int enabled = 0; - op_check_range(op_hash_size, 256, 262144, "op_hash_size value %d not in range (%d %d)\n"); - op_check_range(op_buf_size, 1024, 1048576, "op_buf_size value %d not in range (%d %d)\n"); + op_check_range(op_hash_size, 256, 262144, + "op_hash_size value %d not in range (%d %d)\n"); + op_check_range(op_buf_size, 1024, 1048576, + "op_buf_size value %d not in range (%d %d)\n"); for (i = 0; i < op_nr_counters ; i++) { if (op_ctr_on[i]) { int min_count = op_min_count(op_ctr_val[i], cpu_type); if (!op_ctr_user[i] && !op_ctr_kernel[i]) { - printk(KERN_ERR "oprofile: neither kernel nor user set for counter %d\n", i); + printk(KERN_ERR "oprofile: neither kernel nor user " + "set for counter %d\n", i); return 0; } - op_check_range(op_ctr_count[i], min_count, OP_MAX_PERF_COUNT, "ctr count value %d not in range (%d %ld)\n"); - + op_check_range(op_ctr_count[i], min_count, + OP_MAX_PERF_COUNT, + "ctr count value %d not in range (%d %ld)\n"); + enabled = 1; } } @@ -931,16 +640,13 @@ ret = op_check_events(i, op_ctr_val[i], op_ctr_um[i], cpu_type); if (ret & OP_EVT_NOT_FOUND) - printk(KERN_ERR "oprofile: ctr%d: %d: no such event for cpu %d\n", - i, op_ctr_val[i], cpu_type); + printk(KERN_ERR "oprofile: ctr%d: %d: no such event for cpu %d\n", i, op_ctr_val[i], cpu_type); if (ret & OP_EVT_NO_UM) - printk(KERN_ERR "oprofile: ctr%d: 0x%.2x: invalid unit mask for cpu %d\n", - i, op_ctr_um[i], cpu_type); + printk(KERN_ERR "oprofile: ctr%d: 0x%.2x: invalid unit mask for cpu %d\n", i, op_ctr_um[i], cpu_type); if (ret & OP_EVT_CTR_NOT_ALLOWED) - printk(KERN_ERR "oprofile: ctr%d: %d: can't count event for this counter\n", - i, op_ctr_val[i]); + printk(KERN_ERR "oprofile: ctr%d: %d: can't count event for this counter\n", i, op_ctr_val[i]); if (ret != OP_EVENTS_OK) ok = 0; @@ -1069,26 +775,26 @@ /* * /proc/sys/dev/oprofile/ - * bufsize - * hashsize - * dump - * kernel_only - * pid_filter - * pgrp_filter - * 0/ - * event - * enabled - * count - * unit_mask - * kernel - * user - * 1/ - * event - * enabled - * count - * unit_mask - * kernel - * user + * bufsize + * hashsize + * dump + * kernel_only + * pid_filter + * pgrp_filter + * 0/ + * event + * enabled + * count + * unit_mask + * kernel + * user + * 1/ + * event + * enabled + * count + * unit_mask + * kernel + * user */ static int lproc_dointvec(ctl_table *table, int write, struct file *filp, void *buffer, size_t *lenp) @@ -1261,8 +967,8 @@ /* FIXME: we should save out the old values for the pmcs, then put them back * upon exit. This way the NMI oopser can work after unloading oprofile */ - - smp_hardware = find_intel_smp(); + + find_intel_smp(); if ((err = apic_setup())) return err; Index: oprofile.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.h,v retrieving revision 1.51 retrieving revision 1.52 diff -u -d -r1.51 -r1.52 --- oprofile.h 2001/09/12 01:22:41 1.51 +++ oprofile.h 2001/09/12 05:21:58 1.52 @@ -210,7 +210,6 @@ extern uint eventsel_msr[OP_MAX_COUNTERS]; int oprof_init(void); -int find_intel_smp(void); void oprof_exit(void); void my_set_fixmap(void); void op_intercept_syscalls(void); @@ -225,3 +224,10 @@ int oprof_map_read(char *buf, size_t count, loff_t *ppos); int oprof_init_hashmap(void); void oprof_free_hashmap(void); +void find_intel_smp(void); +void lvtpc_apic_setup(void *dummy); +void lvtpc_apic_restore(void *dummy); +void install_nmi(void); +void restore_nmi(void); +int apic_setup(void); +void disable_local_P6_APIC(void *dummy); |
From: John L. <mov...@us...> - 2001-09-12 02:54:34
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv32504 Modified Files: ChangeLog configure.in op_events.c op_init.c op_user.h oprofile.c Log Message: cpu type detection fixes, irq stats Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.105 retrieving revision 1.106 diff -u -d -r1.105 -r1.106 --- ChangeLog 2001/09/12 01:22:40 1.105 +++ ChangeLog 2001/09/12 02:54:30 1.106 @@ -1,5 +1,16 @@ 2001-09-12 John Levon <mo...@co...> + * configure.in: remove warning + + * op_user.h: + * op_events.c: fix and clean up cpu type detection + + * op_init.c: fix email + + * oprofile.c: add IRQ stats. Not sure whether to keep... + +2001-09-12 John Levon <mo...@co...> + * oprofile.h: * oprofile.c: use cpu_number_map (pedantry thing) Index: configure.in =================================================================== RCS file: /cvsroot/oprofile/oprofile/configure.in,v retrieving revision 1.29 retrieving revision 1.30 diff -u -d -r1.29 -r1.30 --- configure.in 2001/08/16 02:21:19 1.29 +++ configure.in 2001/09/12 02:54:30 1.30 @@ -113,7 +113,6 @@ AC_MSG_CHECKING(for SMP) AX_COMPILE_OPTION(CONFIG_SMP,smp=1,smp=0) AX_MSG_RESULT_YN($smp) -test "$smp" = 1 && echo "Warning: SMP totally untested !" AC_MSG_CHECKING(for versioned modules) mv=0 Index: op_events.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_events.c,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- op_events.c 2001/09/08 21:46:03 1.23 +++ op_events.c 2001/09/12 02:54:30 1.24 @@ -280,7 +280,7 @@ /** * op_min_count - get the minimum count value. * @ctr_type: event value - * @cpu_type: + * @cpu_type: cpu type * * 0 Pentium Pro * @@ -438,71 +438,71 @@ int cpu_type; }; -/* string must be in the correct order to not hide a forward string eg. - * order "Pentium II" "Pentium III" is bad because the first hide the second */ +/* be careful here, later entries will be override earlier ones */ static struct op_cpu_type op_cpu_types[] = { - { "PentiumPro", CPU_PPRO }, - { "Pentium III",CPU_PIII }, - { "Pentium II", CPU_PII }, - { "Pentium III",CPU_PIII }, - { "Athlon", CPU_ATHLON }, - { "Duron", CPU_ATHLON }, - { "K7", CPU_ATHLON }, - { "Celeron", CPU_PII }, - { "Coppermine", CPU_PIII }, + { "PentiumPro", CPU_PPRO }, + { "Pentium II", CPU_PII }, + { "Pentium III", CPU_PIII }, + { "Celeron", CPU_PII }, + { "Coppermine", CPU_PIII }, + { "Athlon", CPU_ATHLON }, + { "Duron", CPU_ATHLON }, + { "K7", CPU_ATHLON }, }; #define OP_CPU_TYPES_NR (sizeof(op_cpu_types) / sizeof(op_cpu_types[0])) + +static int op_type_from_name(char const * name) +{ + uint i; + int cpu_type = CPU_NO_GOOD; + + for (i = 0; i < OP_CPU_TYPES_NR; i++) { + if (strstr(name, op_cpu_types[i].cpu_name)) + cpu_type = op_cpu_types[i].cpu_type; + } + return cpu_type; +} + +#define MODEL_PREFIX "model name\t: " + /** * op_get_cpu_type - get from /proc/cpuinfo the cpu type * - * return DEFAULT_CPU_TYPE if the cpu type is un-recognizable - * FIXME: return -1 + * returns CPU_NO_GOOD if the CPU could not be identified */ int op_get_cpu_type(void) { - int cpu_type; + int cpu_type = CPU_NO_GOOD; + int cputmp; char line[256]; - char *model_name; FILE* fp; - uint i; - int found = 0; - - cpu_type = DEFAULT_CPU_TYPE; fp = fopen("/proc/cpuinfo", "r"); if (!fp) { fprintf(stderr, "Unable to open /proc/cpuinfo for reading\n"); - return cpu_type; } while (fgets(line, sizeof(line) - 1, fp)) { - if (strncmp(line, "model name\t: ", strlen("model name\t: ")) == 0) { - model_name = line + strlen("model name\t: "); - - for (i = 0; i < OP_CPU_TYPES_NR; i++) { - if (strncmp(model_name, op_cpu_types[i].cpu_name, strlen(op_cpu_types[i].cpu_name)) == 0) { - cpu_type = op_cpu_types[i].cpu_type; - - found = 1; - } - } + if (strncmp(line, MODEL_PREFIX, strlen(MODEL_PREFIX)) == 0) { + cputmp = op_type_from_name(line + strlen(MODEL_PREFIX)); + if (cputmp != CPU_NO_GOOD) + cpu_type = cputmp; } } - if (!found) { - /* FIXME: use oprofile mail list adress here ? */ - fprintf(stderr, "Unknown CPU type. Please send /proc/cpuinfo to mo...@co...\n"); - } + if (cpu_type == CPU_NO_GOOD) + fprintf(stderr, "Unknown CPU type. Please send /proc/cpuinfo to opr...@li...\n"); + fclose(fp); return cpu_type; } #undef OP_CPU_TYPES_NR -#endif +#endif /* !defined(MODULE) */ #ifdef OP_EVENTS_DESC struct op_unit_desc { @@ -756,7 +756,7 @@ #include "version.h" -static int cpu_type = DEFAULT_CPU_TYPE; +static int cpu_type = CPU_NO_GOOD; /** * help_for_event - output event name and description @@ -879,17 +879,15 @@ return 0; } else if (!strcmp(argv[i], "--help")) { printf("op_help [--version|--cpu-type] event_name\n"); - return 0; } else if (!strncmp(argv[i], "--cpu-type=", 11)) { sscanf(argv[i] + 11, "%d", &cpu_type); if (cpu_type < 0 || cpu_type >= MAX_CPU_TYPE) { - fprintf(stderr, "invalid cpu type %d, default to to %s\n", cpu_type, cpu_type_str[DEFAULT_CPU_TYPE]); - cpu_type = DEFAULT_CPU_TYPE; + fprintf(stderr, "invalid cpu type %d !\n", cpu_type); + exit(EXIT_FAILURE); } } else if (!strncmp(argv[i], "--get-cpu-type", 11)) { printf("%d\n", cpu_type); - exit(EXIT_SUCCESS); } else if (!strcmp(argv[1], "--gui-description")) { for_gui = 1; Index: op_init.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_init.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -d -r1.8 -r1.9 --- op_init.c 2001/09/08 21:46:03 1.8 +++ op_init.c 2001/09/12 02:54:30 1.9 @@ -55,10 +55,7 @@ if (expected_cpu_type != -1 && expected_cpu_type != cpu_type) { printk("oprofile: user space/module cpu detection mismatch\n"); - - /* FIXME: oprofile list */ - printk("please send the next line and your /proc/cpuinfo to mo...@co...\n"); - + printk("please send the next line and your /proc/cpuinfo to opr...@li...\n"); printk("vendor %d step %d model %d, expected_cpu_type %d, cpu_type %d\n", current_cpu_data.x86_vendor, current_cpu_data.x86, current_cpu_data.x86_model, expected_cpu_type, Index: op_user.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_user.h,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- op_user.h 2001/09/08 21:46:03 1.6 +++ op_user.h 2001/09/12 02:54:30 1.7 @@ -55,9 +55,6 @@ #define CPU_ATHLON 3 #define MAX_CPU_TYPE 4 -/* default value must be set by configure */ -#define DEFAULT_CPU_TYPE CPU_PII - #ifndef NR_CPUS #define NR_CPUS 32 #endif Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.84 retrieving revision 1.85 diff -u -d -r1.84 -r1.85 --- oprofile.c 2001/09/12 01:22:40 1.84 +++ oprofile.c 2001/09/12 02:54:30 1.85 @@ -66,6 +66,7 @@ u32 oprof_ready[NR_CPUS] __cacheline_aligned; static struct _oprof_data oprof_data[NR_CPUS]; +static uint op_irq_stats[NR_CPUS] __cacheline_aligned; extern spinlock_t map_lock; @@ -123,8 +124,10 @@ { ulong l,h; get_perfctr(l, h, ctr); - if (ctr_overflowed(l)) + if (ctr_overflowed(l)) { op_do_profile(data, regs, ctr); + op_irq_stats[op_cpu_id()]++; + } } asmlinkage void op_do_nmi(struct pt_regs *regs) @@ -594,7 +597,7 @@ inline static void pmc_select_stop(uint cpu) { - if (cpu==op_cpu_id()) + if (cpu == op_cpu_id()) pmc_stop(NULL); else smp_call_function(pmc_stop, &cpu, 0, 1); @@ -1127,26 +1130,30 @@ down(&sysctlsem); - if (write) { - /* clean out the hash table as far as possible */ - for (cpu=0; cpu < smp_num_cpus; cpu++) { - struct _oprof_data * data = &oprof_data[cpu]; - pmc_select_stop(cpu); - for (i=0; i < data->hash_size; i++) { - for (j=0; j < OP_NR_ENTRY; j++) - dump_one(data, &data->entries[i].samples[j], cpu); - if (oprof_ready[cpu]) - break; - } - oprof_ready[cpu] = 2; - pmc_select_start(cpu); - } - wake_up(&oprof_wait); - err = 0; + for (cpu=0; cpu < smp_num_cpus; cpu++) + printk("oprofile: CPU%u: %u interrupts\n", cpu, op_irq_stats[cpu]); + + if (!write) { + err = proc_dointvec(table, write, filp, buffer, lenp); goto out; } - - err = proc_dointvec(table, write, filp, buffer, lenp); + + err = 0; + + /* clean out the hash table as far as possible */ + for (cpu=0; cpu < smp_num_cpus; cpu++) { + struct _oprof_data * data = &oprof_data[cpu]; + pmc_select_stop(cpu); + for (i=0; i < data->hash_size; i++) { + for (j=0; j < OP_NR_ENTRY; j++) + dump_one(data, &data->entries[i].samples[j], cpu); + if (oprof_ready[cpu]) + break; + } + oprof_ready[cpu] = 2; + pmc_select_start(cpu); + } + wake_up(&oprof_wait); out: up(&sysctlsem); @@ -1165,7 +1172,6 @@ { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, }; - static ctl_table oprof_root[] = { {1, "oprofile", NULL, 0, 0700, oprof_table}, |
From: John L. <mov...@us...> - 2001-09-12 01:22:46
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv13782 Modified Files: ChangeLog oprofile.c oprofile.h Log Message: pedantry Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.104 retrieving revision 1.105 diff -u -d -r1.104 -r1.105 --- ChangeLog 2001/09/08 21:46:03 1.104 +++ ChangeLog 2001/09/12 01:22:40 1.105 @@ -1,3 +1,8 @@ +2001-09-12 John Levon <mo...@co...> + + * oprofile.h: + * oprofile.c: use cpu_number_map (pedantry thing) + 2001-09-07 Philippe Elie <ph...@cl...> * oprofile.c: remove /proc/.../cpu_type. Check if user Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.83 retrieving revision 1.84 diff -u -d -r1.83 -r1.84 --- oprofile.c 2001/09/08 21:46:03 1.83 +++ oprofile.c 2001/09/12 01:22:40 1.84 @@ -80,7 +80,7 @@ data->nextbuf = 0; return; } - oprof_ready[smp_processor_id()] = 1; + oprof_ready[op_cpu_id()] = 1; } inline static void fill_op_entry(struct op_sample *ops, struct pt_regs *regs, int ctr) @@ -129,7 +129,7 @@ asmlinkage void op_do_nmi(struct pt_regs *regs) { - struct _oprof_data *data = &oprof_data[smp_processor_id()]; + struct _oprof_data *data = &oprof_data[op_cpu_id()]; int i; if (pid_filter && current->pid != pid_filter) @@ -258,11 +258,11 @@ /* set up LVTPC as we need it */ /* IA32 V3, Figure 7.8 */ val = apic_read(APIC_LVTPC); - lvtpc_old_mask[smp_processor_id()] = val & APIC_LVT_MASKED; + lvtpc_old_mask[op_cpu_id()] = val & APIC_LVT_MASKED; /* allow PC overflow interrupts */ val &= ~APIC_LVT_MASKED; /* set delivery to NMI */ - lvtpc_old_mode[smp_processor_id()] = GET_APIC_DELIVERY_MODE(val); + lvtpc_old_mode[op_cpu_id()] = GET_APIC_DELIVERY_MODE(val); val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_NMI); apic_write(APIC_LVTPC, val); } @@ -271,8 +271,8 @@ { uint val = apic_read(APIC_LVTPC); // FIXME: this gives APIC errors on SMP hardware. - // val = SET_APIC_DELIVERY_MODE(val, lvtpc_old_mode[smp_processor_id()]); - if (lvtpc_old_mask[smp_processor_id()]) + // val = SET_APIC_DELIVERY_MODE(val, lvtpc_old_mode[op_cpu_id()]); + if (lvtpc_old_mask[op_cpu_id()]) val |= APIC_LVT_MASKED; else val &= ~APIC_LVT_MASKED; @@ -537,7 +537,7 @@ static void pmc_start(void *info) { - if (info && (*((uint *)info) != smp_processor_id())) + if (info && (*((uint *)info) != op_cpu_id())) return; /* assert: all enable counter are setup except the bit start/stop, @@ -574,7 +574,7 @@ static void pmc_stop(void *info) { - if (info && (*((uint *)info) != smp_processor_id())) + if (info && (*((uint *)info) != op_cpu_id())) return; /* disable counters */ @@ -586,7 +586,7 @@ inline static void pmc_select_start(uint cpu) { - if (cpu==smp_processor_id()) + if (cpu == op_cpu_id()) pmc_start(NULL); else smp_call_function(pmc_start, &cpu, 0, 1); @@ -594,7 +594,7 @@ inline static void pmc_select_stop(uint cpu) { - if (cpu==smp_processor_id()) + if (cpu==op_cpu_id()) pmc_stop(NULL); else smp_call_function(pmc_stop, &cpu, 0, 1); Index: oprofile.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.h,v retrieving revision 1.50 retrieving revision 1.51 diff -u -d -r1.50 -r1.51 --- oprofile.h 2001/09/06 18:13:28 1.50 +++ oprofile.h 2001/09/12 01:22:41 1.51 @@ -172,6 +172,8 @@ struct _descr { u16 limit; u32 base; } __attribute__((__packed__)); struct _idt_descr { u32 a; u32 b; } __attribute__((__packed__)); +#define op_cpu_id() (cpu_number_map(smp_processor_id())) + /* we can't unload safely on SMP */ #ifdef CONFIG_SMP #define smp_can_unload() (allow_unload) |
From: John L. <mov...@us...> - 2001-09-12 01:22:46
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv13782/dae Modified Files: opd_proc.c Log Message: pedantry Index: opd_proc.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/opd_proc.c,v retrieving revision 1.69 retrieving revision 1.70 diff -u -d -r1.69 -r1.70 --- opd_proc.c 2001/09/06 20:41:48 1.69 +++ opd_proc.c 2001/09/12 01:22:41 1.70 @@ -96,7 +96,7 @@ } } - printf("%s stats:\n", opd_get_time()); + printf("%s\n", opd_get_time()); printf("Nr. kernel samples: %lu\n", opd_stats[OPD_KERNEL]); printf("Nr. samples lost due to no process information: %lu\n", opd_stats[OPD_LOST_PROCESS]); printf("Nr. process samples in user-space: %lu\n", opd_stats[OPD_PROCESS]); |
From: Philippe E. <ph...@us...> - 2001-09-08 21:46:07
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv13225/oprofile/pp Modified Files: opf_filter.cpp oprof_convert.c oprofpp.c Log Message: centralize cpu type detection Index: opf_filter.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/opf_filter.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- opf_filter.cpp 2001/09/06 18:13:28 1.5 +++ opf_filter.cpp 2001/09/08 21:46:04 1.6 @@ -45,7 +45,7 @@ double do_ratio(size_t a, size_t total); -// FIXME: must change this +// The correct value is passed by oprofpp on standard input. uint op_nr_counters = 2; } @@ -175,6 +175,8 @@ // sort source by this counter. size_t sort_by_counter; + int cpu_type; + bool until_more_than_samples; bool have_linenr_info; @@ -345,6 +347,7 @@ cpu_speed(0.0), threshold_percent(threshold_percent_), sort_by_counter(sort_by_counter_), + cpu_type(-1), until_more_than_samples(until_more_than_samples_), have_linenr_info(have_linenr_info_) { @@ -908,6 +911,8 @@ // assembly ? } + out << "Cpu type: " << cpu_type << endl; + out << "Cpu speed (MHz estimation) : " << cpu_speed << endl; out << endl; @@ -919,6 +924,17 @@ setup_counter_param(in); string str; + in.read_line(str); + + if (sscanf(str.c_str(), "Cpu type: %d", &cpu_type) != 1) { + cerr << "unable to read cpu_type\n"; + + return false; + } + + if (cpu_type == CPU_ATHLON) + op_nr_counters = 4; + in.read_line(str); if (sscanf(str.c_str(), "Cpu speed was (MHz estimation) : %lf", &cpu_speed) != 1) { Index: oprof_convert.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprof_convert.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -d -r1.10 -r1.11 --- oprof_convert.c 2001/09/06 18:13:28 1.10 +++ oprof_convert.c 2001/09/08 21:46:04 1.11 @@ -207,7 +207,11 @@ int dirty; if (cpu_type == -1 || cpu_type < 0 || cpu_type > 3) { + /* do not default it to allow tricky user to convert on a + * hardware that is not the harware used to generate the sample + * file */ fprintf(stderr, "converting %s to new file format require option --cpu-type=[0|1|2|3]\n", filename); + fprintf(stderr, "use \"op_help --get-cpu-type\" to get your cpu type or specify the cpu type used to generate this samples file\n"); return; } Index: oprofpp.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp.c,v retrieving revision 1.38 retrieving revision 1.39 diff -u -d -r1.38 -r1.39 --- oprofpp.c 2001/09/06 18:13:28 1.38 +++ oprofpp.c 2001/09/08 21:46:04 1.39 @@ -1051,16 +1051,19 @@ get_options(argc, argv); - // FIXME: we must discover op_nr_counters from cpu_type of sample - // file or something - for (i = 0; i < op_nr_counters ; ++i) { + /* op_nr_counters is discovered from the samples itself, until we + * have opened the samples file(s) we must loop over all the possible + * available counters. This is a little what ugly but it allows + * to interpret samples files on a different hardware where the + * the profiler has run */ + for (i = 0; i < OP_MAX_COUNTERS; ++i) { fd[i] = -1; size[i] = 0; samples[i] = NULL; footer[i] = NULL; } - for (i = 0; i < op_nr_counters ; ++i) { + for (i = 0; i < OP_MAX_COUNTERS ; ++i) { if (ctr == -1 || ctr == (int)i) /* if ctr == i, this means than we open only one * samples file so don't allow opening failure to get @@ -1068,23 +1071,23 @@ fd[i] = open_samples_file(i, &size[i], ctr != (int)i); } - for (i = 0; i < op_nr_counters ; ++i) { + for (i = 0; i < OP_MAX_COUNTERS ; ++i) { if (fd[i] != -1) break; } - if (i == op_nr_counters) { + if (i == OP_MAX_COUNTERS) { fprintf(stderr, "Can not open any samples files for %s last error %s\n", samplefile, strerror(errno)); exit(EXIT_FAILURE); } /* sanity check between the different samples files */ - for (i = 0 ; i < op_nr_counters; ++i) { + for (i = 0 ; i < OP_MAX_COUNTERS; ++i) { if (fd[i] != -1) break; } - for (j = i + 1; j < op_nr_counters ; ++j) { + for (j = i + 1; j < OP_MAX_COUNTERS; ++j) { if (fd[j] != -1) { if (size[i] != size[j]) { fprintf(stderr, "oprofpp: mapping file size " @@ -1099,7 +1102,7 @@ } /* output and sanity check on ctr_um, ctr_event and cpu_type */ - for (i = 0 ; i < op_nr_counters ; ++i) { + for (i = 0 ; i < OP_MAX_COUNTERS; ++i) { if (fd[i] != -1) { check_and_output_event(i); @@ -1122,10 +1125,15 @@ exit(EXIT_FAILURE); } - for (i = 0; i < op_nr_counters ; ++i) { + for (i = 0; i < OP_MAX_COUNTERS; ++i) { if (fd[i] != -1) break; } + + if (footer[i]->cpu_type == CPU_ATHLON) + op_nr_counters = 4; + + printf("Cpu type: %d\n", footer[i]->cpu_type); printf("Cpu speed was (MHz estimation) : %f\n", footer[i]->cpu_speed); |
From: Philippe E. <ph...@us...> - 2001-09-08 21:46:07
|
Update of /cvsroot/oprofile/oprofile/gui In directory usw-pr-cvs1:/tmp/cvs-serv13225/oprofile/gui Modified Files: oprofile Log Message: centralize cpu type detection Index: oprofile =================================================================== RCS file: /cvsroot/oprofile/oprofile/gui/oprofile,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- oprofile 2001/09/01 02:03:34 1.11 +++ oprofile 2001/09/08 21:46:04 1.12 @@ -427,7 +427,6 @@ return } - append args " --use-cpu=$processor_type" append args " --map-file=$map_filename" append args " --vmlinux=$kernel_filename" append args " --kernel-only=$kernel_only" |
From: Philippe E. <ph...@us...> - 2001-09-08 21:46:06
|
Update of /cvsroot/oprofile/oprofile/doc In directory usw-pr-cvs1:/tmp/cvs-serv13225/oprofile/doc Modified Files: oprofile.1.in oprofile.sgml Log Message: centralize cpu type detection Index: oprofile.1.in =================================================================== RCS file: /cvsroot/oprofile/oprofile/doc/oprofile.1.in,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- oprofile.1.in 2001/08/16 02:23:01 1.6 +++ oprofile.1.in 2001/09/08 21:46:04 1.7 @@ -93,10 +93,6 @@ Only profile process group pgrp (if compiled in) .br .TP -.I "--use-cpu" -0 or PPro, 1 for PII, 2 for PIII -.br -.TP .I "--ignore-myself" ignore samples for oprofiled .br Index: oprofile.sgml =================================================================== RCS file: /cvsroot/oprofile/oprofile/doc/oprofile.sgml,v retrieving revision 1.24 retrieving revision 1.25 diff -u -d -r1.24 -r1.25 --- oprofile.sgml 2001/09/06 18:13:28 1.24 +++ oprofile.sgml 2001/09/08 21:46:04 1.25 @@ -503,8 +503,8 @@ <listitem><para> The numeric event value. You can convert from symbolic event names to numeric values like so : </para><para><command>echo `op_help CPU_CLK_UNHALTED` >/proc/sys/dev/oprofile/0/0/event</command> - Note that if you are using an Athlon, Duron, etc. you must use - <command>op_help --cpu-type=3 RETIRED_INSNS</command> (for example) to use Athlon events. + You can override the detection of your cpu type with: + <command>op_help --cpu-type=3 RETIRED_INSNS</command> (for example) to see Athlon events on a PII. </para></listitem> </varlistentry> <varlistentry> |
From: Philippe E. <ph...@us...> - 2001-09-08 21:46:06
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv13225/oprofile/dae Modified Files: op_start oprofiled.c Log Message: centralize cpu type detection Index: op_start =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_start,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- op_start 2001/09/06 19:06:22 1.40 +++ op_start 2001/09/08 21:46:04 1.41 @@ -32,37 +32,7 @@ PGRP_FILTER=0 VERBOSE=0 -if test -f /proc/cpuinfo; then - modelname=`cat /proc/cpuinfo | grep "model\ name\ :" | sed -e 's/ //g' | cut -d':' -f2` - case $modelname in - *PentiumPro*) - CPUTYPE=0 - ;; - *PentiumIII*) - CPUTYPE=2 - ;; - *PentiumII*) - CPUTYPE=1 - ;; - *Athlon* | *Duron* | *K7*) - CPUTYPE=3 - ;; - # FIXME: I'm not sure this is right ... - *Coppermine*) - CPUTYPE=2 - ;; - *Celeron*) - CPUTYPE=1 - ;; - *) - echo "Unknown CPU type. Please send /proc/cpuinfo to mo...@co..." - CPUTYPE=0 - ;; - esac - -else - CPUTYPE=0 -fi +CPUTYPE=`op_help --get-cpu-type` case $CPUTYPE in 0|1|2) @@ -255,7 +225,7 @@ echo "Event but no count specified for counter $f" exit 1 fi - CTR_EVENT_VAL[$f]=`op_help --cpu-type=$CPUTYPE ${CTR_EVENT[$f]}` + CTR_EVENT_VAL[$f]=`op_help ${CTR_EVENT[$f]}` if [ -z "${CTR_EVENT_VAL[$f]}" -a ! -z "${CTR_EVENT[$f]}" ]; then echo "Unknown event \"${CTR_EVENT[$f]}\"" exit 1 @@ -276,7 +246,7 @@ grep oprof /proc/devices >/dev/null if [ "$?" -ne 0 ]; then - modprobe oprofile + modprobe oprofile expected_cpu_type=$CPUTYPE if [ "$?" != "0" ] then echo "Couldn't load oprofile.o module" Index: oprofiled.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/oprofiled.c,v retrieving revision 1.41 retrieving revision 1.42 diff -u -d -r1.41 -r1.42 --- oprofiled.c 2001/09/06 18:13:28 1.41 +++ oprofiled.c 2001/09/08 21:46:04 1.42 @@ -419,7 +419,7 @@ struct sigaction act; int i; - cpu_type = opd_read_int_from_file("/proc/sys/dev/oprofile/cpu_type"); + cpu_type = op_get_cpu_type(); if (cpu_type == CPU_ATHLON) op_nr_counters = 4; |