Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/tools/perf/arch/s390/util/auxtrace.c
51948 views
1
#include <errno.h>
2
#include <stdbool.h>
3
#include <stdlib.h>
4
#include <linux/kernel.h>
5
#include <linux/types.h>
6
#include <linux/bitops.h>
7
#include <linux/log2.h>
8
#include <linux/zalloc.h>
9
10
#include "../../util/evlist.h"
11
#include "../../util/auxtrace.h"
12
#include "../../util/evsel.h"
13
#include "../../util/record.h"
14
15
#define PERF_EVENT_CPUM_SF 0xB0000 /* Event: Basic-sampling */
16
#define PERF_EVENT_CPUM_SF_DIAG 0xBD000 /* Event: Combined-sampling */
17
#define DEFAULT_AUX_PAGES 128
18
#define DEFAULT_FREQ 4000
19
20
static void cpumsf_free(struct auxtrace_record *itr)
21
{
22
free(itr);
23
}
24
25
static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused,
26
struct evlist *evlist __maybe_unused)
27
{
28
return 0;
29
}
30
31
static int
32
cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused,
33
struct perf_session *session __maybe_unused,
34
struct perf_record_auxtrace_info *auxtrace_info __maybe_unused,
35
size_t priv_size __maybe_unused)
36
{
37
auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF;
38
return 0;
39
}
40
41
static unsigned long
42
cpumsf_reference(struct auxtrace_record *itr __maybe_unused)
43
{
44
return 0;
45
}
46
47
static int
48
cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused,
49
struct evlist *evlist __maybe_unused,
50
struct record_opts *opts)
51
{
52
unsigned int factor = 1;
53
unsigned int pages;
54
55
opts->full_auxtrace = true;
56
57
/*
58
* The AUX buffer size should be set properly to avoid
59
* overflow of samples if it is not set explicitly.
60
* DEFAULT_AUX_PAGES is an proper size when sampling frequency
61
* is DEFAULT_FREQ. It is expected to hold about 1/2 second
62
* of sampling data. The size used for AUX buffer will scale
63
* according to the specified frequency and DEFAULT_FREQ.
64
*/
65
if (!opts->auxtrace_mmap_pages) {
66
if (opts->user_freq != UINT_MAX)
67
factor = (opts->user_freq + DEFAULT_FREQ
68
- 1) / DEFAULT_FREQ;
69
pages = DEFAULT_AUX_PAGES * factor;
70
opts->auxtrace_mmap_pages = roundup_pow_of_two(pages);
71
}
72
73
return 0;
74
}
75
76
static int
77
cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
78
struct record_opts *opts __maybe_unused,
79
const char *str __maybe_unused)
80
{
81
return 0;
82
}
83
84
/*
85
* auxtrace_record__init is called when perf record
86
* check if the event really need auxtrace
87
*/
88
struct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
89
int *err)
90
{
91
struct auxtrace_record *aux;
92
struct evsel *pos;
93
int diagnose = 0;
94
95
*err = 0;
96
if (evlist->core.nr_entries == 0)
97
return NULL;
98
99
evlist__for_each_entry(evlist, pos) {
100
if (pos->core.attr.config == PERF_EVENT_CPUM_SF_DIAG) {
101
diagnose = 1;
102
pos->needs_auxtrace_mmap = true;
103
break;
104
}
105
}
106
107
if (!diagnose)
108
return NULL;
109
110
/* sampling in diagnose mode. alloc aux buffer */
111
aux = zalloc(sizeof(*aux));
112
if (aux == NULL) {
113
*err = -ENOMEM;
114
return NULL;
115
}
116
117
aux->parse_snapshot_options = cpumsf_parse_snapshot_options;
118
aux->recording_options = cpumsf_recording_options;
119
aux->info_priv_size = cpumsf_info_priv_size;
120
aux->info_fill = cpumsf_info_fill;
121
aux->free = cpumsf_free;
122
aux->reference = cpumsf_reference;
123
124
return aux;
125
}
126
127