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: Philippe E. <ph...@us...> - 2001-09-08 21:46:06
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv13225/oprofile Modified Files: ChangeLog op_events.c op_init.c op_user.h oprofile.c Log Message: centralize cpu type detection Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.103 retrieving revision 1.104 diff -u -d -r1.103 -r1.104 --- ChangeLog 2001/09/06 20:41:48 1.103 +++ ChangeLog 2001/09/08 21:46:03 1.104 @@ -1,3 +1,18 @@ +2001-09-07 Philippe Elie <ph...@cl...> + + * oprofile.c: remove /proc/.../cpu_type. Check if user + mode cpu type detection is identical to module cpu type + * op_events.h: + * op_events.c: add op_get_cpu_type(). script can get cpu_type + by op_help --get-cpu-type + * gui/oprofile: use it + * dae/oprofiled.c: ditto + * dae/op_start: ditto, pass expected_cpu_type to module + * doc/oprofile.sgml: update + * doc/oprofile.1.in: update + * pp/oprofpp.c: get cpu_type from samples file + * pp/opf_filter.cpp: get cpu type from stdin + 2001-09-06 John Levon <mo...@co...> * dae/opd_proc.c: use j not i in msync ! Index: op_events.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_events.c,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- op_events.c 2001/09/06 18:13:28 1.22 +++ op_events.c 2001/09/08 21:46:03 1.23 @@ -429,6 +429,81 @@ return cpu_type_str[cpu_type]; } + +/* module have its own stuff to detect cpu type */ +#ifndef MODULE + +struct op_cpu_type { + const char *cpu_name; + 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 */ +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 }, +}; + +#define OP_CPU_TYPES_NR (sizeof(op_cpu_types) / sizeof(op_cpu_types[0])) + +/** + * 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 + */ +int op_get_cpu_type(void) +{ + int cpu_type; + 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 (!found) { + /* FIXME: use oprofile mail list adress here ? */ + fprintf(stderr, "Unknown CPU type. Please send /proc/cpuinfo to mo...@co...\n"); + } + + return cpu_type; +} + +#undef OP_CPU_TYPES_NR + +#endif + #ifdef OP_EVENTS_DESC struct op_unit_desc { char *desc[7]; @@ -795,6 +870,8 @@ int cpu_type_mask; int for_gui; + cpu_type = op_get_cpu_type(); + for_gui = 0; for (i = 1 ; i < argc ; ++i) { if (!strcmp(argv[i], "--version")) { @@ -810,7 +887,11 @@ fprintf(stderr, "invalid cpu type %d, default to to %s\n", cpu_type, cpu_type_str[DEFAULT_CPU_TYPE]); cpu_type = DEFAULT_CPU_TYPE; } - } else if (!strcmp(argv[1], "--gui-description")) { + } 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; } else { cpu_type_mask = 1 << cpu_type; Index: op_init.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_init.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -d -r1.7 -r1.8 --- op_init.c 2001/09/06 18:13:28 1.7 +++ op_init.c 2001/09/08 21:46:03 1.8 @@ -19,6 +19,10 @@ EXPORT_NO_SYMBOLS; +MODULE_PARM(expected_cpu_type, "i"); +MODULE_PARM_DESC(expected_cpu_type, "Allow checking of detected hardware from the user space"); +static int expected_cpu_type = -1; + extern int cpu_type; extern uint op_nr_counters; extern int separate_running_bit; @@ -46,6 +50,21 @@ if (cpu_type == CPU_ATHLON) { op_nr_counters = 4; separate_running_bit = 1; + } + + 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("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, + cpu_type); + + return CPU_NO_GOOD; } return cpu_type; } Index: op_user.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_user.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- op_user.h 2001/09/06 18:13:28 1.5 +++ op_user.h 2001/09/08 21:46:03 1.6 @@ -169,5 +169,6 @@ /* not used currently */ 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); #endif /* OP_USER_H */ Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.82 retrieving revision 1.83 diff -u -d -r1.82 -r1.83 --- oprofile.c 2001/09/06 18:13:28 1.82 +++ oprofile.c 2001/09/08 21:46:03 1.83 @@ -1153,7 +1153,7 @@ return err; } -static int nr_oprof_static = 7; +static int nr_oprof_static = 6; static ctl_table oprof_table[] = { { 1, "bufsize", &op_buf_size, sizeof(int), 0600, NULL, &lproc_dointvec, NULL, }, @@ -1162,7 +1162,6 @@ { 1, "kernel_only", &kernel_only, sizeof(int), 0600, NULL, &lproc_dointvec, NULL, }, { 1, "pid_filter", &pid_filter, sizeof(pid_t), 0600, NULL, &lproc_dointvec, NULL, }, { 1, "pgrp_filter", &pgrp_filter, sizeof(pid_t), 0600, NULL, &lproc_dointvec, NULL, }, - { 1, "cpu_type", &cpu_type, sizeof(int), 0400, NULL, &lproc_dointvec, NULL, }, { 0, }, { 0, }, { 0, }, { 0, }, { 0, }, }; |
From: John L. <mov...@us...> - 2001-09-06 20:41:50
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv28222/dae Modified Files: opd_proc.c Log Message: fix core dump Index: opd_proc.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/opd_proc.c,v retrieving revision 1.68 retrieving revision 1.69 diff -u -d -r1.68 -r1.69 --- opd_proc.c 2001/09/06 18:13:28 1.68 +++ opd_proc.c 2001/09/06 20:41:48 1.69 @@ -81,7 +81,7 @@ struct opd_image* image = &opd_images[i]; for (j = 0 ; j < op_nr_counters ; ++j) { if (image->sample_files[j].fd > 1) - msync(image->sample_files[i].start, image->len + sizeof(struct opd_footer), MS_ASYNC); + msync(image->sample_files[j].start, image->len + sizeof(struct opd_footer), MS_ASYNC); } } |
From: John L. <mov...@us...> - 2001-09-06 20:41:50
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv28222 Modified Files: ChangeLog Log Message: fix core dump Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.102 retrieving revision 1.103 diff -u -d -r1.102 -r1.103 --- ChangeLog 2001/09/06 19:06:22 1.102 +++ ChangeLog 2001/09/06 20:41:48 1.103 @@ -1,5 +1,9 @@ 2001-09-06 John Levon <mo...@co...> + * dae/opd_proc.c: use j not i in msync ! + +2001-09-06 John Levon <mo...@co...> + * dae/op_start: more sanity checking of options 2001-09-06 John Levon <mo...@co...> |
From: John L. <mov...@us...> - 2001-09-06 19:06:26
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv4674/dae Modified Files: op_start Log Message: extra sanity checks in op_start Index: op_start =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_start,v retrieving revision 1.39 retrieving revision 1.40 diff -u -d -r1.39 -r1.40 --- op_start 2001/09/06 18:13:28 1.39 +++ op_start 2001/09/06 19:06:22 1.40 @@ -76,7 +76,6 @@ # we can now default define individual counter setup variable. f=0 while (( $f < $OP_MAX_COUNTERS )); do - CTR_COUNT[$f]=600000 CTR_USER[$f]=1 CTR_KERNEL[$f]=1 f=$(($f+1)) @@ -252,12 +251,22 @@ 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 --cpu-type=$CPUTYPE ${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 + fi fi + f=$(($f+1)) done |
From: John L. <mov...@us...> - 2001-09-06 19:06:26
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv4674 Modified Files: ChangeLog Log Message: extra sanity checks in op_start Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.101 retrieving revision 1.102 diff -u -d -r1.101 -r1.102 --- ChangeLog 2001/09/06 18:13:28 1.101 +++ ChangeLog 2001/09/06 19:06:22 1.102 @@ -1,5 +1,9 @@ 2001-09-06 John Levon <mo...@co...> + * dae/op_start: more sanity checking of options + +2001-09-06 John Levon <mo...@co...> + * doc/oprofile.sgml: update a bit 2001-09-06 John Levon <mo...@co...> |
From: John L. <mov...@us...> - 2001-09-06 18:13:31
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv22397/pp Modified Files: op_to_source opf_container.cpp opf_filter.cpp oprof_convert.c oprofpp.c Log Message: philippe's cleanup, and several fixes from me. Index: op_to_source =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/op_to_source,v retrieving revision 1.5 retrieving revision 1.6 diff -u -d -r1.5 -r1.6 --- op_to_source 2001/09/01 02:03:34 1.5 +++ op_to_source 2001/09/06 18:13:28 1.6 @@ -101,9 +101,6 @@ shift done -# PHE FIXME : this checking need to be remade with the new samples files naming -# scheme - # Check than enough option has been given. if [ "$object_file" == "" -a "$sample_file" == "" ]; then echo "You need to give at least an object-file or a sample-file" @@ -116,12 +113,15 @@ exit 1 fi -# PHE FIXME: bogus here is case of passing sample_filename without the #x -# prefix. Should be rewrite perhaps. -#if [ "$sample_file" != "" -a ! -f "$sample_file" ]; then -# echo "sample file $sample_file does not exist" -# exit 1 -#fi +if [ "$object_file" == "" -a "$do_to_asm" == "true" ]; then + echo "you must give an object filename if assembly output is required" + exit 1 +fi + +# we don't check existence of sample file because oprofpp can use it +# as a base filename. FIXME: we need to make the check here to avoid breaking +# the pipe used to generate the report, else if sample file do not exist we +# get an ugly message error if [ "$sample_file" != "" ]; then oprofpp_option="$oprofpp_option -f $sample_file" Index: opf_container.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/opf_container.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- opf_container.cpp 2001/09/01 02:03:34 1.4 +++ opf_container.cpp 2001/09/06 18:13:28 1.5 @@ -25,6 +25,11 @@ #include "opf_filter.h" +namespace { + // FIXME ! + uint op_nr_counters = 2; +} + //--------------------------------------------------------------------------- // Functors used as predicate for vma comparison. struct less_sample_entry_by_vma { Index: opf_filter.cpp =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/opf_filter.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- opf_filter.cpp 2001/09/01 02:03:34 1.4 +++ opf_filter.cpp 2001/09/06 18:13:28 1.5 @@ -45,6 +45,8 @@ double do_ratio(size_t a, size_t total); +// FIXME: must change this +uint op_nr_counters = 2; } //--------------------------------------------------------------------------- Index: oprof_convert.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprof_convert.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -d -r1.9 -r1.10 --- oprof_convert.c 2001/09/01 02:03:34 1.9 +++ oprof_convert.c 2001/09/06 18:13:28 1.10 @@ -235,26 +235,13 @@ goto err1; } - /* PHE FIXME: same issue in opd_proc.c with more comments */ -#if 0 - /* ugly: mmap needs than fd size is sufficient. */ - if (lseek(out_fd, size - 1, SEEK_SET) == -1) { - fprintf(stderr, "oprofiled: seek failed for \"%s\". %s\n", out_filename, strerror(errno)); - goto err2; - } - - /* PHE FIXME: this unsparse the file by one memory page - * size at the end file :( An another way to grow a file ? */ - if (write(out_fd, "", 1) != 1) { - perror("oprof_convert: cannot grow sample file. "); + /* 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 unsparse a little what the samples file */ + if (ftruncate(out_fd, size) == -1) { + fprintf(stderr, "oprof_convert: ftruncate failed for \"%s\". %s\n", out_filename, strerror(errno)); goto err2; } -#else - if (ftruncate(out_fd, size) == -1) { - fprintf(stderr, "oprof_convert: ftruncate failed for \"%s\". %s\n", out_filename, strerror(errno)); - goto err2; - } -#endif footer = mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, out_fd, 0); Index: oprofpp.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/oprofpp.c,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- oprofpp.c 2001/09/01 02:03:34 1.37 +++ oprofpp.c 2001/09/06 18:13:28 1.38 @@ -29,6 +29,7 @@ static int showvers; static int verbose; +static uint op_nr_counters = 2; static char const *samplefile; static char *basedir="/var/opd"; @@ -56,6 +57,8 @@ static int ctr = -1; static u32 sect_offset; +static int accumulate_samples(u32 counter[OP_MAX_COUNTERS], int index); + static struct poptOption options[] = { { "samples-file", 'f', POPT_ARG_STRING, &samplefile, 0, "image sample file", "file", }, { "image-file", 'i', POPT_ARG_STRING, &imagefile, 0, "image file", "file", }, @@ -186,16 +189,16 @@ } if (ctr != counter) { - /* PHE FIXME documentation of this behavior */ /* a --counter=x have priority on the # suffixe of filename */ if (ctr != -1 && counter != -1) { /* conflict between #%d and --ctr option */ fprintf(stderr, "oprofpp: conflict between %s filename counter nr and --ctr %d option, using --ctr option %d\n", file_ctr_str, ctr, ctr); + counter = ctr; } - } - counter = ctr; + if (ctr == -1) + ctr = counter; if (ctr == -1) { /* list_all_symbols_details always output all counter and do @@ -216,7 +219,7 @@ if (file_ctr_str) file_ctr_str[0] = '\0'; - if (ctr != -1 && (ctr < 0 || ctr >= op_nr_counters)) { + if (ctr != -1 && (ctr < 0 || ctr >= (int)op_nr_counters)) { ctr = 0; fprintf(stderr, "oprofpp: invalid counter number, using %d\n", ctr); @@ -284,6 +287,7 @@ char **matching; time_t newmtime; bfd *ibfd; + uint i; file = (char *)imagefile; @@ -338,9 +342,18 @@ if (!imagefile) free(file); - /* PHE FIXME: this is broken, should search for a opended sample file - * */ - if (footer[ctr == -1 ? 0 : ctr]->is_kernel) { + for (i = 0; i < op_nr_counters; ++i) { + if (footer[i]) + break; + } + + /* should never happens */ + if (i == op_nr_counters) { + fprintf(stderr,"oprofpp: open_image_file() no samples file open for %s.\n", file); + exit(EXIT_FAILURE); + } + + if (footer[i]->is_kernel) { asection *sect; sect = bfd_get_section_by_name(ibfd, ".text"); @@ -503,13 +516,11 @@ { struct opp_count *ca= (struct opp_count *)a; struct opp_count *cb= (struct opp_count *)b; - - /* PHE FIXME: I think it is correct... */ - int counter = ctr == -1 ? 0 : ctr; - if (ca->count[counter] < cb->count[counter]) + /* note than ctr must be sanitized before calling qsort */ + if (ca->count[ctr] < cb->count[ctr]) return -1; - return (ca->count[counter] > cb->count[counter]); + return (ca->count[ctr] > cb->count[ctr]); } /** @@ -524,9 +535,10 @@ struct opp_count *scounts; u32 start, end; uint tot[OP_MAX_COUNTERS],i,j; - int found_samples, k; + int found_samples; + uint k; - for (i = 0 ; i < op_nr_counters ; ++i) { + for (i = 0; i < op_nr_counters; ++i) { tot[i] = 0; } @@ -547,24 +559,24 @@ } for (j = start; j < end; j++) { - /* PHE FIXME too imbrication level */ - for (k = 0 ; k < op_nr_counters ; ++k) { - if (samples[k] && samples[k][j].count) { - verbprintf("Adding %u 0-samples for symbol $%s$ at pos j 0x%x\n", - samples[k][j].count, syms[i]->name, j); - scounts[i].count[k] += samples[k][j].count; - tot[k] += samples[k][j].count; - } - } + accumulate_samples(scounts[i].count, j); + } + + for (k = 0 ; k < op_nr_counters ; ++k) { + tot[k] += scounts[i].count[k]; } } + 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++) { printf_symbol(scounts[i].sym->name); - /* PHE FIXME too imbrication level */ found_samples = 0; for (k = 0; k < op_nr_counters ; ++k) { if (scounts[i].count[k]) { @@ -593,7 +605,7 @@ { u32 start, end; u32 i, j; - int k; + uint k; for (i=0; i < num; i++) { if (streq(syms[i]->name, symbol)) @@ -762,24 +774,20 @@ /** * accumulate_samples - lookup and output linenr info from a vma address * in a given section to standard output. - * @counter: where to accumulate the samples, can be %NULL + * @counter: where to accumulate the samples * @index: index number of the samples. - * - * if @counter != %NULL accumulate samples count in @counter - * else just return 0/1 if they exist samples at @index * - * return non-zero if samples has been found + * return 0 if no samples has been found else return 1 */ static int accumulate_samples(u32 counter[OP_MAX_COUNTERS], int index) { - int k; + uint k; int found_samples = 0; for (k = 0; k < op_nr_counters; ++k) { if (samples[k] && samples[k][index].count) { found_samples = 1; - if (counter) - counter[k] += samples[k][index].count; + counter[k] += samples[k][index].count; } } @@ -803,7 +811,7 @@ for (i = 0 ; i < num ; ++i) { u32 counter[OP_MAX_COUNTERS]; - int k; + uint k; int found_samples; get_symbol_range(syms[i], (i == num-1) ? NULL : syms[i+1], @@ -1035,7 +1043,7 @@ { bfd *ibfd; asymbol **syms; - int i, j; + uint i, j; fd_t fd[OP_MAX_COUNTERS]; size_t size[OP_MAX_COUNTERS]; uint num; @@ -1043,6 +1051,8 @@ 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) { fd[i] = -1; size[i] = 0; @@ -1051,10 +1061,11 @@ } for (i = 0; i < op_nr_counters ; ++i) { - if (ctr == -1 || ctr == i) - /* PHE FIXME: in some case we can pass 0 as can_fail - * to get better error message */ - fd[i] = open_samples_file(i, &size[i], 1); + 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 + * a more precise error message */ + fd[i] = open_samples_file(i, &size[i], ctr != (int)i); } for (i = 0; i < op_nr_counters ; ++i) { @@ -1111,8 +1122,12 @@ exit(EXIT_FAILURE); } - printf("Cpu speed was (MHz estimation) : %f\n", - footer[ctr == -1 ? 0 : ctr]->cpu_speed); + for (i = 0; i < op_nr_counters ; ++i) { + if (fd[i] != -1) + break; + } + + printf("Cpu speed was (MHz estimation) : %f\n", footer[i]->cpu_speed); if (list_symbols) { do_list_symbols(syms, num); |
From: John L. <mov...@us...> - 2001-09-06 18:13:31
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv22397/dae Modified Files: op_start opd_proc.c oprofiled.c Log Message: philippe's cleanup, and several fixes from me. Index: op_start =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_start,v retrieving revision 1.38 retrieving revision 1.39 diff -u -d -r1.38 -r1.39 --- op_start 2001/09/04 17:30:12 1.38 +++ op_start 2001/09/06 18:13:28 1.39 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # $Id$ # COPYRIGHT (C) 2000 THE VICTORIA UNIVERSITY OF MANCHESTER and John Levon # This program is free software; you can redistribute it and/or modify it @@ -32,18 +32,6 @@ PGRP_FILTER=0 VERBOSE=0 -# PHE FIXME: too many changes needs a redesign. Proposition: -# 1) check for a cpu_type switch, -# 2) stop the daemon -# 3) modprobe oprofile [cpu_type=xx] -# 4) if --cpu-type not given get it from /proc/sys/dev/oprofile/cpu_type -# 5) default init -# 6) parse parameter -# 7) launch the daemon -# this avoid passing cpu_type in the common case and allow in case or module -# misdetect the used core to overwrite it through an init parameters to the -# module - if test -f /proc/cpuinfo; then modelname=`cat /proc/cpuinfo | grep "model\ name\ :" | sed -e 's/ //g' | cut -d':' -f2` case $modelname in @@ -110,7 +98,6 @@ --pgrp-filter=pgrp Only profile process group pgrp Daemon options - --use-cpu=[0|1|2|3] 0: PPro, 1: PII, 2: PIII, 3: AMD Athlon. --ignore-myself=[0|1] ignore samples for oprofiled --log-file=file log file --base-dir=dir base directory of daemon @@ -152,12 +139,15 @@ echo $val > /proc/sys/$dev_name } -# PHE FIXME: assume ctr < 9, how from an awk expr extract the int field? -# probably needs to use bash string manipulation. -# extract the field N from --ctrN-xxxxxx +# extract the integer field N from --ctr[N]-xxxxxxx extract_int() { - echo $1 | awk '{print substr($0, 6, 1)}' + local val=`echo $1 | sed 's,--ctr\([0-9]*\)[-A-Za-z]*,\1,'` + + if (($val >= $OP_MAX_COUNTERS || $val < 0)); then + echo "invalid argument $1: bad counter number" + fi + echo $val } LOG_FILE= @@ -171,15 +161,6 @@ arg=`echo $1 | awk -F= '{print $1}'` val=`echo $1 | awk -F= '{print $2}'` case "$arg" in - # PHE FIXME: this work actually but if the forced cpu type have - # more counter than OP_MAX_COUNTERS only OP_NR_MAX_COUNTERS - # can be used. if less the script do not work and you can - # get many trouble. - --use-cpu) - if [ "$val" != "" ]; then - CPUTYPE=$val - fi - ;; --ignore-myself) if [ "$val" != "" ]; then IGNORE_MYSELF=$val @@ -200,21 +181,20 @@ KERNEL_ONLY=1 fi ;; - # PHE FIXME: see comment at extract_int --ctr*-unit-mask) - CTR_UM[`extract_int $1`]=$val + CTR_UM[`extract_int $arg`]=$val ;; --ctr*-event) - CTR_EVENT[`extract_int $1`]=$val + CTR_EVENT[`extract_int $arg`]=$val ;; --ctr*-count) - CTR_COUNT[`extract_int $1`]=$val + CTR_COUNT[`extract_int $arg`]=$val ;; --ctr*-user) - CTR_USER[`extract_int $1`]=$val + CTR_USER[`extract_int $arg`]=$val ;; --ctr*-kernel) - CTR_KERNEL[`extract_int $1`]=$val + CTR_KERNEL[`extract_int $arg`]=$val ;; --base-dir) DIR=$val @@ -449,7 +429,7 @@ f=$(($f+1)) done -OPD_ARGS="--buffer-size=$BUF_SIZE --use-cpu=$CPUTYPE --ignore-myself=$IGNORE_MYSELF \ +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" Index: opd_proc.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/opd_proc.c,v retrieving revision 1.67 retrieving revision 1.68 diff -u -d -r1.67 -r1.68 --- opd_proc.c 2001/09/04 12:50:10 1.67 +++ opd_proc.c 2001/09/06 18:13:28 1.68 @@ -25,6 +25,7 @@ extern int kernel_only; extern int verbose; +extern uint op_nr_counters; extern unsigned long opd_stats[]; extern char *vmlinux; extern char *smpdir; @@ -74,7 +75,7 @@ struct opd_proc *proc; struct opd_proc *next; uint i; - int j; + uint j; for (i = 0; i < nr_images; i++) { struct opd_image* image = &opd_images[i]; @@ -265,7 +266,7 @@ */ static void opd_handle_old_sample_files(const char *image_name, time_t mtime) { - int i; + uint i; char *mangled; mangled = opd_mangle_filename(smpdir, image_name); @@ -295,9 +296,8 @@ */ static void opd_open_image(struct opd_image *image, const char *name, int kernel) { - int i; + uint i; - /* PHE FIXME : store the mangled name ? */ image->name = opd_strdup(name); image->kernel = kernel; image->len = 0; @@ -386,35 +386,14 @@ fprintf(stderr,"oprofiled: open of image sample file \"%s\" failed: %s\n", mangled, strerror(errno)); goto err1; } - - /* PHE FIXME: keep it, I need opinion on the two manner to do the job - * I am unsure if there is no a thrid way to make this */ -#if 0 - /* ugly: mmap needs than fd size is sufficient, bugs in this area - * is difficult to understand, mmap sucess but the returned pointer - * cause a segfault, then the daemon is killed without coredump nor - * message error. PHE FIXME: why this mmap behavior, and why daemon die - * silently ? */ - if (lseek(sample_file->fd, image->len + sizeof(struct opd_footer) - 1, SEEK_SET) == -1) { - fprintf(stderr, "oprofiled: seek failed for \"%s\". %s\n", mangled, strerror(errno)); - goto err2; - } - /* PHE FIXME: this unsparse the file by one memory page size at the - * end of file :( An another way to grow the file ?, 0 write size do - * not work. try a write from the zero page? */ - if (write(sample_file->fd, "", 1) != 1) { - perror("oprofiled: cannot grow sample file. "); - goto err2; - } -#else - /* PHE FIXME: perhaps this is equivalent to the code above other #if - * alternative */ + /* 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) { fprintf(stderr, "oprofiled: ftruncate failed for \"%s\". %s\n", mangled, strerror(errno)); goto err2; } -#endif sample_file->footer = mmap(0, image->len + sizeof(struct opd_footer), PROT_READ|PROT_WRITE, MAP_SHARED, sample_file->fd, 0); @@ -1163,7 +1142,8 @@ opd_stats[OPD_SAMPLES]++; - verbprintf("DO_PUT_SAMPLE: EIP 0x%.8x, pid %.6d, count %.6d\n", sample->eip, sample->pid, sample->count); + verbprintf("DO_PUT_SAMPLE: c%d, EIP 0x%.8x, pid %.6d, count %.6d\n", + opd_get_counter(sample->count), sample->eip, sample->pid, sample->count); if (opd_eip_is_kernel(sample->eip)) { opd_handle_kernel_sample(sample->eip, sample->count); Index: oprofiled.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/oprofiled.c,v retrieving revision 1.40 retrieving revision 1.41 diff -u -d -r1.40 -r1.41 --- oprofiled.c 2001/09/01 02:03:34 1.40 +++ oprofiled.c 2001/09/06 18:13:28 1.41 @@ -21,6 +21,7 @@ extern u32 ctr_count[OP_MAX_COUNTERS]; extern u8 ctr_event[OP_MAX_COUNTERS]; extern u8 ctr_um[OP_MAX_COUNTERS]; +uint op_nr_counters = 2; static int showvers; int verbose; @@ -51,7 +52,6 @@ static struct poptOption options[] = { { "buffer-size", 'b', POPT_ARG_INT, &opd_buf_size, 0, "nr. of entries in kernel buffer", "num", }, - { "use-cpu", 'p', POPT_ARG_INT, &cpu_type, 0, "0 for PPro, 1 for PII, 2 for PIII, 3 for Athlon", "[0|1|2|3]" }, { "ignore-myself", 'm', POPT_ARG_INT, &ignore_myself, 0, "ignore samples of oprofile driver", "[0|1]"}, { "log-file", 'l', POPT_ARG_STRING, &logfilename, 0, "log file", "file", }, { "base-dir", 'd', POPT_ARG_STRING, &opd_dir, 0, "base directory of daemon", "dir", }, @@ -155,7 +155,8 @@ { poptContext optcon; int ret; - int i, ok; + uint i; + int ok; char c; /* should be sufficient to hold /proc/sys/dev/oprofile/%d/yyyy */ char filename[PATH_MAX + 1]; @@ -165,7 +166,7 @@ c=poptGetNextOpt(optcon); - if (c<-1) { + if (c < -1) { fprintf(stderr, "oprofiled: %s: %s\n", poptBadOption(optcon, POPT_BADOPTION_NOALIAS), poptStrerror(c)); @@ -201,29 +202,24 @@ ctr_um[i]= opd_read_int_from_file(filename); } - cpu_type = opd_read_int_from_file("/proc/sys/dev/oprofile/cpu_type"); - - ok = 1; - /* PHE FIXME : We need to translate cpu_type to a string, see - * cpu_typ_str in op_events.c */ for (i = 0 ; i < op_nr_counters ; ++i) { ret = op_check_events(i, ctr_event[i], ctr_um[i], cpu_type); if (ret & OP_EVT_NOT_FOUND) - fprintf(stderr, "oprofiled: ctr%d: %d: no such event for cpu %d\n", - i, ctr_event[i], cpu_type); + fprintf(stderr, "oprofiled: ctr%d: %d: no such event for cpu %s\n", + i, ctr_event[i], op_get_cpu_type_str(cpu_type)); if (ret & OP_EVT_NO_UM) - fprintf(stderr, "oprofiled: ctr%d: 0x%.2x: invalid unit mask for cpu %d\n", - i, ctr_um[i], cpu_type); + fprintf(stderr, "oprofiled: ctr%d: 0x%.2x: invalid unit mask for cpu %s\n", + i, ctr_um[i], op_get_cpu_type_str(cpu_type)); if (ret & OP_EVT_CTR_NOT_ALLOWED) fprintf(stderr, "oprofiled: ctr%d: %d: can't count event for this counter\n", i, ctr_count[i]); if (ret != OP_EVENTS_OK) - ok = 0; + exit(1); } if (!ok) { @@ -422,6 +418,10 @@ size_t opd_buf_bytesize; struct sigaction act; int i; + + cpu_type = opd_read_int_from_file("/proc/sys/dev/oprofile/cpu_type"); + if (cpu_type == CPU_ATHLON) + op_nr_counters = 4; opd_options(argc, argv); |
From: John L. <mov...@us...> - 2001-09-06 18:13:31
|
Update of /cvsroot/oprofile/oprofile/doc In directory usw-pr-cvs1:/tmp/cvs-serv22397/doc Modified Files: oprofile.sgml Log Message: philippe's cleanup, and several fixes from me. Index: oprofile.sgml =================================================================== RCS file: /cvsroot/oprofile/oprofile/doc/oprofile.sgml,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -r1.23 -r1.24 --- oprofile.sgml 2001/09/04 21:11:00 1.23 +++ oprofile.sgml 2001/09/06 18:13:28 1.24 @@ -63,9 +63,10 @@ </para></listitem> </varlistentry> <varlistentry> - <term>Uniprocessor</term> + <term>Uniprocessor or SMP</term> <listitem><para> - <acronym>SMP</acronym> is currently broken as I don't have a machine to test on ... sorry. + <!-- FIXME: alter this later --> + <acronym>SMP</acronym> machines are supported, but performance is currently worse than the UP case. </para></listitem> </varlistentry> <varlistentry> @@ -78,6 +79,7 @@ <varlistentry> <term>OProfile GUI</term> <listitem><para> + <!-- FIXME: change this if we change to Qt --> The use of the GUI to start the profiler requires : <filename>wish</filename> from the tk package. </para></listitem> </varlistentry> @@ -180,8 +182,7 @@ <para> Will convert from your version to the current version. </para> -<para>Be warned than you cannot convert from new version to old version. If you convert to new version -you cannot reverse the conversion. +<para>Be warned than you cannot convert from the new version to the old version.</para> </sect1> <sect1 id="uninstall"> @@ -334,13 +335,6 @@ </para></listitem> </varlistentry> <varlistentry> - <term><option>--use-cpu</option></term> - <listitem><para> - Specify 0 for Pentium Pros, 1 for Pentium II, 2 for Pentium III and 3 for AMD Athlon/Duron. - <!-- FIXME: is this option necessary ?? --> - </para></listitem> - </varlistentry> - <varlistentry> <term><option>--pid-filter</option></term> <listitem><para> Only samples of this process id will be collected (including any kernel-side samples when this process is in @@ -509,6 +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. </para></listitem> </varlistentry> <varlistentry> @@ -640,6 +636,13 @@ <command>lsmod</command> and similar utilties will still show the module's use count as <constant>-1</constant>. However, this is not to be relied on - the module will become unloadable some short time after stopping profiling. </para> +<para> +Note that by default module unloading is disabled when used on SMP systems. This is because of a small +chance of a module unload race crashing the kernel. As the race is very small, it is allowed to +re-enable the module unload by specifying the "allow_unload" parameter to the module : +</para> +<para><command>modprobe oprofile allow_unload=1</command></para> +<para>This option can be <emphasis>DANGEROUS</emphasis> and should only be used on non-production systems.</para> </sect1> </chapter> @@ -699,7 +702,7 @@ <varlistentry> <term><option>--counter</option></term> <listitem><para> - Which counter (0 or 1) to extract information for. + Which counter (0 - 3) to extract information for. </para></listitem> </varlistentry> <varlistentry> |
From: John L. <mov...@us...> - 2001-09-06 18:13:31
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv22397 Modified Files: ChangeLog op_events.c op_init.c op_user.h oprofile.c oprofile.h Log Message: philippe's cleanup, and several fixes from me. Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.100 retrieving revision 1.101 diff -u -d -r1.100 -r1.101 --- ChangeLog 2001/09/04 21:11:00 1.100 +++ ChangeLog 2001/09/06 18:13:28 1.101 @@ -1,3 +1,38 @@ +2001-09-06 John Levon <mo...@co...> + + * doc/oprofile.sgml: update a bit + +2001-09-06 John Levon <mo...@co...> + + * <most files>: make op_nr_counters a var (no pp support for > 2 yet) + + * dae/oprofiled.c: don't print help when counter event etc. are wrong + +2001-09-06 John Levon <mo...@co...> + + * oprofile.h: + * oprofile.c: use MODULE_LICENSE + +2001-09-06 John Levon <mo...@co...> + + * op_user.h: add missing prototype + + * dae/op_start: fix counter extraction + +2001-09-05 Philippe Elie <ph...@cl...> + + * pp/oprofpp.c: fix a few corner case, cleanup. + * dae/opd_proc: ditto. + + * dae/op_start: better handling of counter number + + * dae/opd_proc: minor change. + + * op_user.h: enable support for four counters + * oprofile.c: ditto. Split functions + + * op_events.c: expose op_get_cpu_type_str(int) to world. + 2001-09-04 John Levon <mo...@co...> * oprofile.h: Index: op_events.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_events.c,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- op_events.c 2001/09/01 02:03:34 1.21 +++ op_events.c 2001/09/06 18:13:28 1.22 @@ -58,6 +58,13 @@ u8 um[7]; }; +static const char* cpu_type_str[MAX_CPU_TYPE] = { + "Pentium Pro", + "PII", + "PIII", + "Athlon" +}; + static struct op_unit_mask op_unit_masks[] = { /* use by the gui */ { 1, utm_mandatory, 0x0f, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, }, @@ -405,6 +412,23 @@ return op_check_events(ctr, *ctr_t, ctr_um, cpu_type); } +/** + * op_get_cpu_type_str - get the cpu string. + * @cpu_type: the cpu type identifier + * + * The function always return a valid const char* + * the core cpu denomination or "invalid cpu type" if + * @cpu_type is not valid. + */ +const char* op_get_cpu_type_str(int cpu_type) +{ + if (cpu_type < 0 || cpu_type > MAX_CPU_TYPE) { + return "invalid cpu type"; + } + + return cpu_type_str[cpu_type]; +} + #ifdef OP_EVENTS_DESC struct op_unit_desc { char *desc[7]; @@ -659,13 +683,6 @@ static int cpu_type = DEFAULT_CPU_TYPE; -static const char* cpu_type_str[MAX_CPU_TYPE] = { - "Pentium Pro", - "PII", - "PIII", - "Athlon" -}; - /** * help_for_event - output event name and description * @i: event number @@ -784,7 +801,7 @@ printf(VERSION_STRING " compiled on " __DATE__ " " __TIME__ "\n"); return 0; } else if (!strcmp(argv[i], "--help")) { - printf("op_help [--version|--cpu-type] event_name"); + printf("op_help [--version|--cpu-type] event_name\n"); return 0; } else if (!strncmp(argv[i], "--cpu-type=", 11)) { Index: op_init.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_init.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -d -r1.6 -r1.7 --- op_init.c 2001/08/19 20:09:17 1.6 +++ op_init.c 2001/09/06 18:13:28 1.7 @@ -20,6 +20,8 @@ EXPORT_NO_SYMBOLS; extern int cpu_type; +extern uint op_nr_counters; +extern int separate_running_bit; static int __init hw_ok(void) { @@ -40,6 +42,11 @@ else cpu_type = (current_cpu_data.x86_model > 5) ? CPU_PIII : (current_cpu_data.x86_model > 2); + + if (cpu_type == CPU_ATHLON) { + op_nr_counters = 4; + separate_running_bit = 1; + } return cpu_type; } Index: op_user.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/op_user.h,v retrieving revision 1.4 retrieving revision 1.5 diff -u -d -r1.4 -r1.5 --- op_user.h 2001/09/01 02:03:34 1.4 +++ op_user.h 2001/09/06 18:13:28 1.5 @@ -22,13 +22,24 @@ #include "version.h" -/* PHE FIXME: op_config.h, typedef it and prefix by op_ ? */ +#ifndef u8 #define u8 unsigned char +#endif +#ifndef u16 #define u16 unsigned short +#endif +#ifndef u32 #define u32 unsigned int +#endif +#ifndef uint #define uint unsigned int +#endif +#ifndef ulong #define ulong unsigned long +#endif +#ifndef fd_t #define fd_t int +#endif /* event check returns */ #define OP_EVENTS_OK 0x0 @@ -69,20 +80,10 @@ * 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 * OP_BITS_CTR! */ -#define OP_MAX_COUNTERS 2 - -/* The real number of counters supported for the running cpu, I define it - * separately to allow using a variable rather a constant so distribution can - * provide a generic binary for oprofile. This need also a few additional - * fixes */ -#define op_nr_counters 2 - -/* IA32 have only one bit to start/stop all counter, AMD have separate bit - * inside each event select MSR */ -#define separate_running_bit 0 +#define OP_MAX_COUNTERS 4 /* the number of bits neccessary to store OP_MAX_COUNTERS values */ -#define OP_BITS_CTR 1 +#define OP_BITS_CTR 2 /* the number of reserved bits in count, + 1 is for the notification bit */ #define OP_BITS (OP_BITS_CTR + 1) @@ -91,7 +92,7 @@ #define OP_BITS_COUNT (16 - OP_BITS) /* counter nr mask */ -#define OP_CTR_MASK ((~0U << OP_BITS_COUNT) >> 1) +#define OP_CTR_MASK ((~0U << (OP_BITS_COUNT + 1)) >> 1) /* top OP_BITS bits of count are used as follows: */ /* is this actually a notification ? */ @@ -164,6 +165,7 @@ /* 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); +const char* op_get_cpu_type_str(int cpu_type); /* not used currently */ 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); Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.81 retrieving revision 1.82 diff -u -d -r1.81 -r1.82 --- oprofile.c 2001/09/04 21:11:00 1.81 +++ oprofile.c 2001/09/06 18:13:28 1.82 @@ -22,6 +22,7 @@ static char *op_version = VERSION_STRING; MODULE_AUTHOR("John Levon (mo...@co...)"); MODULE_DESCRIPTION("Continuous Profiling Module"); +MODULE_LICENSE("GPL"); #ifdef CONFIG_SMP MODULE_PARM(allow_unload, "i"); @@ -48,6 +49,12 @@ static uint perfctr_msr[OP_MAX_COUNTERS]; static uint eventsel_msr[OP_MAX_COUNTERS]; +/* number of counters physically present */ +uint op_nr_counters = 2; + +/* whether we enable for each counter (athlon) or globally (intel) */ +int separate_running_bit; + static u32 prof_on __cacheline_aligned; static int smp_hardware; @@ -308,8 +315,6 @@ /* ugly hack */ my_set_fixmap(); - /* FIXME: NMI delivery for SMP ? */ - /* enable local APIC via MSR. Forgetting this is a fun way to lock the box */ /* IA32 V3, 7.4.2 */ @@ -430,16 +435,12 @@ case CPU_ATHLON: eventsel_msr[0] = MSR_K7_PERFCTL0; eventsel_msr[1] = MSR_K7_PERFCTL1; -/* FIXME ATHLON enable only with OP_MAX_COUNTERS 4 and an athlon to test this eventsel_msr[2] = MSR_K7_PERFCTL2; eventsel_msr[3] = MSR_K7_PERFCTL3; -*/ perfctr_msr[0] = MSR_K7_PERFCTR0; perfctr_msr[1] = MSR_K7_PERFCTR1; -/* FIXME ATHLON ditto perfctr_msr[2] = MSR_K7_PERFCTR2; perfctr_msr[3] = MSR_K7_PERFCTR3; -*/ break; default: eventsel_msr[0] = MSR_IA32_EVNTSEL0; @@ -460,7 +461,7 @@ * all bits are cleared except the reserved bits 21 */ for (i = 0 ; i < op_nr_counters ; ++i) { rdmsr(eventsel_msr[i], low, high); - wrmsr(eventsel_msr[i], low & (1 << 22), high); + wrmsr(eventsel_msr[i], low & (1 << 21), high); /* avoid a false detection of ctr overflow in NMI handler */ wrmsr(perfctr_msr[i], -1, -1); @@ -513,52 +514,74 @@ #endif } -static void pmc_start(void *info) +inline static void pmc_start_P6(void) +{ + uint low,high; + + rdmsr(eventsel_msr[0], low, high); + wrmsr(eventsel_msr[0], low | (1 << 22), high); +} + +inline static void pmc_start_Athlon(void) { uint low,high; int i; + for (i = 0 ; i < op_nr_counters ; ++i) { + if (op_ctr_count[i]) { + rdmsr(eventsel_msr[i], low, high); + wrmsr(eventsel_msr[i], low | (1 << 22), high); + } + } +} + +static void pmc_start(void *info) +{ if (info && (*((uint *)info) != smp_processor_id())) return; /* assert: all enable counter are setup except the bit start/stop, * all counter disable contains zeroes (except perhaps the reserved - * bit 21) */ + * bit 21), counter disable contains -1 sign extended in msr count */ /* enable all needed counter */ - if (separate_running_bit == 0) { - rdmsr(eventsel_msr[0], low, high); - wrmsr(eventsel_msr[0], low | (1 << 22), high); - } else { - for (i = 0 ; i < op_nr_counters ; ++i) { - if (op_ctr_count[i]) { - rdmsr(eventsel_msr[i], low, high); - wrmsr(eventsel_msr[i], low | (1 << 22), high); - } - } - } + if (separate_running_bit == 0) + pmc_start_P6(); + else + pmc_start_Athlon(); } -static void pmc_stop(void *info) +inline static void pmc_stop_P6(void) { uint low,high; + + rdmsr(eventsel_msr[0], low, high); + wrmsr(eventsel_msr[0], low & ~(1 << 22), high); +} + +inline static void pmc_stop_Athlon(void) +{ + uint low,high; int i; + for (i = 0 ; i < op_nr_counters ; ++i) { + if (op_ctr_count[i]) { + rdmsr(eventsel_msr[i], low, high); + wrmsr(eventsel_msr[i], low & ~(1 << 22), high); + } + } +} + +static void pmc_stop(void *info) +{ if (info && (*((uint *)info) != smp_processor_id())) return; /* disable counters */ - if (separate_running_bit == 0) { - rdmsr(eventsel_msr[0], low, high); - wrmsr(eventsel_msr[0], low & ~(1 << 22), high); - } else { - for (i = 0 ; i < op_nr_counters ; ++i) { - if (op_ctr_count[i]) { - rdmsr(eventsel_msr[i], low, high); - wrmsr(eventsel_msr[i], low & ~(1 << 22), high); - } - } - } + if (separate_running_bit == 0) + pmc_stop_P6(); + else + pmc_stop_Athlon(); } inline static void pmc_select_start(uint cpu) @@ -850,11 +873,6 @@ return -EFAULT; } - /* PHE FIXME: this is inefficient if only few counter are - * enable. Some other place in the code must be fixed if we - * allocate only on demand, take care than note currently are - * always put in data[0]->buffer even if the counter 0 is - * disable */ data->buffer = vmalloc(buf_size); if (!data->buffer) { printk(KERN_ERR "oprofile: failed to allocate eviction buffer of %lu bytes\n",buf_size); @@ -880,12 +898,11 @@ uint cpu; int ok; struct _oprof_data *data; - int enabled; + 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"); - enabled = 0; 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); @@ -901,7 +918,7 @@ } if (!enabled) { - printk(KERN_ERR "oprofile: neither counter enabled.\n"); + printk(KERN_ERR "oprofile: no counters have been enabled.\n"); return 0; } @@ -1170,7 +1187,6 @@ static int __init init_sysctl(void) { ctl_table *next = &oprof_table[nr_oprof_static]; - ctl_table *counter_table[op_nr_counters + 1]; ctl_table *tab; int i,j; @@ -1192,7 +1208,6 @@ tab[3] = ((ctl_table){ 1, "unit_mask", &op_ctr_um[i], sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); tab[4] = ((ctl_table){ 1, "kernel", &op_ctr_kernel[i], sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); tab[5] = ((ctl_table){ 1, "user", &op_ctr_user[i], sizeof(int), 0600, NULL, lproc_dointvec, NULL, }); - counter_table[i] = tab; next++; } Index: oprofile.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.h,v retrieving revision 1.49 retrieving revision 1.50 diff -u -d -r1.49 -r1.50 --- oprofile.h 2001/09/04 21:11:00 1.49 +++ oprofile.h 2001/09/06 18:13:28 1.50 @@ -198,6 +198,11 @@ #include <linux/completion.h> #endif +// 2.4.10 introduced MODULE_LICENSE +#ifndef MODULE_LICENSE +#define MODULE_LICENSE(x) +#endif + /* These arrays are filled by hw_ok() */ extern uint perfctr_msr[OP_MAX_COUNTERS]; extern uint eventsel_msr[OP_MAX_COUNTERS]; |
From: John L. <mov...@us...> - 2001-09-04 21:11:03
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv29011 Modified Files: ChangeLog oprofile.c oprofile.h Log Message: a couple of fixes Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.99 retrieving revision 1.100 diff -u -d -r1.99 -r1.100 --- ChangeLog 2001/09/04 17:30:12 1.99 +++ ChangeLog 2001/09/04 21:11:00 1.100 @@ -1,5 +1,11 @@ 2001-09-04 John Levon <mo...@co...> + * oprofile.h: + * oprofile.c: don't restore delivery mode to LVTPC (causes + APIC error on SMP). Fix for silly sem hang with do_dump + +2001-09-04 John Levon <mo...@co...> + * dae/op_start: fix typo bug 2001-09-04 John Levon <mo...@co...> Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.80 retrieving revision 1.81 diff -u -d -r1.80 -r1.81 --- oprofile.c 2001/09/04 12:50:10 1.80 +++ oprofile.c 2001/09/04 21:11:00 1.81 @@ -263,7 +263,8 @@ static void __exit lvtpc_apic_restore(void *dummy) { uint val = apic_read(APIC_LVTPC); - val = SET_APIC_DELIVERY_MODE(val, lvtpc_old_mode[smp_processor_id()]); + // 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 |= APIC_LVT_MASKED; else @@ -1226,13 +1227,7 @@ int can = -EBUSY; down(&sysctlsem); -/* the module unload race can currently only happen on SMP */ -#ifdef CONFIG_SMP - if (!allow_unload) - return -EBUSY; -#endif - - if (!prof_on && !GET_USE_COUNT(THIS_MODULE)) + if (smp_can_unload() && !prof_on && !GET_USE_COUNT(THIS_MODULE)) can = 0; up(&sysctlsem); return can; Index: oprofile.h =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.h,v retrieving revision 1.48 retrieving revision 1.49 diff -u -d -r1.48 -r1.49 --- oprofile.h 2001/09/01 02:03:34 1.48 +++ oprofile.h 2001/09/04 21:11:00 1.49 @@ -172,6 +172,13 @@ struct _descr { u16 limit; u32 base; } __attribute__((__packed__)); struct _idt_descr { u32 a; u32 b; } __attribute__((__packed__)); +/* we can't unload safely on SMP */ +#ifdef CONFIG_SMP +#define smp_can_unload() (allow_unload) +#else +#define smp_can_unload() 1 +#endif + // 2.4.3 introduced rw mmap semaphore #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3) #define take_mmap_sem(mm) down(&mm->mmap_sem) |
From: John L. <mov...@us...> - 2001-09-04 21:11:03
|
Update of /cvsroot/oprofile/oprofile/doc In directory usw-pr-cvs1:/tmp/cvs-serv29011/doc Modified Files: oprofile.sgml Log Message: a couple of fixes Index: oprofile.sgml =================================================================== RCS file: /cvsroot/oprofile/oprofile/doc/oprofile.sgml,v retrieving revision 1.22 retrieving revision 1.23 diff -u -d -r1.22 -r1.23 --- oprofile.sgml 2001/09/04 17:24:09 1.22 +++ oprofile.sgml 2001/09/04 21:11:00 1.23 @@ -27,7 +27,7 @@ <title>Introduction</title> <para> -OProfile is a profiling system for Linux 2.4 systems on P6 processors. It is capable of profiling +OProfile is a profiling system for Linux 2.4 systems on most x86 processors. It is capable of profiling all parts of a running system, from the kernel (including modules and interrupt handlers) to shared libraries to binaries. It runs transparently in the background collecting information at a low overhead. These features make it ideal for profiling entire systems in production environments to determine bottle |
From: John L. <mov...@us...> - 2001-09-04 17:30:15
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv4158/dae Modified Files: op_start Log Message: s/CPU_TYPE/CPUTYPE in op_start Index: op_start =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_start,v retrieving revision 1.37 retrieving revision 1.38 diff -u -d -r1.37 -r1.38 --- op_start 2001/09/01 02:03:34 1.37 +++ op_start 2001/09/04 17:30:12 1.38 @@ -272,7 +272,7 @@ f=0 while (( $f < $OP_MAX_COUNTERS )); do if [[ ${#CTR_EVENT[$f]} != 0 ]]; then - CTR_EVENT_VAL[$f]=`op_help --cpu-type=$CPU_TYPE ${CTR_EVENT[$f]}` + CTR_EVENT_VAL[$f]=`op_help --cpu-type=$CPUTYPE ${CTR_EVENT[$f]}` if [ -z "${CTR_EVENT_VAL[$f]}" -a ! -z "${CTR_EVENT[$f]}" ]; then echo "Unknown event \"${CTR_EVENT[$f]}\"" exit 1 |
From: John L. <mov...@us...> - 2001-09-04 17:30:14
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv4158 Modified Files: ChangeLog Log Message: s/CPU_TYPE/CPUTYPE in op_start Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.98 retrieving revision 1.99 diff -u -d -r1.98 -r1.99 --- ChangeLog 2001/09/04 17:24:09 1.98 +++ ChangeLog 2001/09/04 17:30:12 1.99 @@ -1,5 +1,9 @@ 2001-09-04 John Levon <mo...@co...> + * dae/op_start: fix typo bug + +2001-09-04 John Levon <mo...@co...> + * doc/oprofile.sgml: some small tidies 2001-09-04 John Levon <mo...@co...> |
From: John L. <mov...@us...> - 2001-09-04 17:24:13
|
Update of /cvsroot/oprofile/oprofile/doc In directory usw-pr-cvs1:/tmp/cvs-serv2445/doc Modified Files: oprofile.sgml Log Message: doc tidies Index: oprofile.sgml =================================================================== RCS file: /cvsroot/oprofile/oprofile/doc/oprofile.sgml,v retrieving revision 1.21 retrieving revision 1.22 diff -u -d -r1.21 -r1.22 --- oprofile.sgml 2001/08/20 20:05:19 1.21 +++ oprofile.sgml 2001/09/04 17:24:09 1.22 @@ -3,7 +3,7 @@ <book id="oprofile-guide"> <bookinfo> <title>OProfile manual</title> - + <authorgroup> <author> <firstname>John</firstname> @@ -56,25 +56,23 @@ <term>Intel P6 processor or AMD Athlon/Duron.</term> <listitem><para> A CPU with a P6 generation core is required. In marketing terms this translates to anything between an Intel - Pentium Pro (NOT Pentium Classics) and a Pentium III. Specifically, Pentium IVs are not yet supported due to - different hardware. + Pentium Pro (NOT Pentium Classics) and a Pentium III, including all Celerons. + Pentium IVs are not yet supported due to different hardware. Also note that Mobile P6 processors lack the necessary CPU features and are also not supported. - The AMD Athlon & Duron CPUs are also supported, as their <acronym>APIC</acronym> and performance counters - are very similar. These CPUs offer 4 seperate counters as opposed to the 2 provided by the Intel P6 family. - OProfile currently only supports using 2 of these available counters. + The AMD Athlon & Duron CPUs are also supported. </para></listitem> </varlistentry> <varlistentry> <term>Uniprocessor</term> <listitem><para> <acronym>SMP</acronym> is currently broken as I don't have a machine to test on ... sorry. - </para></listitem> + </para></listitem> </varlistentry> <varlistentry> <term>Required libraries</term> <listitem><para> These libraries are required : <filename>popt</filename>, <filename>bfd</filename>, - <filename>liberty</filename>, <filename>dl</filename> + <filename>liberty</filename>, <filename>dl</filename> </para></listitem> </varlistentry> <varlistentry> @@ -97,7 +95,7 @@ </varlistentry> </variablelist> </para> - + </sect1> <sect1 id="resources"> @@ -107,7 +105,7 @@ <varlistentry> <term>Web page</term> <listitem><para> - There is a web page (which you may be reading now) at + There is a web page (which you may be reading now) at <ulink url="http://oprofile.sf.net/">http://oprofile.sf.net/</ulink>. </para></listitem> </varlistentry> @@ -160,7 +158,7 @@ of writing, the second is only available in the ac series, but is to be preferred). </para> -</sect1> +</sect1> <sect1 id="upgrading"> <title>Upgrading the version of oprofile</title> @@ -169,10 +167,10 @@ </para> <para> Oprofile does not guarantee that the file format of samples is compatible with the format in older versions. -If you want to keep old sample files you need to use the <command>oprof_convert</command> utility. +If you want to keep old sample files you need to use the <command>oprof_convert</command> utility. In any case you should backup your old sample files before processing the files in case something bad occurs. This processing is not needed for all version changes - for now the only conversion needed -is between the alpha 0.0.3 version and 0.0.4 or above. If no conversion is needed <command>oprof_convert</command> does +is between the alpha 0.0.3 version and 0.0.4 or above. If no conversion is needed <command>oprof_convert</command> does nothing (successfully). </para> <para><command>oprof_convert</command> usage :</para> @@ -193,43 +191,43 @@ remove all installed file except your configuration file in the directory <filename>~/.oprofile</filename> </para> </sect1> - + </chapter> <chapter id="usage"> <title>Usage</title> - + <sect1 id="typical"> <title>A typical session</title> <para> Before getting into detail about usage, it's probably a good idea to have a quick stroll through an example -session. -</para> -<para> -First we need to start the profiler running in the background. We need to pass the correct <filename>System.map</filename> +session (this example is for Intel processors not AMD). +</para> +<para> +First we need to start the profiler running in the background. We need to pass the correct <filename>System.map</filename> and <filename>vmlinux</filename> files to the daemon, and we need to specify what event to count and the counter value. Here I've started with : </para> <para><command>op_start --map-file=/boot/2.4.0ac12/System.map --vmlinux=/boot/2.4.0ac12/vmlinux --ctr0-event=CPU_CLK_UNHALTED --ctr0-count=600000</command></para> <para> -A quick <command>ps ax</command> confirms that the daemon (<command>oprofiled</command>) has started, +A quick <command>ps ax</command> confirms that the daemon (<command>oprofiled</command>) has started, along with the kernel thread (<command>oprof-thread</command>). Data is now being collected in the kernel. -Now we can do whatever we like ... although in this case I'm profiling the C++ application +Now we can do whatever we like ... although in this case I'm profiling the C++ application <ulink url="http://www.lyx.org/">LyX</ulink>, previously compiled using the <option>-g</option> option to <command>g++</command>. Note that unlike <command>gprof</command>, no instrumentation (<option>-pg</option> and <option>-a</option> options to <command>gcc</command>) -is necessary. This is major factor in achieving the low overhead of OProfile. +is necessary. This is major factor in achieving the low overhead of OProfile. </para> <para> -Anyway, data will be processed by daemon every ten minutes. I'm too lazy to wait that long, so force the issue with : +Rather than wait for the buffers to fill up, I now force the profiling data to be processed with : </para> <para><command>op_dump</command></para> -<para> +<para> which will ask the kernel module to dump as much data as it can to the daemon. <note> <para>Forcing a dump like this can cause the daemon to become very busy, especially the first time it is done. Don't worry, -that's not normal behaviour; so if you are profiling over a larger period of time, such spikes won't appear. +that's not normal behaviour; so if you are profiling over a larger period of time, such spikes won't appear. </para> -</note> +</note> I can now ask for a symbol-based summary of the sample profile : </para> @@ -238,19 +236,19 @@ You will have to specify the full path unless you also specify the sample file (see the manpage). This can be quite slow on large binaries, so sit tight. As it's a C++ program, I asked for the symbols to be demangled to a readable form. Examining the file will give the symbols against which the most hits were registered. In this case I got : -</para> +</para> <para> <!-- is DocBook really this shit ? Can't be ... literallayout class="Monospaced" just doesn't work for me ... --> <computeroutput> -<literallayout> +<literallayout> ... Row::par(void)[0x0813ab54]: 5.4079% (472 samples) LyXText::GetRow(LyXParagraph *, int, int &) const[0x08170a4c]: 5.5683% (486 samples) LyXParagraph::GetFontSettings(BufferParams const &, int) const[0x08145420]: 5.7516% (502 samples) Row::next(void) const[0x0813ac24]: 15.4904% (1352 samples) -</literallayout> +</literallayout> </computeroutput> -</para> +</para> <para> at the top. Note that over a longer run (or with a lower ctr0-count value) the number of samples will be much more statistically reliable. Note that these sample counts do <emphasis>not</emphasis> necessarily reflect the relative amounts of time @@ -262,17 +260,17 @@ <para> If you're more used to <command>gprof</command> style profile output, you can use <command>oprofpp -g gmon.out</command> and then <command>gprof -p binary</command> to get flat profiles. OProfile does not (cannot) support the call graph -feature of <command>gprof</command>. +feature of <command>gprof</command>. </para> -</note> -</para> - +</note> +</para> + </sect1> - + <sect1 id="starting-daemon"> -<title>Starting profiling from the <command>op_start</command> script</title> +<title>Starting profiling from the <command>op_start</command> script</title> <para> -In this section the configuration and startup of the profiler is discussed in more depth. +In this section the configuration and startup of the profiler is discussed in more depth. </para> <para> A shell script <command>op_start</command> is provided to set up the correct environment, insert the kernel module, @@ -285,8 +283,8 @@ on-disk size). Each filename corresponds to the profiled binary image (with <constant>/</constant> characters replaced with <constant>}</constant> characters). The man page for <command>op_start</command> details the all the options, only interesting ones are listed here : -</para> -<para> +</para> +<para> <variablelist> <varlistentry> <term><option>--list-events</option></term> @@ -300,7 +298,7 @@ <listitem><para> This is the number of entries in the kernel-side profiling buffer. Generally the default value is fine: you might want to change this on low-memory machines, or if you are doing very detailed profiling. - Each entry in the buffer takes 8 bytes. + Each entry in the buffer takes 8 bytes. </para></listitem> </varlistentry> <varlistentry> @@ -339,7 +337,7 @@ <term><option>--use-cpu</option></term> <listitem><para> Specify 0 for Pentium Pros, 1 for Pentium II, 2 for Pentium III and 3 for AMD Athlon/Duron. - This is only needed if you use an event not available on the Pentium Pro. + <!-- FIXME: is this option necessary ?? --> </para></listitem> </varlistentry> <varlistentry> @@ -361,24 +359,24 @@ <listitem><para> This makes the daemon <emphasis>very</emphasis> verbose in its logfile. Don't use this unless you need it as the overhead of logging the data is significant. It is however useful for determining profiler bugs - (believe me ;) + (believe me ;) </para></listitem> </varlistentry> </variablelist> </para> -<para> +<para> As mentioned, the runtime profiler system consists of two components: a kernel module (<filename>oprofile</filename>) and a user-space daemon process (<filename>oprofiled</filename>). The kernel module collects sample data into the hash table and buffer, and wakes up the daemon process when it is approaching full. The daemon will read this -data, and process it into a non-volatile form. Any samples are recorded into the sample files at processing time. -</para> +data, and process it into a non-volatile form. Any samples are recorded into the sample files at processing time. +</para> <para> The <command>op_start</command> shell script will insert the kernel module if needed. The profiling is activated when the daemon process initialises. Configuration of the kernel module parameters is done via <command>sysctl</command>; the available files are detailed in <xref linkend="sysctl">. </para> - + <sect2 id="hardware-counters"> <title>Intel P6 Performance Counters</title> <para> @@ -386,15 +384,15 @@ from <ulink url="http://developer.intel.com/">http://developer.intel.com/</ulink>. The AMD Athlon/Duron implementation is detailed in <ulink url="http://www.amd.com/products/cpg/athlon/techdocs/pdf/22007.pdf"> http://www.amd.com/products/cpg/athlon/techdocs/pdf/22007.pdf</ulink>. -P6-core processors are capable of delivering an interrupt to the local <acronym>APIC</acronym> <acronym>LVTPC</acronym> +These processors are capable of delivering an interrupt to the local <acronym>APIC</acronym> <acronym>LVTPC</acronym> vector when a counter overflows. This is the basic mechanism on which OProfile is based. The kernel module installs an interrupt handler for this vector. The delivery mode is set to <acronym>NMI</acronym> so that blocking interrupts in the kernel does not prevent profiling. When the interrupt handler is called, -the current <acronym>EIP</acronym> <acronym>PC</acronym> value, process id, and counter (there are only -two counters, 0 and 1) are recorded into the profiling structure. This allows the overflow event to be attached -to a specific assembly instruction in a binary image. The daemon is necessary to transform these recorded +the current <acronym>EIP</acronym> <acronym>PC</acronym> value, process id, and counter +are recorded into the profiling structure. This allows the overflow event to be attached +to a specific assembly instruction in a binary image. The daemon is necessary to transform these recorded values into a count against a file offset for a given binary image, in order to produce profile data off-line -at a later time. +at a later time. </para> <para> If we use an event such as <constant>CPU_CLK_UNHALTED</constant> or <constant>INST_RETIRED</constant>, we can @@ -404,8 +402,8 @@ <para> However there are several caveats. Firstly there are those issues listed in the Intel manual. There is a delay between the counter overflow and the interrupt delivery that can skew results on a small scale - this means -you cannot rely on the profiles at the instruction level, except as a binary was/wasn't executed indicator. -If you are using an "event-mode" counter such as the cache counters, a count registered against it doesn't mean +you cannot rely on the profiles at the instruction level, except as a binary was/wasn't executed indicator. +If you are using an "event-mode" counter such as the cache counters, a count registered against it doesn't mean that it is responsible for that event. However, it implies that the counter overflowed in the dynamic vicinity of that instruction, to within a few instructions. Further details on this problem can be found in the Digital paper "ProfileMe: A Hardware Performance Counter". Also note that a very high number of interrupts @@ -422,19 +420,22 @@ </para> <para> So you must specify a counter value with the <option>--ctrX-count</option> option, where <option>X</option> -is either 0 or 1 for which counter to program. After each overflow event, the counter will be re-initialised +is the logical counter number in the range 0-3 (0-1 for Intel processors, which only have two counters). +Using multiple counters is useful for profiling several aspects of the same running program. +After each overflow event, the counter will be re-initialised such that another overflow will occur after this many events have been counted. Picking a good value for this parameter is, unfortunately, somewhat of a grey art (not quite black). It is of course dependent on the event -you have chosen. For basic time-based profiling, you will probably use <constant>CPU_CLK_UNHALTED</constant>. +you have chosen. For basic time-based profiling, you will probably use <constant>CPU_CLK_UNHALTED</constant> +(on Intel). You can estimate how many interrupts this value will generate per second with this event by dividing your CPU clock rate by the chosen value. I have a 600MHz Celeron, so specifying an overflow value of 100,000 will generate around 600 interrupts per second. Specifying too large a value will mean not enough interrupts are generated to give a realistic profile (though this problem can be ameliorated by profiling for <emphasis>longer</emphasis>). Specifying too small a value can lead to overflow problems discussed previously. </para> - + </sect2> - + <sect2 id="sysctl"> <title><command>sysctl</command> tree</title> <para> @@ -450,31 +451,31 @@ <varlistentry> <term><filename>bufsize</filename></term> <listitem><para> - The buffer size, corresponding to the <option>--buffer-size</option> option. + The buffer size, corresponding to the <option>--buffer-size</option> option. </para></listitem> </varlistentry> <varlistentry> <term><filename>hashsize</filename></term> <listitem><para> - The hash table size, corresponding to the <option>--hash-table-size</option> option. + The hash table size, corresponding to the <option>--hash-table-size</option> option. </para></listitem> </varlistentry> <varlistentry> <term><filename>kernel_only</filename></term> <listitem><para> - Corresponding to the <option>--kernel-only</option> option. + Corresponding to the <option>--kernel-only</option> option. </para></listitem> </varlistentry> <varlistentry> <term><filename>pgrp_filter</filename></term> <listitem><para> - Corresponding to the <option>--pgrp-filter</option> option. + Corresponding to the <option>--pgrp-filter</option> option. </para></listitem> </varlistentry> <varlistentry> <term><filename>pid_filter</filename></term> <listitem><para> - Corresponding to the <option>--pid-filter</option> option. + Corresponding to the <option>--pid-filter</option> option. </para></listitem> </varlistentry> <varlistentry> @@ -488,51 +489,51 @@ <term><filename>0, 1, ...</filename></term> <listitem><para> Each counter will have a directory containing files for that counter's settings. - The rest of the files described here are per-counter. + The rest of the files described here are per-counter. </para></listitem> </varlistentry> <varlistentry> <term><filename>count</filename></term> <listitem><para> - The counter value for this counter. + The counter value for this counter. </para></listitem> </varlistentry> <varlistentry> <term><filename>enabled</filename></term> <listitem><para> - Whether this counter is active. + Whether this counter is active. </para></listitem> </varlistentry> <varlistentry> <term><filename>event</filename></term> <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> + </para><para><command>echo `op_help CPU_CLK_UNHALTED` >/proc/sys/dev/oprofile/0/0/event</command> </para></listitem> </varlistentry> <varlistentry> <term><filename>kernel</filename></term> <listitem><para> - Whether to profile the kernel. + Whether to profile the kernel. </para></listitem> </varlistentry> <varlistentry> <term><filename>unit_mask</filename></term> <listitem><para> - The unit mask specified. + The unit mask specified. </para></listitem> </varlistentry> <varlistentry> <term><filename>user</filename></term> <listitem><para> - Whether to profile user-space. + Whether to profile user-space. </para></listitem> </varlistentry> -</variablelist> +</variablelist> </para> - + </sect2> - + </sect1> <sect1 id="oprofile-gui"> @@ -587,25 +588,25 @@ <title>Misuse of <command>oprofile</command> and stability of system</title> <para> OProfile is a low-level profiler which allow continuous profiling with a low-overhead cost. -If not used carefully, this can affect the stability of the system. +If not used carefully, this can affect the stability of the system. If too low a count reset value is set for a counter, the system can become overloaded with counter -interrupts, and seem as if the system has frozen. +interrupts, and seem as if the system has frozen. </para> <note><para> This can happen as follows: When the profiler count reaches zero an NMI handler is called which stores the sample values in an internal buffer, then resets the counter to its original value. If the count is very low, a pending NMI can be sent before the NMI handler has completed. Due to the priority of the NMI, the local APIC delivers the pending interrupt immediately after -completion of the previous interrupt handler, and control never returns to other parts of the system. +completion of the previous interrupt handler, and control never returns to other parts of the system. In this way the system seems to be frozen. </para></note> <para>If this happens, it will be impossible to bring the system back to a workable state. There is no way to provide real security against this happening, other than making sure to use a reasonable value for the counter reset. For example, setting CPU_CLK_UNHALTED event type with a ridiculously low reset count (e.g. 500) is likely to freeze the system. -</para> +</para> <para> -In short : <command>Don't try a foolish sample count value.</command> Unfortunately the definition of a foolish value +In short : <command>Don't try a foolish sample count value.</command> Unfortunately the definition of a foolish value is really dependent on the event type - if ever in doubt, e-mail <address><email>opr...@li...</email></address>. </para> <para>Do I hear you shout "but my event value is low, but not stupid !" ? Yes, this can be the case. In these @@ -616,10 +617,10 @@ </sect1> </chapter> - + <chapter id="features"> <title>Other features</title> - + <sect1 id="pidpgrpfilter"> <title>pid/pgrp filter</title> <para>There are situations where you are only interested in the profiling results of a particular @@ -628,7 +629,7 @@ options to <command>op_start</command>, or by setting the relevant sysctls as mentioned in <xref linkend="sysctl">. </para> </sect1> - + <sect1 id="unloadable"> <title>Unloadable kernel module</title> <para> @@ -639,10 +640,10 @@ <command>lsmod</command> and similar utilties will still show the module's use count as <constant>-1</constant>. However, this is not to be relied on - the module will become unloadable some short time after stopping profiling. </para> -</sect1> +</sect1> </chapter> - + <chapter id="results"> <title>Obtaining and interpreting results</title> <para> @@ -665,13 +666,13 @@ with symbols show up in <filename>/proc/ksyms</filename>). </para> <sect1 id="post-profiler"> -<title><command>oprofpp</command> usage</title> +<title><command>oprofpp</command> usage</title> <para> Oprofpp can be used in three major modes; list symbol mode, detailed symbol mode, or <command>gprof</command> mode. The first gives sorted histogram output of sample counts against functions as shown in the walkthrough. The second can show individual sample counts against instructions inside a function, useful for detailed profiling, whilst the third mode is handy if you're used to <command>gprof</command> style output. Note that only flat <command>gprof</command> -profiles are supported, however. +profiles are supported, however. </para> <para> Some interesting options of the post-processor : @@ -680,65 +681,65 @@ <term><option>--samples-file</option></term> <listitem><para> The samples file to use. This is not necessary, as it can be derived from the filename of the - absolute-path-specified binary image. - </para></listitem> - </varlistentry> + absolute-path-specified binary image. + </para></listitem> + </varlistentry> <varlistentry> <term><option>--image-file</option></term> <listitem><para> - The binary image (shared library, kernel vmlinux, or program) to produce data for. - </para></listitem> - </varlistentry> + The binary image (shared library, kernel vmlinux, or program) to produce data for. + </para></listitem> + </varlistentry> <varlistentry> <term><option>--demangle</option></term> <listitem><para> Demangle C++ symbol names. - </para></listitem> - </varlistentry> + </para></listitem> + </varlistentry> <varlistentry> <term><option>--counter</option></term> <listitem><para> - Which counter (0 or 1) to extract information for. - </para></listitem> - </varlistentry> + Which counter (0 or 1) to extract information for. + </para></listitem> + </varlistentry> <varlistentry> <term><option>--list-symbols</option></term> <listitem><para> List a histogram of sample counts against symbols. - </para></listitem> - </varlistentry> + </para></listitem> + </varlistentry> <varlistentry> <term><option>--list-symbol</option></term> <listitem><para> - Provide a detailed listing for the specified symbol. A future release should allow a full source annotation facility, but not now, Bernard. - </para></listitem> - </varlistentry> + Provide a detailed listing for the specified symbol. A future release should allow a full source annotation facility, but not now, Bernard. + </para></listitem> + </varlistentry> <varlistentry> <term><option>--dump-gprof-file</option></term> <listitem><para> Dump output to the specified file in <command>gprof</command> format. If you specify <filename>gmon.out</filename>, - you can then call <command>gprof -p <binary></command>. - </para></listitem> - </varlistentry> + you can then call <command>gprof -p <binary></command>. + </para></listitem> + </varlistentry> <varlistentry> <term><option>--list-all-symbols-details</option></term> <listitem><para> Provide a detailed listing for all symbols. - </para></listitem> - </varlistentry> + </para></listitem> + </varlistentry> <varlistentry> <term><option>--output-linenr-info</option></term> <listitem><para> Add filename::linenr info for all samples, usable only with --list-all-symbols-details. - </para></listitem> - </varlistentry> -</variablelist> -</para> - -</sect1> + </para></listitem> + </varlistentry> +</variablelist> +</para> + +</sect1> <sect1 id="op-to-source"> -<title><command>op_to_source</command> usage</title> +<title><command>op_to_source</command> usage</title> <para> <command>op_to_source</command> generates annotated source files or assembly listings optionally mixed with source. The op_to_source utility is actually a wrapper script around the opf_filter application. @@ -753,7 +754,7 @@ <xref linkend="interpreting"> about these problems. </para> <para> -The option allowed are : +The options allowed are : <variablelist> <varlistentry> <term><option>--assembly</option></term> @@ -767,14 +768,14 @@ <term><option>--source-with-assembly</option></term> <listitem><para> Output assembly code mixed with the source file, imply <option>--assembly</option>. - </para></listitem> + </para></listitem> </varlistentry> <varlistentry> <term><option>--sort-by-counter counter_nr</option></term> <listitem><para> Sort by decreasing number of samples on counter_nr. For assembly output this option provide only a filtering and not a sort order. - </para></listitem> + </para></listitem> </varlistentry> <varlistentry> <term><option>--with-more-than-samples percent_samples</option></term> @@ -789,20 +790,20 @@ <listitem><para> Output source file or assembly symbol until the amount of samples outputted reach percent_samples. See the note above. Can not be combined with <option>--with-more-than-samples</option>. - </para></listitem> + </para></listitem> </varlistentry> <varlistentry> <term><option>--samples-file</option></term> <listitem><para> Specify the samples file. At least one of the <option>--samples-file</option> or <option>--image-file</option> must be specifed. - </para></listitem> + </para></listitem> </varlistentry> <varlistentry> <term><option>--image-file</option></term> <listitem><para> Specify the image file. - </para></listitem> + </para></listitem> </varlistentry> </variablelist> </para> @@ -819,18 +820,18 @@ instruction-level profiling. However, for almost all circumstances the data can be useful. Ideally a utility such as Intel's VTUNE would be available to allow careful instruction-level analysis; go hassle Intel for this, not me ;) -</para> -</sect1> +</para> +</sect1> </chapter> <chapter id="overhead"> <title>Profiling overhead</title> -<para> +<para> One of the major design criteria for OProfile was low overhead. In many cases profiling is hardly noticeable in terms of overhead (I regularly leave it turned on all the time). It achieves this by judicious use of kernel-side data structures to reduce the analysis overhead to a bare runtime minimum. There are several things -that unfortunately complicate the issue, so there are cases where the overhead is +that unfortunately complicate the issue, so there are cases where the overhead is noticeable. </para> <para> @@ -841,18 +842,18 @@ data is presented in the source distribution. In fact most situations have much fewer numbers of processes, leading to far better performance. </para> -<para>Some graphs of performance characteristics of oprofile are available on the website - - see <xref linkend="resources">. -</para> +<para>Some graphs of performance characteristics of oprofile are available on the website + - see <xref linkend="resources">. +</para> </chapter> <chapter id="ack"> <title>Acknowledgments</title> <para> Thanks to (in no particular order) : Arjan van de Ven, Rik van Riel, Juan Quintela, Philippe Elie, -Phillipp Rumpf, Tigran Aivazian, Alex Brown, Alisdair Rawsthorne, Bob Montgomery, -Dave Jones, Charles Filtness; and finally Pulp, for "Intro". +Phillipp Rumpf, Tigran Aivazian, Alex Brown, Alisdair Rawsthorne, Bob Montgomery, Ray Bryant, +Dave Jones, Charles Filtness; and finally Pulp, for "Intro". </para> -</chapter> - +</chapter> + </book> |
From: John L. <mov...@us...> - 2001-09-04 17:24:13
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv2445 Modified Files: ChangeLog Log Message: doc tidies Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.97 retrieving revision 1.98 diff -u -d -r1.97 -r1.98 --- ChangeLog 2001/09/04 12:50:10 1.97 +++ ChangeLog 2001/09/04 17:24:09 1.98 @@ -1,5 +1,9 @@ 2001-09-04 John Levon <mo...@co...> + * doc/oprofile.sgml: some small tidies + +2001-09-04 John Levon <mo...@co...> + * oprofile.c: change lvtpc_apic_restore to be more careful ! 2001-09-02 John Levon <mo...@co...> @@ -80,7 +84,7 @@ * oprofile.h: * pp/oprofpp.c: * pp/oprofpp.h: reflects caller/prototype, lot of changes. - + 2001-08-31 John Levon <mo...@co...> * Makefile.in: @@ -102,7 +106,7 @@ 2001-08-19 John Levon <mo...@co...> * dae/op_start: handle celeries in cpu type - + 2001-08-19 John Levon <mo...@co...> * op_init.c: |
From: John L. <mov...@us...> - 2001-09-04 12:50:13
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv13179/dae Modified Files: opd_proc.c Log Message: fix for lvtpc_apic_restore Index: opd_proc.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/opd_proc.c,v retrieving revision 1.66 retrieving revision 1.67 diff -u -d -r1.66 -r1.67 --- opd_proc.c 2001/09/02 00:32:28 1.66 +++ opd_proc.c 2001/09/04 12:50:10 1.67 @@ -472,7 +472,6 @@ counter = opd_get_counter(count); sample_file = &image->sample_files[counter]; - printf("counter %d\n", counter); if (sample_file->fd < 1) { opd_open_sample_file(image, counter); if (sample_file->fd < 1) { |
From: John L. <mov...@us...> - 2001-09-04 12:50:13
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv13179 Modified Files: ChangeLog oprofile.c Log Message: fix for lvtpc_apic_restore Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.96 retrieving revision 1.97 diff -u -d -r1.96 -r1.97 --- ChangeLog 2001/09/02 14:34:44 1.96 +++ ChangeLog 2001/09/04 12:50:10 1.97 @@ -1,3 +1,7 @@ +2001-09-04 John Levon <mo...@co...> + + * oprofile.c: change lvtpc_apic_restore to be more careful ! + 2001-09-02 John Levon <mo...@co...> * oprofile.c: don't allow unload on SMP unless allow_unload Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.79 retrieving revision 1.80 diff -u -d -r1.79 -r1.80 --- oprofile.c 2001/09/02 14:34:44 1.79 +++ oprofile.c 2001/09/04 12:50:10 1.80 @@ -241,7 +241,8 @@ #endif } -static uint old_lvtpc[NR_CPUS]; +static uint lvtpc_old_mask[NR_CPUS]; +static uint lvtpc_old_mode[NR_CPUS]; static void __init lvtpc_apic_setup(void *dummy) { @@ -249,17 +250,25 @@ /* set up LVTPC as we need it */ /* IA32 V3, Figure 7.8 */ - old_lvtpc[smp_processor_id()] = val = apic_read(APIC_LVTPC); + val = apic_read(APIC_LVTPC); + lvtpc_old_mask[smp_processor_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); val = SET_APIC_DELIVERY_MODE(val, APIC_MODE_NMI); apic_write(APIC_LVTPC, val); } static void __exit lvtpc_apic_restore(void *dummy) { - apic_write(APIC_LVTPC, old_lvtpc[smp_processor_id()]); + uint val = apic_read(APIC_LVTPC); + val = SET_APIC_DELIVERY_MODE(val, lvtpc_old_mode[smp_processor_id()]); + if (lvtpc_old_mask[smp_processor_id()]) + val |= APIC_LVT_MASKED; + else + val &= ~APIC_LVT_MASKED; + apic_write(APIC_LVTPC, val); } static int __init apic_needs_setup(void) |
From: John L. <mov...@us...> - 2001-09-02 14:34:46
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv21339 Modified Files: ChangeLog oprofile.c Log Message: don't unload on SMP Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.95 retrieving revision 1.96 diff -u -d -r1.95 -r1.96 --- ChangeLog 2001/09/02 01:08:45 1.95 +++ ChangeLog 2001/09/02 14:34:44 1.96 @@ -1,5 +1,10 @@ 2001-09-02 John Levon <mo...@co...> + * oprofile.c: don't allow unload on SMP unless allow_unload + is set. Still needs docs (no point till SMP works). + +2001-09-02 John Levon <mo...@co...> + * dae/op_dump: complain if not root more clearly. 2001-09-02 John Levon <mo...@co...> Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.78 retrieving revision 1.79 diff -u -d -r1.78 -r1.79 --- oprofile.c 2001/09/02 00:38:04 1.78 +++ oprofile.c 2001/09/02 14:34:44 1.79 @@ -23,6 +23,12 @@ MODULE_AUTHOR("John Levon (mo...@co...)"); MODULE_DESCRIPTION("Continuous Profiling Module"); +#ifdef CONFIG_SMP +MODULE_PARM(allow_unload, "i"); +MODULE_PARM_DESC(allow_unload, "Allow module to be unloaded on SMP"); +static int allow_unload; +#endif + /* sysctl settables */ static int op_hash_size=OP_DEFAULT_HASH_SIZE; static int op_buf_size=OP_DEFAULT_BUF_SIZE; @@ -1211,6 +1217,12 @@ int can = -EBUSY; down(&sysctlsem); +/* the module unload race can currently only happen on SMP */ +#ifdef CONFIG_SMP + if (!allow_unload) + return -EBUSY; +#endif + if (!prof_on && !GET_USE_COUNT(THIS_MODULE)) can = 0; up(&sysctlsem); |
From: John L. <mov...@us...> - 2001-09-02 01:08:48
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv23855/dae Modified Files: op_dump Log Message: small improvement to op_dump Index: op_dump =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/op_dump,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- op_dump 2001/08/11 01:45:54 1.1 +++ op_dump 2001/09/02 01:08:45 1.2 @@ -2,8 +2,13 @@ # useful for dumping ... -if [ ! -f /proc/sys/dev/oprofile/dump ]; then +if [ ! -d /proc/sys/dev/oprofile ]; then echo "You must have the oprofile module loaded to dump data." + exit 1 +fi + +if [ ! -w /proc/sys/dev/oprofile/dump ]; then + echo "Must be root." exit 1 fi |
From: John L. <mov...@us...> - 2001-09-02 01:08:48
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv23855 Modified Files: ChangeLog Log Message: small improvement to op_dump Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.94 retrieving revision 1.95 diff -u -d -r1.94 -r1.95 --- ChangeLog 2001/09/02 00:38:04 1.94 +++ ChangeLog 2001/09/02 01:08:45 1.95 @@ -1,5 +1,9 @@ 2001-09-02 John Levon <mo...@co...> + * dae/op_dump: complain if not root more clearly. + +2001-09-02 John Levon <mo...@co...> + * oprofile.c: remove bogus setting for NMI oopser. smp_apic_restore() -> lvtpc_apic_restore() |
From: John L. <mov...@us...> - 2001-09-02 00:38:07
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv15911 Modified Files: ChangeLog oprofile.c Log Message: remove bogus code Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.93 retrieving revision 1.94 diff -u -d -r1.93 -r1.94 --- ChangeLog 2001/09/02 00:32:28 1.93 +++ ChangeLog 2001/09/02 00:38:04 1.94 @@ -1,3 +1,8 @@ +2001-09-02 John Levon <mo...@co...> + + * oprofile.c: remove bogus setting for NMI oopser. + smp_apic_restore() -> lvtpc_apic_restore() + 2001-09-01 Philippe Elie <ph...@cl...> * oprofile.c: fix pmc_setup() Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.77 retrieving revision 1.78 diff -u -d -r1.77 -r1.78 --- oprofile.c 2001/09/02 00:32:28 1.77 +++ oprofile.c 2001/09/02 00:38:04 1.78 @@ -251,7 +251,7 @@ apic_write(APIC_LVTPC, val); } -static void __exit smp_apic_restore(void *dummy) +static void __exit lvtpc_apic_restore(void *dummy) { apic_write(APIC_LVTPC, old_lvtpc[smp_processor_id()]); } @@ -495,18 +495,6 @@ wrmsr(eventsel_msr[1], low, high); } #endif - - /* disable ctr1 if the UP oopser might be on, but we can't do anything - * interesting with the NMIs - */ - /* PHE FIXME ATHLON bugged if running 3/4 counters ?, I really don't - * understand when and why this is executed */ - /* this is pretty bogus really. especially as we don't re-enable it. - * Instead, save state set up, and restore with pmc_unsetup or similar */ -#if !defined(CONFIG_X86_UP_APIC) || !defined(OP_EXPORTED_DO_NMI) - /* PHE FIXME: on my config this start counter 1 with the new code */ -// wrmsr(eventsel_msr[1], low, high); -#endif } static void pmc_start(void *info) @@ -1235,6 +1223,9 @@ printk(KERN_INFO "%s\n", op_version); + /* 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(); if ((err = apic_setup())) @@ -1262,6 +1253,7 @@ /* do this now so we don't have to track save/restores later */ op_save_syscalls(); + printk("oprofile: oprofile loaded, major %u\n", op_major); return 0; @@ -1275,8 +1267,8 @@ { oprof_free_hashmap(); unregister_chrdev(op_major, "oprof"); - smp_call_function(smp_apic_restore, NULL, 0, 1); - smp_apic_restore(NULL); + smp_call_function(lvtpc_apic_restore, NULL, 0, 1); + lvtpc_apic_restore(NULL); cleanup_sysctl(); // currently no need to reset APIC state } |
From: John L. <mov...@us...> - 2001-09-02 00:32:32
|
Update of /cvsroot/oprofile/oprofile/pp In directory usw-pr-cvs1:/tmp/cvs-serv14034/pp Modified Files: Makefile.in Log Message: philippe's patch Index: Makefile.in =================================================================== RCS file: /cvsroot/oprofile/oprofile/pp/Makefile.in,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- Makefile.in 2001/09/01 02:03:34 1.15 +++ Makefile.in 2001/09/02 00:32:28 1.16 @@ -21,7 +21,7 @@ uninstall: for f in $(INSTALL_LIST); do \ - -rm -f $(BINDIR)/$$f; \ + rm -f $(BINDIR)/$$f; \ done CFLAGS=-Wall -Wstrict-prototypes -W -pipe -DOP_EVENTS_DESC -L/usr/lib @CFLAGS@ |
From: John L. <mov...@us...> - 2001-09-02 00:32:32
|
Update of /cvsroot/oprofile/oprofile/dae In directory usw-pr-cvs1:/tmp/cvs-serv14034/dae Modified Files: Makefile.in opd_proc.c Log Message: philippe's patch Index: Makefile.in =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/Makefile.in,v retrieving revision 1.15 retrieving revision 1.16 diff -u -d -r1.15 -r1.16 --- Makefile.in 2001/09/01 02:03:34 1.15 +++ Makefile.in 2001/09/02 00:32:28 1.16 @@ -20,7 +20,7 @@ uninstall: for f in $(INSTALL_LIST); do \ - -rm -f $(BINDIR)/$$f; \ + rm -f $(BINDIR)/$$f; \ done clean: Index: opd_proc.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/dae/opd_proc.c,v retrieving revision 1.65 retrieving revision 1.66 diff -u -d -r1.65 -r1.66 --- opd_proc.c 2001/09/01 02:03:34 1.65 +++ opd_proc.c 2001/09/02 00:32:28 1.66 @@ -472,6 +472,7 @@ counter = opd_get_counter(count); sample_file = &image->sample_files[counter]; + printf("counter %d\n", counter); if (sample_file->fd < 1) { opd_open_sample_file(image, counter); if (sample_file->fd < 1) { |
From: John L. <mov...@us...> - 2001-09-02 00:32:32
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv14034 Modified Files: ChangeLog oprofile.c Log Message: philippe's patch Index: ChangeLog =================================================================== RCS file: /cvsroot/oprofile/oprofile/ChangeLog,v retrieving revision 1.92 retrieving revision 1.93 diff -u -d -r1.92 -r1.93 --- ChangeLog 2001/09/01 02:03:34 1.92 +++ ChangeLog 2001/09/02 00:32:28 1.93 @@ -1,3 +1,10 @@ +2001-09-01 Philippe Elie <ph...@cl...> + + * oprofile.c: fix pmc_setup() + + * pp/Makefile.in: + * dae/Makefile.in: fix uninstall problem + 2001-08-31 Philippe Elie <ph...@cl...> * oprofile.h: Index: oprofile.c =================================================================== RCS file: /cvsroot/oprofile/oprofile/oprofile.c,v retrieving revision 1.76 retrieving revision 1.77 diff -u -d -r1.76 -r1.77 --- oprofile.c 2001/09/01 02:03:34 1.76 +++ oprofile.c 2001/09/02 00:32:28 1.77 @@ -441,10 +441,13 @@ /* Stop and clear all counter: IA32 use bit 22 of eventsel_msr0 to * enable/disable all counter, AMD use separate bit 22 in each msr, - * all other bits are cleared except the reserved bits 21 */ + * all bits are cleared except the reserved bits 21 */ for (i = 0 ; i < op_nr_counters ; ++i) { rdmsr(eventsel_msr[i], low, high); - wrmsr(eventsel_msr[i], low & ~(3 << 22), high); + wrmsr(eventsel_msr[i], low & (1 << 22), high); + + /* avoid a false detection of ctr overflow in NMI handler */ + wrmsr(perfctr_msr[i], -1, -1); } /* setup each counter */ @@ -501,7 +504,8 @@ /* this is pretty bogus really. especially as we don't re-enable it. * Instead, save state set up, and restore with pmc_unsetup or similar */ #if !defined(CONFIG_X86_UP_APIC) || !defined(OP_EXPORTED_DO_NMI) - wrmsr(eventsel_msr[1], low, high); + /* PHE FIXME: on my config this start counter 1 with the new code */ +// wrmsr(eventsel_msr[1], low, high); #endif } |
From: Dave J. <da...@us...> - 2001-09-01 21:50:38
|
Update of /cvsroot/oprofile/oprofile In directory usw-pr-cvs1:/tmp/cvs-serv5883 Modified Files: .cvsignore Log Message: Update ignorance list. Index: .cvsignore =================================================================== RCS file: /cvsroot/oprofile/oprofile/.cvsignore,v retrieving revision 1.2 retrieving revision 1.3 diff -u -d -r1.2 -r1.3 --- .cvsignore 2000/08/18 01:24:37 1.2 +++ .cvsignore 2001/09/01 21:50:35 1.3 @@ -3,6 +3,7 @@ version.h a.diff oprofile.s +confdefs.h config.log config.cache config.status |