William Cohen | 1 Jun 2008 19:52
Picon

Re: Release Candidate 1 for OProfile 0.9.4

Maynard Johnson wrote:
> We are pleased to announce OProfile 0.9.4 Release Candidate 1.  You can download 
> this release at:
> http://sourceforge.net/project/showfiles.php?group_id=16191
> 
> This release has many new features and fixes.  The biggest change with this 
> release is the addition of support for profiling JITed code.  Java agents that 
> support Java 1.4 (JVMPI) and later (JVMTI) are included with OProfile.  See the 
> release notes below for more details.
> 
> Please test this release candidate and let us know (good or bad) how it works.
> 
> Thanks.
> -Maynard Johnson

Hi Maynard,

Thanks so much for working on a releasing Oprofile 0.9.4.

What is the logic for having oprofile require a special user and group oprofile 
for installation? On rpm builds the build machine might not have the special 
user and groups oprofile this may present an issue.

  Noticed that the Fedora 9 kernel (2.6.25.3-18.fc9) on x86_64 started with 
"nmi_watchdog=2" doesn't work with oprofile because performance counter 0 is 
used for the watchdog.  There were some patches submitted earlier earlier that 
allowed the performance counter allocation to occur even when some performance 
counter are already reserved. Would it be possible to roll this patch into 
0.9.4? Below is a link to the related email.

(Continue reading)

Daniel Hansel | 2 Jun 2008 11:15
Picon

Re: Release Candidate 1 for OProfile 0.9.4

William Cohen wrote:
> Hi Maynard,
> 
> Thanks so much for working on a releasing Oprofile 0.9.4.
> 
> What is the logic for having oprofile require a special user and group oprofile 
> for installation? On rpm builds the build machine might not have the special 
> user and groups oprofile this may present an issue.
> 
Hi William,

the special user account is introduced due to fact that the handling 
with potentially insecure data (i.e. the conversion of dump file 
produced during JIT profiling) may "offer" a point to be attacked (e.g. 
buffer overflow, etc.).
Therefore we decided to run the conversion step using a special user 
account. This mechanism is commonly used for such things.

>   Noticed that the Fedora 9 kernel (2.6.25.3-18.fc9) on x86_64 started with 
> "nmi_watchdog=2" doesn't work with oprofile because performance counter 0 is 
> used for the watchdog.  There were some patches submitted earlier earlier that 
> allowed the performance counter allocation to occur even when some performance 
> counter are already reserved. Would it be possible to roll this patch into 
> 0.9.4? Below is a link to the related email.
> 
> http://marc.info/?l=oprofile-list&m=120716521708920&w=2
Maybe Maynard could answer this question.
> 
> Will
> 
(Continue reading)

Maynard Johnson | 2 Jun 2008 14:34
Picon
Favicon

Re: Release Candidate 1 for OProfile 0.9.4

William Cohen wrote:
> Maynard Johnson wrote:
>   
>> We are pleased to announce OProfile 0.9.4 Release Candidate 1.  You can download 
>> this release at:
>> http://sourceforge.net/project/showfiles.php?group_id=16191
>>
>> This release has many new features and fixes.  The biggest change with this 
>> release is the addition of support for profiling JITed code.  Java agents that 
>> support Java 1.4 (JVMPI) and later (JVMTI) are included with OProfile.  See the 
>> release notes below for more details.
>>
>> Please test this release candidate and let us know (good or bad) how it works.
>>
>> Thanks.
>> -Maynard Johnson
>>     
>
> Hi Maynard,
>
> Thanks so much for working on a releasing Oprofile 0.9.4.
>
> What is the logic for having oprofile require a special user and group oprofile 
> for installation? On rpm builds the build machine might not have the special 
> user and groups oprofile this may present an issue.
>   
One thing to add to Daniel's reply . . . The configure script puts out a
warning message if the 'oprofile' user and group accounts do not exist,
and 'make install' will fail if they do not exist.  Will this be a
problem for your rpm build machines?  Please look at the new file in
(Continue reading)

SourceForge.net | 2 Jun 2008 16:24
Picon
Favicon

[ oprofile-Bugs-1982201 ] opreport --xml total event count mismatch

Bugs item #1982201, was opened at 2008-06-02 17:24
Message generated for change (Tracker Item Submitted) made by Item Submitter
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=116191&aid=1982201&group_id=16191

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
Category: None
Group: None
Status: Open
Resolution: None
Priority: 5
Private: No
Submitted By: tommi (ttrantal)
Assigned to: Nobody/Anonymous (nobody)
Summary: opreport --xml total event count mismatch

Initial Comment:
Profiling with the --separate flag, opreport XML output can give incorrect total count.

To reproduce:

1) Put this to ''/tmp/test.c'' and compile with ''gcc test.c -o test'':
#include <stdlib.h>
int main() { unsigned i; for (i=0; i < 30000000; ++i) free(malloc(2048)); return 0; }

2) Do some profiling:
$ opcontrol --separate=library --no-vmlinux --setup --event=CPU_CLK_UNHALTED:100000 --start --image=/tmp/test
$ /tmp/test
(Continue reading)

Ramachandramurthy, Bharath | 2 Jun 2008 19:24

RE: Thread Level Profiling Clarification Required.

Hi Maynard

I tried generating the opreport using the thread id option as mentioned in your email [ opreport -l tgid:< > ].

For all the threads I only see very high level info regarding the CPU level usage. Also I don't see the CPU
occupancy for all the symbols/functions in this thread.

Any idea how to get those details ?

Thanks in advance.

Regards
Bharath

-----Original Message-----
From: Maynard Johnson [mailto:maynardj <at> us.ibm.com]
Sent: Thursday, May 29, 2008 6:33 AM
To: Ramachandramurthy, Bharath
Cc: oprofile-list <at> lists.sf.net
Subject: Re: Thread Level Profiling Clarification Required.

Ramachandramurthy, Bharath wrote:
> Hi
>
> While retrieving thread level oprofiling data I am facing a problem.
>
> I ran the oprofile with the following configuration "opcontrol --separate=all".
> [ I also tried with "opcontrol -separate=thread" option ]
>
> Then, I did dump the data using "opcontrol -dump" option after running my application.
(Continue reading)

Peter Wong | 2 Jun 2008 22:07
Picon
Favicon

Oprofile 0.9.4 works fine


Oprofile 0.9.4 works reasonably well for profiling linpack on a POWER6 system.

Peter Wong, Linux Performance Team in IBM
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
oprofile-list mailing list
oprofile-list <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/oprofile-list
Maynard Johnson | 2 Jun 2008 22:10
Picon
Favicon

Re: Thread Level Profiling Clarification Required.

Ramachandramurthy, Bharath wrote:
> Hi Maynard
>
> I tried generating the opreport using the thread id option as mentioned in your email [ opreport -l tgid:< > ].
>
> For all the threads I only see very high level info regarding the CPU level usage. Also I don't see the CPU
occupancy for all the symbols/functions in this thread.
>
> Any idea how to get those details ?
>   
See the man page for opreport for info on how to generate a report with
per-instruction or per-source line sample attribution (-d or -g).  To
separate samples per-cpu and thread, run opcontrol with
--separate=cpu,thread.

-Maynard
> Thanks in advance.
>
> Regards
> Bharath
>
>
> -----Original Message-----
> From: Maynard Johnson [mailto:maynardj <at> us.ibm.com]
> Sent: Thursday, May 29, 2008 6:33 AM
> To: Ramachandramurthy, Bharath
> Cc: oprofile-list <at> lists.sf.net
> Subject: Re: Thread Level Profiling Clarification Required.
>
> Ramachandramurthy, Bharath wrote:
>   
>> Hi
>>
>> While retrieving thread level oprofiling data I am facing a problem.
>>
>> I ran the oprofile with the following configuration "opcontrol --separate=all".
>> [ I also tried with "opcontrol -separate=thread" option ]
>>
>> Then, I did dump the data using "opcontrol -dump" option after running my application.
>>
>> When I try retrieving the data from the logs using
>> "opreport -l > <file_name>" I find the following error.
>>
>> # opreport -l > file_name
>> opreport error: Already displaying results for parameter tgid with values:
>> tgid:0,tgid:5,tgid:110,tgid:120,tgid:1140, and 50 more,
>> which conflicts with parameter tid.
>> Suggestion: specify tgid: or --merge tgid
>>
>> Then I did try with # opreport -merge=all -l > <file_name>.
>> It did generate a log file but I couldn't find any thread level usage details. All I could find was
>> The data in the below format.
>>
>>     
> During your profiling session, identify the process IDs of the
> application(s) on which you want to focus.  Then run 'opreport -l
> tgid:<comma-separated-list-of-tgids>'.  If your application is
> multi-threaded and you only want to focus on specific threads versus the
> entire thread group, then use 'opreport -l
> tid:<comma-separated-list-of-tids>'.
>
> -Maynard
>   
>> -------------------------------------------------------------------------------------
>>
>> samples  %        app name                 symbol name
>> -------------------------------------------------------------------------------------
>>
>>
>> Any inputs on what I am missing here to retrieve the thread level details ?
>>
>> Please reply ASAP to me only.
>>
>> Regards
>> Bharath
>>
>>
>>
>>
>> ------------------------------------------------------------------------
>>
>> -------------------------------------------------------------------------
>> This SF.net email is sponsored by: Microsoft
>> Defy all challenges. Microsoft(R) Visual Studio 2008.
>> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
>> ------------------------------------------------------------------------
>>
>> _______________________________________________
>> oprofile-list mailing list
>> oprofile-list <at> lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/oprofile-list
>>
>>     
>
>
>   

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Jason Yeh | 3 Jun 2008 15:44
Picon
Favicon

[PATCH] Updated: Oprofile Multiplexing

This is an updated patch to enable Oprofile module to switch between different
sets of events at the user specified interval. It allows the module to gather
more event statistics than the number of event counters on the hardware in a
single run of profiling.

A new file (/dev/oprofile/timeout_ms) is added for user to specify the interval.
If the number of user specified events is more than the number of events counter
on the hardware, the patch will schedule a delayed work and switch/re-writes the
different sets of value into the events counter. The switching mechanism needs
to be done for each architecture if it wishes to support this multiplexing scheme.
Only AMD CPU is supported in this patch.

Signed-off-by: Jason Yeh <jason.yeh <at> amd.com>
---

 arch/x86/oprofile/nmi_int.c         |   20 +++++
 arch/x86/oprofile/op_counter.h      |    3
 arch/x86/oprofile/op_model_athlon.c |  123 +++++++++++++++++++++++++++++-------
 arch/x86/oprofile/op_x86_model.h    |    2
 drivers/oprofile/oprof.c            |   57 +++++++++++++++-
 drivers/oprofile/oprof.h            |    4 -
 drivers/oprofile/oprofile_files.c   |   39 ++++++++++-
 include/linux/oprofile.h            |    3
 8 files changed, 223 insertions(+), 28 deletions(-)

diff --git a/arch/x86/oprofile/nmi_int.c b/arch/x86/oprofile/nmi_int.c
index cc48d3f..42fef97 100644
--- a/arch/x86/oprofile/nmi_int.c
+++ b/arch/x86/oprofile/nmi_int.c
 <at>  <at>  -80,6 +80,24  <at>  <at>  static void exit_sysfs(void)
 #define exit_sysfs() do { } while (0)
 #endif /* CONFIG_PM */

+static void nmi_cpu_switch(void *dummy)
+{
+	struct op_msrs *msrs = &__get_cpu_var(cpu_msrs);
+	model->switch_ctrs(msrs);
+}
+
+static int nmi_switch_event(void)
+{
+	/* Check CPU 0 should be sufficient */
+	struct op_msrs const *msrs = &per_cpu(cpu_msrs, 0);
+
+	if (model->check_multiplexing(msrs) < 0)
+		return -EINVAL;
+
+	on_each_cpu(nmi_cpu_switch, NULL, 0, 1);
+	return 0;
+}
+
 static int profile_exceptions_notify(struct notifier_block *self,
 				     unsigned long val, void *data)
 {
 <at>  <at>  -326,6 +344,7  <at>  <at>  static int nmi_create_files(struct super_block *sb, struct dentry *root)
 		oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask);
 		oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel);
 		oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user);
+		counter_config[i].save_count_low = 0;
 	}

 	return 0;
 <at>  <at>  -455,6 +474,7  <at>  <at>  int __init op_nmi_init(struct oprofile_operations *ops)
 	ops->start = nmi_start;
 	ops->stop = nmi_stop;
 	ops->cpu_type = cpu_type;
+	ops->switch_events = nmi_switch_event;
 	printk(KERN_INFO "oprofile: using NMI interrupt.\n");
 	return 0;
 }
diff --git a/arch/x86/oprofile/op_counter.h b/arch/x86/oprofile/op_counter.h
index 2880b15..786d6e0 100644
--- a/arch/x86/oprofile/op_counter.h
+++ b/arch/x86/oprofile/op_counter.h
 <at>  <at>  -10,13 +10,14  <at>  <at> 
 #ifndef OP_COUNTER_H
 #define OP_COUNTER_H

-#define OP_MAX_COUNTER 8
+#define OP_MAX_COUNTER 32

 /* Per-perfctr configuration as set via
  * oprofilefs.
  */
 struct op_counter_config {
         unsigned long count;
+		unsigned long save_count_low;
         unsigned long enabled;
         unsigned long event;
         unsigned long kernel;
diff --git a/arch/x86/oprofile/op_model_athlon.c b/arch/x86/oprofile/op_model_athlon.c
index 3d53487..4a09666 100644
--- a/arch/x86/oprofile/op_model_athlon.c
+++ b/arch/x86/oprofile/op_model_athlon.c
 <at>  <at>  -11,6 +11,7  <at>  <at> 
  */

 #include <linux/oprofile.h>
+#include <linux/percpu.h>
 #include <asm/ptrace.h>
 #include <asm/msr.h>
 #include <asm/nmi.h>
 <at>  <at>  -18,8 +19,10  <at>  <at> 
 #include "op_x86_model.h"
 #include "op_counter.h"

-#define NUM_COUNTERS 4
-#define NUM_CONTROLS 4
+#define NUM_COUNTERS 32
+#define NUM_HARDWARE_COUNTERS 4
+#define NUM_CONTROLS 32
+#define NUM_HARDWARE_CONTROLS 4

 #define CTR_IS_RESERVED(msrs, c) (msrs->counters[(c)].addr ? 1 : 0)
 #define CTR_READ(l, h, msrs, c) do {rdmsr(msrs->counters[(c)].addr, (l), (h)); } while (0)
 <at>  <at>  -43,21 +46,24  <at>  <at> 
 #define CTRL_SET_GUEST_ONLY(val, h) (val |= ((h & 1) << 8))

 static unsigned long reset_value[NUM_COUNTERS];
+static DEFINE_PER_CPU(int, switch_index);

 static void athlon_fill_in_addresses(struct op_msrs * const msrs)
 {
 	int i;

 	for (i = 0; i < NUM_COUNTERS; i++) {
-		if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + i))
-			msrs->counters[i].addr = MSR_K7_PERFCTR0 + i;
+		int hw_counter = i % NUM_HARDWARE_COUNTERS;
+		if (reserve_perfctr_nmi(MSR_K7_PERFCTR0 + hw_counter))
+			msrs->counters[i].addr = MSR_K7_PERFCTR0 + hw_counter;
 		else
 			msrs->counters[i].addr = 0;
 	}

 	for (i = 0; i < NUM_CONTROLS; i++) {
-		if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + i))
-			msrs->controls[i].addr = MSR_K7_EVNTSEL0 + i;
+		int hw_control = i % NUM_HARDWARE_CONTROLS;
+		if (reserve_evntsel_nmi(MSR_K7_EVNTSEL0 + hw_control))
+			msrs->controls[i].addr = MSR_K7_EVNTSEL0 + hw_control;
 		else
 			msrs->controls[i].addr = 0;
 	}
 <at>  <at>  -69,8 +75,15  <at>  <at>  static void athlon_setup_ctrs(struct op_msrs const * const msrs)
 	unsigned int low, high;
 	int i;

+	for (i = 0; i < NUM_COUNTERS; ++i) {
+		if (counter_config[i].enabled)
+			reset_value[i] = counter_config[i].count;
+		else
+			reset_value[i] = 0;
+	}
+
 	/* clear all counters */
-	for (i = 0 ; i < NUM_CONTROLS; ++i) {
+	for (i = 0 ; i < NUM_HARDWARE_CONTROLS; ++i) {
 		if (unlikely(!CTRL_IS_RESERVED(msrs, i)))
 			continue;
 		CTRL_READ(low, high, msrs, i);
 <at>  <at>  -80,14 +93,14  <at>  <at>  static void athlon_setup_ctrs(struct op_msrs const * const msrs)
 	}

 	/* avoid a false detection of ctr overflows in NMI handler */
-	for (i = 0; i < NUM_COUNTERS; ++i) {
+	for (i = 0; i < NUM_HARDWARE_COUNTERS; ++i) {
 		if (unlikely(!CTR_IS_RESERVED(msrs, i)))
 			continue;
 		CTR_WRITE(1, msrs, i);
 	}

 	/* enable active counters */
-	for (i = 0; i < NUM_COUNTERS; ++i) {
+	for (i = 0; i < NUM_HARDWARE_COUNTERS; ++i) {
 		if ((counter_config[i].enabled) && (CTR_IS_RESERVED(msrs, i))) {
 			reset_value[i] = counter_config[i].count;

 <at>  <at>  -106,26 +119,36  <at>  <at>  static void athlon_setup_ctrs(struct op_msrs const * const msrs)
 			CTRL_SET_GUEST_ONLY(high, 0);

 			CTRL_WRITE(low, high, msrs, i);
-		} else {
-			reset_value[i] = 0;
 		}
 	}
 }

 
+/*
+ * Quick check to see if multiplexing is necessary.
+ * The check should be efficient since counters are used
+ * in ordre.
+ */
+static int athlon_check_multiplexing(struct op_msrs const * const msrs)
+{
+	return counter_config[NUM_HARDWARE_COUNTERS].count ? 0 : -EINVAL;
+}
+
+
 static int athlon_check_ctrs(struct pt_regs * const regs,
 			     struct op_msrs const * const msrs)
 {
 	unsigned int low, high;
 	int i;

-	for (i = 0 ; i < NUM_COUNTERS; ++i) {
-		if (!reset_value[i])
+	for (i = 0 ; i < NUM_HARDWARE_COUNTERS ; ++i) {
+		int offset = i + __get_cpu_var(switch_index);
+		if (!reset_value[offset])
 			continue;
 		CTR_READ(low, high, msrs, i);
 		if (CTR_OVERFLOWED(low)) {
-			oprofile_add_sample(regs, i);
-			CTR_WRITE(reset_value[i], msrs, i);
+			oprofile_add_sample(regs, offset);
+			CTR_WRITE(reset_value[offset], msrs, i);
 		}
 	}

 <at>  <at>  -138,13 +161,14  <at>  <at>  static void athlon_start(struct op_msrs const * const msrs)
 {
 	unsigned int low, high;
 	int i;
-	for (i = 0 ; i < NUM_COUNTERS ; ++i) {
+	for (i = 0 ; i < NUM_HARDWARE_COUNTERS ; ++i) {
 		if (reset_value[i]) {
 			CTRL_READ(low, high, msrs, i);
 			CTRL_SET_ACTIVE(low);
 			CTRL_WRITE(low, high, msrs, i);
 		}
 	}
+	__get_cpu_var(switch_index) = 0;
 }

 
 <at>  <at>  -155,8 +179,8  <at>  <at>  static void athlon_stop(struct op_msrs const * const msrs)

 	/* Subtle: stop on all counters to avoid race with
 	 * setting our pm callback */
-	for (i = 0 ; i < NUM_COUNTERS ; ++i) {
-		if (!reset_value[i])
+	for (i = 0 ; i < NUM_HARDWARE_COUNTERS ; ++i) {
+		if (!reset_value[i + per_cpu(switch_index, smp_processor_id())])
 			continue;
 		CTRL_READ(low, high, msrs, i);
 		CTRL_SET_INACTIVE(low);
 <at>  <at>  -164,15 +188,70  <at>  <at>  static void athlon_stop(struct op_msrs const * const msrs)
 	}
 }

+
+static void athlon_switch_ctrs(struct op_msrs const * const msrs)
+{
+	unsigned int low, high;
+	int i, s = per_cpu(switch_index, smp_processor_id());
+
+	athlon_stop(msrs);
+
+	/* save the current hw counts */
+	for (i = 0; i < NUM_HARDWARE_COUNTERS; ++i) {
+		int offset = i + s;
+		if (!reset_value[offset])
+			continue;
+		CTR_READ(low, high, msrs, i);
+		/* convert counter value to actual count, assume high = -1 */
+		counter_config[offset].save_count_low =
+				(unsigned int) -1 - low - 1;
+	}
+
+	/* move to next eventset */
+	s += NUM_HARDWARE_COUNTERS;
+	if ((s > NUM_HARDWARE_COUNTERS) || (counter_config[s].count == 0)) {
+		per_cpu(switch_index, smp_processor_id()) = 0;
+		s = 0;
+	} else
+		per_cpu(switch_index, smp_processor_id()) = s;
+
+	/* enable next active counters */
+	for (i = 0; i < NUM_HARDWARE_COUNTERS; ++i) {
+		int offset = i + s;
+		if ((counter_config[offset].enabled)
+					&& (CTR_IS_RESERVED(msrs, i))) {
+			if (unlikely(!counter_config[offset].save_count_low))
+				counter_config[offset].save_count_low =
+						counter_config[offset].count;
+			CTR_WRITE(counter_config[offset].save_count_low,
+					msrs, i);
+			CTRL_READ(low, high, msrs, i);
+			CTRL_CLEAR_LO(low);
+			CTRL_CLEAR_HI(high);
+			CTRL_SET_ENABLE(low);
+			CTRL_SET_USR(low, counter_config[offset].user);
+			CTRL_SET_KERN(low, counter_config[offset].kernel);
+			CTRL_SET_UM(low, counter_config[offset].unit_mask);
+			CTRL_SET_EVENT_LOW(low, counter_config[offset].event);
+			CTRL_SET_EVENT_HIGH(high, counter_config[offset].event);
+			CTRL_SET_HOST_ONLY(high, 0);
+			CTRL_SET_GUEST_ONLY(high, 0);
+			CTRL_SET_ACTIVE(low);
+			CTRL_WRITE(low, high, msrs, i);
+		}
+	}
+}
+
+
 static void athlon_shutdown(struct op_msrs const * const msrs)
 {
 	int i;

-	for (i = 0 ; i < NUM_COUNTERS ; ++i) {
+	for (i = 0 ; i < NUM_HARDWARE_COUNTERS ; ++i) {
 		if (CTR_IS_RESERVED(msrs, i))
 			release_perfctr_nmi(MSR_K7_PERFCTR0 + i);
 	}
-	for (i = 0 ; i < NUM_CONTROLS ; ++i) {
+	for (i = 0 ; i < NUM_HARDWARE_COUNTERS ; ++i) {
 		if (CTRL_IS_RESERVED(msrs, i))
 			release_evntsel_nmi(MSR_K7_EVNTSEL0 + i);
 	}
 <at>  <at>  -186,5 +265,7  <at>  <at>  struct op_x86_model_spec const op_athlon_spec = {
 	.check_ctrs = &athlon_check_ctrs,
 	.start = &athlon_start,
 	.stop = &athlon_stop,
-	.shutdown = &athlon_shutdown
+	.shutdown = &athlon_shutdown,
+	.switch_ctrs = &athlon_switch_ctrs,
+	.check_multiplexing = &athlon_check_multiplexing
 };
diff --git a/arch/x86/oprofile/op_x86_model.h b/arch/x86/oprofile/op_x86_model.h
index 45b605f..45003c2 100644
--- a/arch/x86/oprofile/op_x86_model.h
+++ b/arch/x86/oprofile/op_x86_model.h
 <at>  <at>  -41,6 +41,8  <at>  <at>  struct op_x86_model_spec {
 	void (*start)(struct op_msrs const * const msrs);
 	void (*stop)(struct op_msrs const * const msrs);
 	void (*shutdown)(struct op_msrs const * const msrs);
+	void (*switch_ctrs)(struct op_msrs const * const msrs);
+	int (*check_multiplexing)(struct op_msrs const * const msrs);
 };

 extern struct op_x86_model_spec const op_ppro_spec;
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index 2c64517..9385e1a 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
 <at>  <at>  -12,6 +12,8  <at>  <at> 
 #include <linux/init.h>
 #include <linux/oprofile.h>
 #include <linux/moduleparam.h>
+#include <linux/workqueue.h>
+#include <linux/time.h>
 #include <asm/mutex.h>

 #include "oprof.h"
 <at>  <at>  -19,13 +21,18  <at>  <at> 
 #include "cpu_buffer.h"
 #include "buffer_sync.h"
 #include "oprofile_stats.h"
+
+static unsigned long is_setup;
+static void switch_worker(struct work_struct *work);
+static DECLARE_DELAYED_WORK(switch_work, switch_worker);
+static DEFINE_MUTEX(start_mutex);

 struct oprofile_operations oprofile_ops;

+unsigned long timeout_jiffies;
 unsigned long oprofile_started;
 unsigned long backtrace_depth;
-static unsigned long is_setup;
-static DEFINE_MUTEX(start_mutex);
+/* Multiplexing defaults at 1 msec*/

 /* timer
    0 - use performance monitoring hardware if available
 <at>  <at>  -87,6 +94,16  <at>  <at>  out:
 	return err;
 }

+static void start_switch_worker(void)
+{
+	schedule_delayed_work(&switch_work, timeout_jiffies);
+}
+
+static void switch_worker(struct work_struct *work)
+{
+	if (!oprofile_ops.switch_events())
+		start_switch_worker();
+}

 /* Actually start profiling (echo 1>/dev/oprofile/enable) */
 int oprofile_start(void)
 <at>  <at>  -94,7 +111,6  <at>  <at>  int oprofile_start(void)
 	int err = -EINVAL;

 	mutex_lock(&start_mutex);
- 
 	if (!is_setup)
 		goto out;

 <at>  <at>  -108,6 +124,9  <at>  <at>  int oprofile_start(void)
 	if ((err = oprofile_ops.start()))
 		goto out;

+	if (oprofile_ops.switch_events)
+		start_switch_worker();
+
 	oprofile_started = 1;
 out:
 	mutex_unlock(&start_mutex);
 <at>  <at>  -123,6 +142,7  <at>  <at>  void oprofile_stop(void)
 		goto out;
 	oprofile_ops.stop();
 	oprofile_started = 0;
+	cancel_delayed_work_sync(&switch_work);
 	/* wake up the daemon to read what remains */
 	wake_up_buffer_waiter();
 out:
 <at>  <at>  -155,6 +175,31  <at>  <at>  post_sync:
 	mutex_unlock(&start_mutex);
 }

+/* User inputs in ms, converts to jiffies */
+int oprofile_set_timeout(unsigned long val_msec)
+{
+	int err = 0;
+
+	mutex_lock(&start_mutex);
+
+	if (oprofile_started) {
+		err = -EBUSY;
+		goto out;
+	}
+
+	if (!oprofile_ops.switch_events) {
+		err = -EINVAL;
+		goto out;
+	}
+
+	if ((timeout_jiffies = msecs_to_jiffies(val_msec)) == MAX_JIFFY_OFFSET)
+		timeout_jiffies = msecs_to_jiffies(1);
+
+out:
+	mutex_unlock(&start_mutex);
+	return err;
+
+}

 int oprofile_set_backtrace(unsigned long val)
 {
 <at>  <at>  -179,10 +224,16  <at>  <at>  out:
 	return err;
 }

+static void __init oprofile_switch_timer_init(void)
+{
+	timeout_jiffies = msecs_to_jiffies(1);
+}
+
 static int __init oprofile_init(void)
 {
 	int err;

+	oprofile_switch_timer_init();
 	err = oprofile_arch_init(&oprofile_ops);

 	if (err < 0 || timer) {
diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h
index 1832365..c4406a7 100644
--- a/drivers/oprofile/oprof.h
+++ b/drivers/oprofile/oprof.h
 <at>  <at>  -27,7 +27,8  <at>  <at>  extern unsigned long fs_buffer_watershed;
 extern struct oprofile_operations oprofile_ops;
 extern unsigned long oprofile_started;
 extern unsigned long backtrace_depth;
- 
+extern unsigned long timeout_jiffies;
+
 struct super_block;
 struct dentry;

 <at>  <at>  -35,5 +36,6  <at>  <at>  void oprofile_create_files(struct super_block * sb, struct dentry * root);
 void oprofile_timer_init(struct oprofile_operations * ops);

 int oprofile_set_backtrace(unsigned long depth);
+int oprofile_set_timeout(unsigned long time);

 #endif /* OPROF_H */
diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c
index ef953ba..cc4f5a1 100644
--- a/drivers/oprofile/oprofile_files.c
+++ b/drivers/oprofile/oprofile_files.c
 <at>  <at>  -9,6 +9,7  <at>  <at> 

 #include <linux/fs.h>
 #include <linux/oprofile.h>
+#include <linux/jiffies.h>

 #include "event_buffer.h"
 #include "oprofile_stats.h"
 <at>  <at>  -18,6 +19,40  <at>  <at>  unsigned long fs_buffer_size = 131072;
 unsigned long fs_cpu_buffer_size = 8192;
 unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */

+static ssize_t timeout_read(struct file *file, char __user *buf,
+		size_t count, loff_t *offset)
+{
+	return oprofilefs_ulong_to_user(jiffies_to_msecs(timeout_jiffies),
+				buf, count, offset);
+}
+
+
+static ssize_t timeout_write(struct file *file, char const __user *buf,
+		size_t count, loff_t *offset)
+{
+	unsigned long val;
+	int retval;
+
+	if (*offset)
+		return -EINVAL;
+
+	retval = oprofilefs_ulong_from_user(&val, buf, count);
+	if (retval)
+		return retval;
+
+	retval = oprofile_set_timeout(val);
+
+	if (retval)
+		return retval;
+	return count;
+}
+
+static const struct file_operations timeout_fops = {
+	.read		= timeout_read,
+	.write		= timeout_write,
+};
+
+
 static ssize_t depth_read(struct file * file, char __user * buf, size_t count, loff_t * offset)
 {
 	return oprofilefs_ulong_to_user(backtrace_depth, buf, count, offset);
 <at>  <at>  -85,11 +120,10  <at>  <at>  static ssize_t enable_write(struct file * file, char const __user * buf, size_t

 	if (*offset)
 		return -EINVAL;
-
 	retval = oprofilefs_ulong_from_user(&val, buf, count);
 	if (retval)
 		return retval;
- 
+
 	if (val)
 		retval = oprofile_start();
 	else
 <at>  <at>  -129,6 +163,7  <at>  <at>  void oprofile_create_files(struct super_block * sb, struct dentry * root)
 	oprofilefs_create_file(sb, root, "cpu_type", &cpu_type_fops); 
 	oprofilefs_create_file(sb, root, "backtrace_depth", &depth_fops);
 	oprofilefs_create_file(sb, root, "pointer_size", &pointer_size_fops);
+	oprofilefs_create_file(sb, root, "timeout_ms", &timeout_fops);
 	oprofile_create_stats_files(sb, root);
 	if (oprofile_ops.create_files)
 		oprofile_ops.create_files(sb, root);
diff --git a/include/linux/oprofile.h b/include/linux/oprofile.h
index 041bb31..71af056 100644
--- a/include/linux/oprofile.h
+++ b/include/linux/oprofile.h
 <at>  <at>  -65,6 +65,9  <at>  <at>  struct oprofile_operations {

 	/* Initiate a stack backtrace. Optional. */
 	void (*backtrace)(struct pt_regs * const regs, unsigned int depth);
+
+	/* Multiplex between different events. Optional. */
+	int (*switch_events)(void);
 	/* CPU identification string. */
 	char * cpu_type;
 };

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
William Cohen | 3 Jun 2008 17:53
Picon

Re: Release Candidate 1 for OProfile 0.9.4

Maynard Johnson wrote:
> William Cohen wrote:
>> Maynard Johnson wrote:
>>   
>>> We are pleased to announce OProfile 0.9.4 Release Candidate 1.  You can download 
>>> this release at:
>>> http://sourceforge.net/project/showfiles.php?group_id=16191
>>>
>>> This release has many new features and fixes.  The biggest change with this 
>>> release is the addition of support for profiling JITed code.  Java agents that 
>>> support Java 1.4 (JVMPI) and later (JVMTI) are included with OProfile.  See the 
>>> release notes below for more details.
>>>
>>> Please test this release candidate and let us know (good or bad) how it works.
>>>
>>> Thanks.
>>> -Maynard Johnson
>>>     
>> Hi Maynard,
>>
>> Thanks so much for working on a releasing Oprofile 0.9.4.
>>
>> What is the logic for having oprofile require a special user and group oprofile 
>> for installation? On rpm builds the build machine might not have the special 
>> user and groups oprofile this may present an issue.
>>   
> One thing to add to Daniel's reply . . . The configure script puts out a
> warning message if the 'oprofile' user and group accounts do not exist,
> and 'make install' will fail if they do not exist.  Will this be a
> problem for your rpm build machines?  Please look at the new file in
> oprofile's root source directory called README_PACKAGERS for additional
> info on spec file changes that are needed to support these required user
> and group accounts and let me know if you see any problems with this.
>>   Noticed that the Fedora 9 kernel (2.6.25.3-18.fc9) on x86_64 started with 
>> "nmi_watchdog=2" doesn't work with oprofile because performance counter 0 is 
>> used for the watchdog.  There were some patches submitted earlier earlier that 
>> allowed the performance counter allocation to occur even when some performance 
>> counter are already reserved. Would it be possible to roll this patch into 
>> 0.9.4? Below is a link to the related email.
>>
>> http://marc.info/?l=oprofile-list&m=120716521708920&w=2

I didn't find the README_PACKAGERS file in the oprofile-0.9.4-rc1. It appears to 
be missing. I took a look to see if there were other discrepancies between the 
0.9.4-rc4 and the cvs. Aren't the generated html files generated as part of 
build? I thought the html were generated as part of the build. Below are files 
of interest that differd between the 0.9.4-rc1 and cvs.

  diff -u /tmp/o094rc1.files /tmp/orawhide.files

+./doc/buffers.dia
-./doc/internals.html
+./doc/CodingStyle
-./doc/op-jit-devel.html
-./doc/oprofile.1
-./doc/oprofile.html
+./HACKING
-./ltmain.sh
-./missing
+./README_PACKAGERS

RPM packages should be buildable by normal users. rpmbuild makes a separate 
directory in install the files into, so they can be installed as a normal user 
in that directory. It might be better to use %defattr in the %file section of 
the .spec file, so normal users can build the rpm. The real rpm install will 
give the files the appropriate group/owner. Which files are the ones that should 
be owned by oprofile?

>>   
> Will, it looks to me like John gave his approval for that patch on April
> 16.  Assuming that's the case, once you commit it, I can spin a release
> candidate 2 if you can test it.

I didn't see the approval, I checked the patch in today, so it doesn't hold up 
the spin.

-Will

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
Maynard Johnson | 4 Jun 2008 00:14
Picon
Favicon

Re: Release Candidate 1 for OProfile 0.9.4

William Cohen wrote:
> Maynard Johnson wrote:
>> William Cohen wrote:
>>> Maynard Johnson wrote:
>>>  
>>>> We are pleased to announce OProfile 0.9.4 Release Candidate 1.  You 
>>>> can download this release at:
>>>> http://sourceforge.net/project/showfiles.php?group_id=16191
>>>>
>>>> This release has many new features and fixes.  The biggest change 
>>>> with this release is the addition of support for profiling JITed 
>>>> code.  Java agents that support Java 1.4 (JVMPI) and later (JVMTI) 
>>>> are included with OProfile.  See the release notes below for more 
>>>> details.
>>>>
>>>> Please test this release candidate and let us know (good or bad) how 
>>>> it works.
>>>>
>>>> Thanks.
>>>> -Maynard Johnson
>>>>     
>>> Hi Maynard,
>>>
>>> Thanks so much for working on a releasing Oprofile 0.9.4.
>>>
>>> What is the logic for having oprofile require a special user and 
>>> group oprofile for installation? On rpm builds the build machine 
>>> might not have the special user and groups oprofile this may present 
>>> an issue.
>>>   
>> One thing to add to Daniel's reply . . . The configure script puts out a
>> warning message if the 'oprofile' user and group accounts do not exist,
>> and 'make install' will fail if they do not exist.  Will this be a
>> problem for your rpm build machines?  Please look at the new file in
>> oprofile's root source directory called README_PACKAGERS for additional
>> info on spec file changes that are needed to support these required user
>> and group accounts and let me know if you see any problems with this.
>>>   Noticed that the Fedora 9 kernel (2.6.25.3-18.fc9) on x86_64 
>>> started with "nmi_watchdog=2" doesn't work with oprofile because 
>>> performance counter 0 is used for the watchdog.  There were some 
>>> patches submitted earlier earlier that allowed the performance 
>>> counter allocation to occur even when some performance counter are 
>>> already reserved. Would it be possible to roll this patch into 0.9.4? 
>>> Below is a link to the related email.
>>>
>>> http://marc.info/?l=oprofile-list&m=120716521708920&w=2
> 
> I didn't find the README_PACKAGERS file in the oprofile-0.9.4-rc1. It 
Oops.  Forgot to add this new file to EXTRA_DIST in Makefile.am.  Thanks for 
catching it.
> appears to be missing. I took a look to see if there were other 
> discrepancies between the 0.9.4-rc4 and the cvs. Aren't the generated 
> html files generated as part of build? I thought the html were generated 
Looking back at 0.9.3 and 0.9.2, html files were included in the release tar balls.
> as part of the build. Below are files of interest that differd between 
> the 0.9.4-rc1 and cvs.
> 
>  diff -u /tmp/o094rc1.files /tmp/orawhide.files
> 
> +./doc/buffers.dia
> -./doc/internals.html
> +./doc/CodingStyle
> -./doc/op-jit-devel.html
> -./doc/oprofile.1
> -./doc/oprofile.html
> +./HACKING
> -./ltmain.sh
> -./missing
> +./README_PACKAGERS
> 
> RPM packages should be buildable by normal users. rpmbuild makes a 
> separate directory in install the files into, so they can be installed 
> as a normal user in that directory. It might be better to use %defattr 
> in the %file section of the .spec file, so normal users can build the 
> rpm. The real rpm install will give the files the appropriate 
> group/owner. Which files are the ones that should be owned by oprofile?
There aren't any files distributed with oprofile that are owned by the new 
'oprofile' account.  This account is used for converting JIT dump files to ELF 
files instead of having root do the conversion (which it was felt might open a 
Trojan horse type of security hole).

Yes, it would certainly be preferable to allow a normal user to run rpmbuild for 
oprofile -- and they can -- assuming the special user and group accounts exist 
on the build machine.  But I take it that you would also prefer to build the rpm 
without having to create the 'oprofile' account on the build machine, right?

The README_PACKAGERS file suggests to RPM packagers that they add code in the 
spec file to create the 'oprofile' account at rpm install time.  Is this, along 
with the configure warning enough to cover the bases?  (But maybe not all RPM 
packagers would read the README_PACKAGERS file.)  If we remove the 'make 
install' error and someone attempts to do JIT profiling without the 'oprofile' 
account existing, a runtime error would be logged in the oprofiled.log.  This is 
a pretty "quiet" error that not everyone knows how to find, but at least the 
user would know something didn't work right, since the output would be obviously 
incorrect.  We could beef up the user guide to highlight in more places the need 
for the 'oprofile account'.

Will, I'm not terribly familiar with the rpmbuild process . . . can you think of 
any other alternatives?  Maybe an alternate install target for rpmbuild that 
doesn't error out if the 'oprofile' account doesn't exist?  Anyone else have 
suggestions or comments?

Regards,
-Maynard

> 
>>>   
>> Will, it looks to me like John gave his approval for that patch on April
>> 16.  Assuming that's the case, once you commit it, I can spin a release
>> candidate 2 if you can test it.
> 
> I didn't see the approval, I checked the patch in today, so it doesn't 
> hold up the spin.
> 
> -Will

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php

Gmane