From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>,
Ingo Molnar <mingo@kernel.org>, Borislav Petkov <bp@alien8.de>,
Stephane Eranian <eranian@google.com>,
Harish Chegondi <harish.chegondi@intel.com>,
Kan Liang <kan.liang@intel.com>,
Andi Kleen <andi.kleen@intel.com>
Subject: [patch 04/11] x86/perf/intel_uncore: Cleanup hardware on exit
Date: Wed, 17 Feb 2016 13:47:33 -0000 [thread overview]
Message-ID: <20160217133932.018288722@linutronix.de> (raw)
In-Reply-To: 20160217132903.767990400@linutronix.de
[-- Attachment #1: x86-perf-intel_uncore--Cleanup-hardware-on-exit.patch --]
[-- Type: text/plain, Size: 10907 bytes --]
When tearing down the boxes nothing undoes the hardware state which was setup
by box->init_box(). Add a box->exit_box() callback and implement it for the
uncores which have an init_box() callback.
This misses the cleanup in the error exit pathes, but I cannot be bothered to
implement it before cleaning up the rest of the driver, which makes that task
way simpler.
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/kernel/cpu/perf_event_intel_uncore.c | 6 +-
arch/x86/kernel/cpu/perf_event_intel_uncore.h | 9 +++
arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c | 6 ++
arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c | 13 ++++
arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c | 57 +++++++++++++++++++-
5 files changed, 88 insertions(+), 3 deletions(-)
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -927,6 +927,7 @@ static int uncore_pci_probe(struct pci_d
raw_spin_lock(&uncore_box_lock);
list_del(&box->list);
raw_spin_unlock(&uncore_box_lock);
+ uncore_box_exit(box);
kfree(box);
}
return ret;
@@ -972,6 +973,7 @@ static void uncore_pci_remove(struct pci
}
WARN_ON_ONCE(atomic_read(&box->refcnt) != 1);
+ uncore_box_exit(box);
kfree(box);
if (last_box)
@@ -1079,8 +1081,10 @@ static void uncore_cpu_dying(int cpu)
pmu = &type->pmus[j];
box = *per_cpu_ptr(pmu->box, cpu);
*per_cpu_ptr(pmu->box, cpu) = NULL;
- if (box && atomic_dec_and_test(&box->refcnt))
+ if (box && atomic_dec_and_test(&box->refcnt)) {
list_add(&box->list, &boxes_to_free);
+ uncore_box_exit(box);
+ }
}
}
}
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
@@ -61,6 +61,7 @@ struct intel_uncore_type {
struct intel_uncore_ops {
void (*init_box)(struct intel_uncore_box *);
+ void (*exit_box)(struct intel_uncore_box *);
void (*disable_box)(struct intel_uncore_box *);
void (*enable_box)(struct intel_uncore_box *);
void (*disable_event)(struct intel_uncore_box *, struct perf_event *);
@@ -306,6 +307,14 @@ static inline void uncore_box_init(struc
}
}
+static inline void uncore_box_exit(struct intel_uncore_box *box)
+{
+ if (test_and_clear_bit(UNCORE_BOX_FLAG_INITIATED, &box->flags)) {
+ if (box->pmu->type->ops->exit_box)
+ box->pmu->type->ops->exit_box(box);
+ }
+}
+
static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
{
return (box->phys_id < 0);
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_nhmex.c
@@ -201,6 +201,11 @@ static void nhmex_uncore_msr_init_box(st
wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
}
+static void nhmex_uncore_msr_exit_box(struct intel_uncore_box *box)
+{
+ wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, 0);
+}
+
static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
{
unsigned msr = uncore_msr_box_ctl(box);
@@ -250,6 +255,7 @@ static void nhmex_uncore_msr_enable_even
#define NHMEX_UNCORE_OPS_COMMON_INIT() \
.init_box = nhmex_uncore_msr_init_box, \
+ .exit_box = nhmex_uncore_msr_exit_box, \
.disable_box = nhmex_uncore_msr_disable_box, \
.enable_box = nhmex_uncore_msr_enable_box, \
.disable_event = nhmex_uncore_msr_disable_event, \
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snb.c
@@ -95,6 +95,12 @@ static void snb_uncore_msr_init_box(stru
}
}
+static void snb_uncore_msr_exit_box(struct intel_uncore_box *box)
+{
+ if (box->pmu->pmu_idx == 0)
+ wrmsrl(SNB_UNC_PERF_GLOBAL_CTL, 0);
+}
+
static struct uncore_event_desc snb_uncore_events[] = {
INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0x00"),
{ /* end: all zeroes */ },
@@ -116,6 +122,7 @@ static struct attribute_group snb_uncore
static struct intel_uncore_ops snb_uncore_msr_ops = {
.init_box = snb_uncore_msr_init_box,
+ .exit_box = snb_uncore_msr_exit_box,
.disable_event = snb_uncore_msr_disable_event,
.enable_event = snb_uncore_msr_enable_event,
.read_counter = uncore_msr_read_counter,
@@ -231,6 +238,11 @@ static void snb_uncore_imc_init_box(stru
box->hrtimer_duration = UNCORE_SNB_IMC_HRTIMER_INTERVAL;
}
+static void snb_uncore_imc_exit_box(struct intel_uncore_box *box)
+{
+ iounmap(box->io_addr);
+}
+
static void snb_uncore_imc_enable_box(struct intel_uncore_box *box)
{}
@@ -458,6 +470,7 @@ static struct pmu snb_uncore_imc_pmu = {
static struct intel_uncore_ops snb_uncore_imc_ops = {
.init_box = snb_uncore_imc_init_box,
+ .exit_box = snb_uncore_imc_exit_box,
.enable_box = snb_uncore_imc_enable_box,
.disable_box = snb_uncore_imc_disable_box,
.disable_event = snb_uncore_imc_disable_event,
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore_snbep.c
@@ -387,6 +387,14 @@ static void snbep_uncore_pci_init_box(st
pci_write_config_dword(pdev, box_ctl, SNBEP_PMON_BOX_CTL_INT);
}
+static void snbep_uncore_pci_exit_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+ int box_ctl = uncore_pci_box_ctl(box);
+
+ pci_write_config_dword(pdev, box_ctl, 0);
+}
+
static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
{
u64 config;
@@ -440,6 +448,14 @@ static void snbep_uncore_msr_init_box(st
wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
}
+static void snbep_uncore_msr_exit_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+
+ if (msr)
+ wrmsrl(msr, 0);
+}
+
static struct attribute *snbep_uncore_formats_attr[] = {
&format_attr_event.attr,
&format_attr_umask.attr,
@@ -567,7 +583,8 @@ static struct attribute_group snbep_unco
#define SNBEP_UNCORE_MSR_OPS_COMMON_INIT() \
__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(), \
- .init_box = snbep_uncore_msr_init_box \
+ .init_box = snbep_uncore_msr_init_box, \
+ .exit_box = snbep_uncore_msr_exit_box \
static struct intel_uncore_ops snbep_uncore_msr_ops = {
SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
@@ -575,6 +592,7 @@ static struct intel_uncore_ops snbep_unc
#define SNBEP_UNCORE_PCI_OPS_COMMON_INIT() \
.init_box = snbep_uncore_pci_init_box, \
+ .exit_box = snbep_uncore_pci_exit_box, \
.disable_box = snbep_uncore_pci_disable_box, \
.enable_box = snbep_uncore_pci_enable_box, \
.disable_event = snbep_uncore_pci_disable_event, \
@@ -1236,10 +1254,19 @@ int snbep_uncore_pci_init(void)
static void ivbep_uncore_msr_init_box(struct intel_uncore_box *box)
{
unsigned msr = uncore_msr_box_ctl(box);
+
if (msr)
wrmsrl(msr, IVBEP_PMON_BOX_CTL_INT);
}
+static void ivbep_uncore_msr_exit_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+
+ if (msr)
+ wrmsrl(msr, 0);
+}
+
static void ivbep_uncore_pci_init_box(struct intel_uncore_box *box)
{
struct pci_dev *pdev = box->pci_dev;
@@ -1247,8 +1274,16 @@ static void ivbep_uncore_pci_init_box(st
pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, IVBEP_PMON_BOX_CTL_INT);
}
+static void ivbep_uncore_pci_exit_box(struct intel_uncore_box *box)
+{
+ struct pci_dev *pdev = box->pci_dev;
+
+ pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, 0);
+}
+
#define IVBEP_UNCORE_MSR_OPS_COMMON_INIT() \
.init_box = ivbep_uncore_msr_init_box, \
+ .exit_box = ivbep_uncore_msr_exit_box, \
.disable_box = snbep_uncore_msr_disable_box, \
.enable_box = snbep_uncore_msr_enable_box, \
.disable_event = snbep_uncore_msr_disable_event, \
@@ -1261,6 +1296,7 @@ static struct intel_uncore_ops ivbep_unc
static struct intel_uncore_ops ivbep_uncore_pci_ops = {
.init_box = ivbep_uncore_pci_init_box,
+ .exit_box = ivbep_uncore_pci_exit_box,
.disable_box = snbep_uncore_pci_disable_box,
.enable_box = snbep_uncore_pci_enable_box,
.disable_event = snbep_uncore_pci_disable_event,
@@ -1497,6 +1533,7 @@ static void ivbep_cbox_enable_event(stru
static struct intel_uncore_ops ivbep_uncore_cbox_ops = {
.init_box = ivbep_uncore_msr_init_box,
+ .exit_box = ivbep_uncore_msr_exit_box,
.disable_box = snbep_uncore_msr_disable_box,
.enable_box = snbep_uncore_msr_enable_box,
.disable_event = snbep_uncore_msr_disable_event,
@@ -1613,6 +1650,7 @@ static u64 ivbep_uncore_irp_read_counter
static struct intel_uncore_ops ivbep_uncore_irp_ops = {
.init_box = ivbep_uncore_pci_init_box,
+ .exit_box = ivbep_uncore_pci_exit_box,
.disable_box = snbep_uncore_pci_disable_box,
.enable_box = snbep_uncore_pci_enable_box,
.disable_event = ivbep_uncore_irp_disable_event,
@@ -1633,6 +1671,7 @@ static struct intel_uncore_type ivbep_un
static struct intel_uncore_ops ivbep_uncore_qpi_ops = {
.init_box = ivbep_uncore_pci_init_box,
+ .exit_box = ivbep_uncore_pci_exit_box,
.disable_box = snbep_uncore_pci_disable_box,
.enable_box = snbep_uncore_pci_enable_box,
.disable_event = snbep_uncore_pci_disable_event,
@@ -1914,6 +1953,7 @@ static void hswep_cbox_enable_event(stru
static struct intel_uncore_ops knl_uncore_cha_ops = {
.init_box = snbep_uncore_msr_init_box,
+ .exit_box = snbep_uncore_msr_exit_box,
.disable_box = snbep_uncore_msr_disable_box,
.enable_box = snbep_uncore_msr_enable_box,
.disable_event = snbep_uncore_msr_disable_event,
@@ -2008,6 +2048,7 @@ static void knl_uncore_imc_enable_event(
static struct intel_uncore_ops knl_uncore_imc_ops = {
.init_box = snbep_uncore_pci_init_box,
+ .exit_box = snbep_uncore_pci_exit_box,
.disable_box = snbep_uncore_pci_disable_box,
.enable_box = knl_uncore_imc_enable_box,
.read_counter = snbep_uncore_pci_read_counter,
@@ -2397,6 +2438,7 @@ static void hswep_cbox_enable_event(stru
static struct intel_uncore_ops hswep_uncore_cbox_ops = {
.init_box = snbep_uncore_msr_init_box,
+ .exit_box = snbep_uncore_msr_exit_box,
.disable_box = snbep_uncore_msr_disable_box,
.enable_box = snbep_uncore_msr_enable_box,
.disable_event = snbep_uncore_msr_disable_event,
@@ -2442,9 +2484,19 @@ static void hswep_uncore_sbox_msr_init_b
}
}
+static void hswep_uncore_sbox_msr_exit_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+
+ /* CHECKME: Does this need the bit dance like init() ? */
+ if (msr)
+ wrmsrl(msr, 0);
+}
+
static struct intel_uncore_ops hswep_uncore_sbox_msr_ops = {
__SNBEP_UNCORE_MSR_OPS_COMMON_INIT(),
- .init_box = hswep_uncore_sbox_msr_init_box
+ .init_box = hswep_uncore_sbox_msr_init_box,
+ .exit_box = hswep_uncore_sbox_msr_exit_box
};
static struct attribute *hswep_uncore_sbox_formats_attr[] = {
@@ -2584,6 +2636,7 @@ static u64 hswep_uncore_irp_read_counter
static struct intel_uncore_ops hswep_uncore_irp_ops = {
.init_box = snbep_uncore_pci_init_box,
+ .exit_box = snbep_uncore_pci_exit_box,
.disable_box = snbep_uncore_pci_disable_box,
.enable_box = snbep_uncore_pci_enable_box,
.disable_event = ivbep_uncore_irp_disable_event,
next prev parent reply other threads:[~2016-02-17 13:52 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-02-17 13:47 [patch 00/11] x86/perf/intel_uncore: Cleanup and enhancements Thomas Gleixner
2016-02-17 13:47 ` [patch 01/11] x86/perf/intel_uncore: Remove pointless mask check Thomas Gleixner
2016-02-17 13:47 ` [patch 02/11] x86/perf/intel_uncore: Simplify error rollback Thomas Gleixner
2016-02-17 13:47 ` [patch 03/11] x86/perf/intel_uncore: Fix error handling Thomas Gleixner
2016-02-17 13:47 ` Thomas Gleixner [this message]
2016-02-17 15:49 ` [patch 04/11] x86/perf/intel_uncore: Cleanup hardware on exit Liang, Kan
2016-02-17 18:16 ` Thomas Gleixner
2016-02-17 21:57 ` Liang, Kan
2016-02-17 22:00 ` Thomas Gleixner
2016-02-17 13:47 ` [patch 05/11] x86/perf/intel_uncore: Make code readable Thomas Gleixner
2016-02-17 13:47 ` [patch 06/11] x86/topology: Provide helper to retrieve number of cpu packages Thomas Gleixner
2016-02-17 13:47 ` [patch 07/11] x86/perf/uncore: Track packages not per cpu data Thomas Gleixner
2016-02-17 21:19 ` Stephane Eranian
2016-02-17 21:24 ` Andi Kleen
2016-02-17 21:56 ` Thomas Gleixner
2016-02-17 22:16 ` Andi Kleen
2016-02-17 22:31 ` Thomas Gleixner
2016-02-18 7:50 ` Ingo Molnar
2016-02-18 8:13 ` Peter Zijlstra
2016-02-18 9:35 ` Stephane Eranian
2016-02-18 9:51 ` Peter Zijlstra
2016-02-18 10:25 ` Thomas Gleixner
2016-02-18 10:22 ` Thomas Gleixner
2016-02-18 10:54 ` Thomas Gleixner
2016-02-19 8:39 ` Thomas Gleixner
2016-02-17 21:25 ` Thomas Gleixner
2016-02-17 13:47 ` [patch 08/11] x86/perf/intel_uncore: Clear all hardware state on exit Thomas Gleixner
2016-02-17 13:47 ` [patch 09/11] x86/perf/intel_uncore: Make PCI and MSR uncore independent Thomas Gleixner
2016-02-17 13:47 ` [patch 10/11] cpumask: Export cpumask_any_but Thomas Gleixner
2016-02-17 13:47 ` [patch 11/11] x86/perf/intel_uncore: Make it modular Thomas Gleixner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160217133932.018288722@linutronix.de \
--to=tglx@linutronix.de \
--cc=andi.kleen@intel.com \
--cc=bp@alien8.de \
--cc=eranian@google.com \
--cc=harish.chegondi@intel.com \
--cc=kan.liang@intel.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@kernel.org \
--cc=peterz@infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.