Commit 7e75fc3f authored by Hendrik Brueckner's avatar Hendrik Brueckner Committed by Martin Schwidefsky

s390/cpum_sf: Add raw data sampling to support the diagnostic-sampling function

Also support the diagnostic-sampling function in addition to the basic-sampling
function.  Diagnostic-sampling data entries contain hardware model specific
sampling data and additional programs are required to analyze the data.

To deliver diagnostic-sampling, as well, as basis-sampling data entries to user
space, introduce support for sampling "raw data".  If this particular perf
sampling type (PERF_SAMPLE_RAW) is used, sampling data entries are copied
to user space.  External programs can then analyze these data.
Signed-off-by: default avatarHendrik Brueckner <brueckner@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent dd127b3b
...@@ -59,13 +59,15 @@ struct cpumf_ctr_info { ...@@ -59,13 +59,15 @@ struct cpumf_ctr_info {
/* QUERY SAMPLING INFORMATION block */ /* QUERY SAMPLING INFORMATION block */
struct hws_qsi_info_block { /* Bit(s) */ struct hws_qsi_info_block { /* Bit(s) */
unsigned int b0_13:14; /* 0-13: zeros */ unsigned int b0_13:14; /* 0-13: zeros */
unsigned int as:1; /* 14: sampling authorisation control*/ unsigned int as:1; /* 14: basic-sampling authorization */
unsigned int b15_21:7; /* 15-21: zeros */ unsigned int ad:1; /* 15: diag-sampling authorization */
unsigned int es:1; /* 22: sampling enable control */ unsigned int b16_21:6; /* 16-21: zeros */
unsigned int b23_29:7; /* 23-29: zeros */ unsigned int es:1; /* 22: basic-sampling enable control */
unsigned int cs:1; /* 30: sampling activation control */ unsigned int ed:1; /* 23: diag-sampling enable control */
unsigned int:1; /* 31: reserved */ unsigned int b24_29:6; /* 24-29: zeros */
unsigned int bsdes:16; /* 4-5: size of basic sampling entry */ unsigned int cs:1; /* 30: basic-sampling activation control */
unsigned int cd:1; /* 31: diag-sampling activation control */
unsigned int bsdes:16; /* 4-5: size of basic sampling entry */
unsigned int dsdes:16; /* 6-7: size of diagnostic sampling entry */ unsigned int dsdes:16; /* 6-7: size of diagnostic sampling entry */
unsigned long min_sampl_rate; /* 8-15: minimum sampling interval */ unsigned long min_sampl_rate; /* 8-15: minimum sampling interval */
unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/ unsigned long max_sampl_rate; /* 16-23: maximum sampling interval*/
...@@ -82,10 +84,11 @@ struct hws_lsctl_request_block { ...@@ -82,10 +84,11 @@ struct hws_lsctl_request_block {
unsigned int s:1; /* 0: maximum buffer indicator */ unsigned int s:1; /* 0: maximum buffer indicator */
unsigned int h:1; /* 1: part. level reserved for VM use*/ unsigned int h:1; /* 1: part. level reserved for VM use*/
unsigned long long b2_53:52;/* 2-53: zeros */ unsigned long long b2_53:52;/* 2-53: zeros */
unsigned int es:1; /* 54: sampling enable control */ unsigned int es:1; /* 54: basic-sampling enable control */
unsigned int b55_61:7; /* 55-61: - zeros */ unsigned int ed:1; /* 55: diag-sampling enable control */
unsigned int cs:1; /* 62: sampling activation control */ unsigned int b56_61:6; /* 56-61: - zeros */
unsigned int b63:1; /* 63: zero */ unsigned int cs:1; /* 62: basic-sampling activation control */
unsigned int cd:1; /* 63: diag-sampling activation control */
unsigned long interval; /* 8-15: sampling interval */ unsigned long interval; /* 8-15: sampling interval */
unsigned long tear; /* 16-23: TEAR contents */ unsigned long tear; /* 16-23: TEAR contents */
unsigned long dear; /* 24-31: DEAR contents */ unsigned long dear; /* 24-31: DEAR contents */
...@@ -96,8 +99,7 @@ struct hws_lsctl_request_block { ...@@ -96,8 +99,7 @@ struct hws_lsctl_request_block {
unsigned long rsvrd4; /* reserved */ unsigned long rsvrd4; /* reserved */
} __packed; } __packed;
struct hws_basic_entry {
struct hws_data_entry {
unsigned int def:16; /* 0-15 Data Entry Format */ unsigned int def:16; /* 0-15 Data Entry Format */
unsigned int R:4; /* 16-19 reserved */ unsigned int R:4; /* 16-19 reserved */
unsigned int U:4; /* 20-23 Number of unique instruct. */ unsigned int U:4; /* 20-23 Number of unique instruct. */
...@@ -114,6 +116,18 @@ struct hws_data_entry { ...@@ -114,6 +116,18 @@ struct hws_data_entry {
unsigned long long hpp; /* Host Program Parameter */ unsigned long long hpp; /* Host Program Parameter */
} __packed; } __packed;
struct hws_diag_entry {
unsigned int def:16; /* 0-15 Data Entry Format */
unsigned int R:14; /* 16-19 and 20-30 reserved */
unsigned int I:1; /* 31 entry valid or invalid */
u8 data[]; /* Machine-dependent sample data */
} __packed;
struct hws_combined_entry {
struct hws_basic_entry basic; /* Basic-sampling data entry */
struct hws_diag_entry diag; /* Diagnostic-sampling data entry */
} __packed;
struct hws_trailer_entry { struct hws_trailer_entry {
union { union {
struct { struct {
......
...@@ -52,15 +52,39 @@ struct perf_sf_sde_regs { ...@@ -52,15 +52,39 @@ struct perf_sf_sde_regs {
#define PERF_CPUM_CF_MAX_CTR 256 #define PERF_CPUM_CF_MAX_CTR 256
/* Perf PMU definitions for the sampling facility */ /* Perf PMU definitions for the sampling facility */
#define PERF_CPUM_SF_MAX_CTR 1 #define PERF_CPUM_SF_MAX_CTR 2
#define PERF_EVENT_CPUM_SF 0xB0000UL /* Raw event ID */ #define PERF_EVENT_CPUM_SF 0xB0000UL /* Event: Basic-sampling */
#define PERF_EVENT_CPUM_SF_DIAG 0xBD000UL /* Event: Combined-sampling */
#define PERF_CPUM_SF_BASIC_MODE 0x0001 /* Basic-sampling flag */
#define PERF_CPUM_SF_DIAG_MODE 0x0002 /* Diagnostic-sampling flag */
#define PERF_CPUM_SF_MODE_MASK (PERF_CPUM_SF_BASIC_MODE| \
PERF_CPUM_SF_DIAG_MODE)
#define REG_NONE 0 #define REG_NONE 0
#define REG_OVERFLOW 1 #define REG_OVERFLOW 1
#define OVERFLOW_REG(hwc) ((hwc)->extra_reg.config) #define OVERFLOW_REG(hwc) ((hwc)->extra_reg.config)
#define SFB_ALLOC_REG(hwc) ((hwc)->extra_reg.alloc) #define SFB_ALLOC_REG(hwc) ((hwc)->extra_reg.alloc)
#define RAWSAMPLE_REG(hwc) ((hwc)->config)
#define TEAR_REG(hwc) ((hwc)->last_tag) #define TEAR_REG(hwc) ((hwc)->last_tag)
#define SAMPL_RATE(hwc) ((hwc)->event_base) #define SAMPL_RATE(hwc) ((hwc)->event_base)
#define SAMPL_FLAGS(hwc) ((hwc)->config_base)
#define SAMPL_DIAG_MODE(hwc) (SAMPL_FLAGS(hwc) & PERF_CPUM_SF_DIAG_MODE)
/* Structure for sampling data entries to be passed as perf raw sample data
* to user space. Note that raw sample data must be aligned and, thus, might
* be padded with zeros.
*/
struct sf_raw_sample {
#define SF_RAW_SAMPLE_BASIC PERF_CPUM_SF_BASIC_MODE
#define SF_RAW_SAMPLE_DIAG PERF_CPUM_SF_DIAG_MODE
u64 format;
u32 size; /* Size of sf_raw_sample */
u16 bsdes; /* Basic-sampling data entry size */
u16 dsdes; /* Diagnostic-sampling data entry size */
struct hws_basic_entry basic; /* Basic-sampling data entry */
struct hws_diag_entry diag; /* Diagnostic-sampling data entry */
u8 padding[]; /* Padding to next multiple of 8 */
} __packed;
/* Perf hardware reserve and release functions */ /* Perf hardware reserve and release functions */
int perf_reserve_sampling(void); int perf_reserve_sampling(void);
......
This diff is collapsed.
...@@ -139,16 +139,21 @@ static void print_debug_sf(void) ...@@ -139,16 +139,21 @@ static void print_debug_sf(void)
int cpu = smp_processor_id(); int cpu = smp_processor_id();
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
if (qsi(&si)) { if (qsi(&si))
pr_err("CPU[%i]: CPM_SF: qsi failed\n");
return; return;
}
pr_info("CPU[%i]: CPM_SF: as=%i es=%i cs=%i bsdes=%i dsdes=%i" pr_info("CPU[%i] CPUM_SF: basic=%i diag=%i min=%i max=%i cpu_speed=%i\n",
" min=%i max=%i cpu_speed=%i tear=%p dear=%p\n", cpu, si.as, si.ad, si.min_sampl_rate, si.max_sampl_rate,
cpu, si.as, si.es, si.cs, si.bsdes, si.dsdes, si.cpu_speed);
si.min_sampl_rate, si.max_sampl_rate, si.cpu_speed,
si.tear, si.dear); if (si.as)
pr_info("CPU[%i] CPUM_SF: Basic-sampling: a=%i e=%i c=%i"
" bsdes=%i tear=%p dear=%p\n", cpu,
si.as, si.es, si.cs, si.bsdes, si.tear, si.dear);
if (si.ad)
pr_info("CPU[%i] CPUM_SF: Diagnostic-sampling: a=%i e=%i c=%i"
" dsdes=%i tear=%p dear=%p\n", cpu,
si.ad, si.ed, si.cd, si.dsdes, si.tear, si.dear);
} }
void perf_event_print_debug(void) void perf_event_print_debug(void)
......
...@@ -799,7 +799,7 @@ static void worker_on_interrupt(unsigned int cpu) ...@@ -799,7 +799,7 @@ static void worker_on_interrupt(unsigned int cpu)
static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt, static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt,
unsigned long *dear) unsigned long *dear)
{ {
struct hws_data_entry *sample_data_ptr; struct hws_basic_entry *sample_data_ptr;
unsigned long *trailer; unsigned long *trailer;
trailer = trailer_entry_ptr(*sdbt); trailer = trailer_entry_ptr(*sdbt);
...@@ -809,7 +809,7 @@ static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt, ...@@ -809,7 +809,7 @@ static void add_samples_to_oprofile(unsigned int cpu, unsigned long *sdbt,
trailer = dear; trailer = dear;
} }
sample_data_ptr = (struct hws_data_entry *)(*sdbt); sample_data_ptr = (struct hws_basic_entry *)(*sdbt);
while ((unsigned long *)sample_data_ptr < trailer) { while ((unsigned long *)sample_data_ptr < trailer) {
struct pt_regs *regs = NULL; struct pt_regs *regs = NULL;
......
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