mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
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: Hendrik Brueckner <brueckner@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
committed by
Martin Schwidefsky
parent
dd127b3b97
commit
7e75fc3ff4
@@ -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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
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 {
|
|||||||
#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);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -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)
|
|||||||
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,
|
|||||||
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;
|
||||||
|
|||||||
Reference in New Issue
Block a user