linux_dsm_epyc7002/arch/powerpc/include/asm/imc-pmu.h
Anju T Sudhakar 684d984038 powerpc/powernv: Add debugfs interface for imc-mode and imc-command
In memory Collection (IMC) counter pmu driver controls the ucode's
execution state. At the system boot, IMC perf driver pause the ucode.
Ucode state is changed to "running" only when any of the nest units
are monitored or profiled using perf tool.

Nest units support only limited set of hardware counters and ucode is
always programmed in the "production mode" ("accumulation") mode. This
mode is configured to provide key performance metric data for most of
the nest units.

But ucode also supports other modes which would be used for "debug" to
drill down specific nest units. That is, ucode when switched to
"powerbus" debug mode (for example), will dynamically reconfigure the
nest counters to target only "powerbus" related events in the hardware
counters. This allows the IMC nest unit to focus on powerbus related
transactions in the system in more detail. At this point, production
mode events may or may not be counted.

IMC nest counters has both in-band (ucode access) and out of band
access to it. Since not all nest counter configurations are supported
by ucode, out of band tools are used to characterize other nest
counter configurations.

Patch provides an interface via "debugfs" to enable the switching of
ucode modes in the system. To switch ucode mode, one has to first
pause the microcode (imc_cmd), and then write the target mode value to
the "imc_mode" file.

Proposed Approach:

In the proposed approach, the function (export_imc_mode_and_cmd) which
creates the debugfs interface for imc mode and command is implemented
in opal-imc.c. Thus we can use imc_get_mem_addr() to get the homer
base address for each chip.

The interface to expose imc mode and command is required only if we
have nest pmu units registered. Employing the existing data structures
to track whether we have any nest units registered will require to
extend data from perf side to opal-imc.c. Instead an integer is
introduced to hold that information by counting successful nest unit
registration. Debugfs interface is removed based on the integer count.

Example for the interface:

  $ ls /sys/kernel/debug/imc
  imc_cmd_0  imc_cmd_8  imc_mode_0  imc_mode_8

Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
2018-01-19 23:05:00 +11:00

132 lines
3.0 KiB
C

#ifndef __ASM_POWERPC_IMC_PMU_H
#define __ASM_POWERPC_IMC_PMU_H
/*
* IMC Nest Performance Monitor counter support.
*
* Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation.
* (C) 2017 Anju T Sudhakar, IBM Corporation.
* (C) 2017 Hemant K Shaw, 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 later version.
*/
#include <linux/perf_event.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/io.h>
#include <asm/opal.h>
/*
* Compatibility macros for IMC devices
*/
#define IMC_DTB_COMPAT "ibm,opal-in-memory-counters"
#define IMC_DTB_UNIT_COMPAT "ibm,imc-counters"
/*
* LDBAR: Counter address and Enable/Disable macro.
* perf/imc-pmu.c has the LDBAR layout information.
*/
#define THREAD_IMC_LDBAR_MASK 0x0003ffffffffe000ULL
#define THREAD_IMC_ENABLE 0x8000000000000000ULL
/*
* For debugfs interface for imc-mode and imc-command
*/
#define IMC_CNTL_BLK_OFFSET 0x3FC00
#define IMC_CNTL_BLK_CMD_OFFSET 8
#define IMC_CNTL_BLK_MODE_OFFSET 32
/*
* Structure to hold memory address information for imc units.
*/
struct imc_mem_info {
u64 *vbase;
u32 id;
};
/*
* Place holder for nest pmu events and values.
*/
struct imc_events {
u32 value;
char *name;
char *unit;
char *scale;
};
/* Event attribute array index */
#define IMC_FORMAT_ATTR 0
#define IMC_EVENT_ATTR 1
#define IMC_CPUMASK_ATTR 2
#define IMC_NULL_ATTR 3
/* PMU Format attribute macros */
#define IMC_EVENT_OFFSET_MASK 0xffffffffULL
/*
* Device tree parser code detects IMC pmu support and
* registers new IMC pmus. This structure will hold the
* pmu functions, events, counter memory information
* and attrs for each imc pmu and will be referenced at
* the time of pmu registration.
*/
struct imc_pmu {
struct pmu pmu;
struct imc_mem_info *mem_info;
struct imc_events *events;
/*
* Attribute groups for the PMU. Slot 0 used for
* format attribute, slot 1 used for cpusmask attribute,
* slot 2 used for event attribute. Slot 3 keep as
* NULL.
*/
const struct attribute_group *attr_groups[4];
u32 counter_mem_size;
int domain;
/*
* flag to notify whether the memory is mmaped
* or allocated by kernel.
*/
bool imc_counter_mmaped;
};
/*
* Structure to hold id, lock and reference count for the imc events which
* are inited.
*/
struct imc_pmu_ref {
struct mutex lock;
unsigned int id;
int refc;
};
/*
* In-Memory Collection Counters type.
* Data comes from Device tree.
* Three device type are supported.
*/
enum {
IMC_TYPE_THREAD = 0x1,
IMC_TYPE_CORE = 0x4,
IMC_TYPE_CHIP = 0x10,
};
/*
* Domains for IMC PMUs
*/
#define IMC_DOMAIN_NEST 1
#define IMC_DOMAIN_CORE 2
#define IMC_DOMAIN_THREAD 3
extern int init_imc_pmu(struct device_node *parent,
struct imc_pmu *pmu_ptr, int pmu_id);
extern void thread_imc_disable(void);
extern int get_max_nest_dev(void);
#endif /* __ASM_POWERPC_IMC_PMU_H */