Commit 23c25b0d authored by Stéphane Eranian's avatar Stéphane Eranian Committed by Tony Luck

[IA64] perfmon.c: cleanup system-wide context when closed from another cpu

- fix pfm_stop() and pfm_flush_pmds() to correctly cleanup
  in case of a system-wide context which is closed while running
  from another processor. This was leading to an assertion failure
  in pfm_loads_regs() for the next user of the PMU on the monitored
  CPU.
signed-off-by: default avatarstephane eranian <eranian@hpl.hp.com>
Signed-off-by: default avatarTony Luck <tony.luck@intel.com>
parent bc312267
...@@ -3985,7 +3985,10 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs) ...@@ -3985,7 +3985,10 @@ pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
state = ctx->ctx_state; state = ctx->ctx_state;
is_system = ctx->ctx_fl_system; is_system = ctx->ctx_fl_system;
if (state != PFM_CTX_LOADED && state != PFM_CTX_MASKED) return -EINVAL; /*
* context must be attached to issue the stop command (includes LOADED,MASKED,ZOMBIE)
*/
if (state == PFM_CTX_UNLOADED) return -EINVAL;
/* /*
* In system wide and when the context is loaded, access can only happen * In system wide and when the context is loaded, access can only happen
...@@ -6312,15 +6315,15 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) ...@@ -6312,15 +6315,15 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
*/ */
is_self = ctx->ctx_task == task ? 1 : 0; is_self = ctx->ctx_task == task ? 1 : 0;
#ifdef CONFIG_SMP
if (task == current) {
#else
/* /*
* in UP, the state can still be in the registers * can access PMU is task is the owner of the PMU state on the current CPU
* or if we are running on the CPU bound to the context in system-wide mode
* (that is not necessarily the task the context is attached to in this mode).
* In system-wide we always have can_access_pmu true because a task running on an
* invalid processor is flagged earlier in the call stack (see pfm_stop).
*/ */
if (task == current || GET_PMU_OWNER() == task) { can_access_pmu = (GET_PMU_OWNER() == task) || (ctx->ctx_fl_system && ctx->ctx_cpu == smp_processor_id());
#endif if (can_access_pmu) {
can_access_pmu = 1;
/* /*
* Mark the PMU as not owned * Mark the PMU as not owned
* This will cause the interrupt handler to do nothing in case an overflow * This will cause the interrupt handler to do nothing in case an overflow
...@@ -6330,6 +6333,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx) ...@@ -6330,6 +6333,7 @@ pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
* on. * on.
*/ */
SET_PMU_OWNER(NULL, NULL); SET_PMU_OWNER(NULL, NULL);
DPRINT(("releasing ownership\n"));
/* /*
* read current overflow status: * read current overflow status:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment