forked from Minki/linux
a6dbf93a2a
Currently there is a bug where if you use oprofile on a pSeries machine, then use perf_counters, then use oprofile again, oprofile will not work correctly; it will lose the PMU configuration the next time the hypervisor does a partition context switch, and thereafter won't count anything. Maynard Johnson identified the sequence causing the problem: - oprofile setup calls ppc_enable_pmcs(), which calls pseries_lpar_enable_pmcs, which tells the hypervisor that we want to use the PMU, and sets the "PMU in use" flag in the lppaca. This flag tells the hypervisor whether it needs to save and restore the PMU config. - The perf_counter code sets and clears the "PMU in use" flag directly as it context-switches the PMU between tasks, and leaves it clear when it finishes. - oprofile setup, called for a new oprofile run, calls ppc_enable_pmcs, which does nothing because it has already been called. In particular it doesn't set the "PMU in use" flag. This fixes the problem by arranging for ppc_enable_pmcs to always set the "PMU in use" flag. It makes the perf_counter code call ppc_enable_pmcs also rather than calling the lower-level function directly, and removes the setting of the "PMU in use" flag from pseries_lpar_enable_pmcs, since that is now done in its caller. This also removes the declaration of pasemi_enable_pmcs because it isn't defined anywhere. Reported-by: Maynard Johnson <mpjohn@us.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org> Cc: <stable@kernel.org) Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
50 lines
1.3 KiB
C
50 lines
1.3 KiB
C
/*
|
|
* pmc.h
|
|
* Copyright (C) 2004 David Gibson, IBM Corporation
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
#ifndef _POWERPC_PMC_H
|
|
#define _POWERPC_PMC_H
|
|
#ifdef __KERNEL__
|
|
|
|
#include <asm/ptrace.h>
|
|
|
|
typedef void (*perf_irq_t)(struct pt_regs *);
|
|
extern perf_irq_t perf_irq;
|
|
|
|
int reserve_pmc_hardware(perf_irq_t new_perf_irq);
|
|
void release_pmc_hardware(void);
|
|
void ppc_enable_pmcs(void);
|
|
|
|
#ifdef CONFIG_PPC64
|
|
#include <asm/lppaca.h>
|
|
|
|
static inline void ppc_set_pmu_inuse(int inuse)
|
|
{
|
|
get_lppaca()->pmcregs_in_use = inuse;
|
|
}
|
|
|
|
extern void power4_enable_pmcs(void);
|
|
|
|
#else /* CONFIG_PPC64 */
|
|
|
|
static inline void ppc_set_pmu_inuse(int inuse) { }
|
|
|
|
#endif
|
|
|
|
#endif /* __KERNEL__ */
|
|
#endif /* _POWERPC_PMC_H */
|