Skip to content

Commit 0dcb7b6

Browse files
committed
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Ingo Molnar: "Mostly tooling fixes, but also start/stop filter related fixes, a perf event read() fix, a fix uncovered by fuzzing, and an uprobes leak fix" * 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: perf/core: Check return value of the perf_event_read() IPI perf/core: Enable mapping of the stop filters perf/core: Update filters only on executable mmap perf/core: Fix file name handling for start/stop filters perf/core: Fix event_function_local() uprobes: Fix the memcg accounting perf intel-pt: Fix occasional decoding errors when tracing system-wide tools: Sync kvm related header files for arm64 and s390 perf probe: Release resources on error when handling exit paths perf probe: Check for dup and fdopen failures perf symbols: Fix annotation of objects with debuginfo files perf script: Don't disable use_callchain if input is pipe perf script: Show proper message when failed list scripts perf jitdump: Add the right header to get the major()/minor() definitions perf ppc64le: Fix build failure when libelf is not present perf tools mem: Fix -t store option for record command perf intel-pt: Fix ip compression
2 parents bd3fd45 + 71e7bc2 commit 0dcb7b6

File tree

14 files changed

+207
-69
lines changed

14 files changed

+207
-69
lines changed

kernel/events/core.c

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -242,18 +242,6 @@ static int event_function(void *info)
242242
return ret;
243243
}
244244

245-
static void event_function_local(struct perf_event *event, event_f func, void *data)
246-
{
247-
struct event_function_struct efs = {
248-
.event = event,
249-
.func = func,
250-
.data = data,
251-
};
252-
253-
int ret = event_function(&efs);
254-
WARN_ON_ONCE(ret);
255-
}
256-
257245
static void event_function_call(struct perf_event *event, event_f func, void *data)
258246
{
259247
struct perf_event_context *ctx = event->ctx;
@@ -303,6 +291,54 @@ static void event_function_call(struct perf_event *event, event_f func, void *da
303291
raw_spin_unlock_irq(&ctx->lock);
304292
}
305293

294+
/*
295+
* Similar to event_function_call() + event_function(), but hard assumes IRQs
296+
* are already disabled and we're on the right CPU.
297+
*/
298+
static void event_function_local(struct perf_event *event, event_f func, void *data)
299+
{
300+
struct perf_event_context *ctx = event->ctx;
301+
struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
302+
struct task_struct *task = READ_ONCE(ctx->task);
303+
struct perf_event_context *task_ctx = NULL;
304+
305+
WARN_ON_ONCE(!irqs_disabled());
306+
307+
if (task) {
308+
if (task == TASK_TOMBSTONE)
309+
return;
310+
311+
task_ctx = ctx;
312+
}
313+
314+
perf_ctx_lock(cpuctx, task_ctx);
315+
316+
task = ctx->task;
317+
if (task == TASK_TOMBSTONE)
318+
goto unlock;
319+
320+
if (task) {
321+
/*
322+
* We must be either inactive or active and the right task,
323+
* otherwise we're screwed, since we cannot IPI to somewhere
324+
* else.
325+
*/
326+
if (ctx->is_active) {
327+
if (WARN_ON_ONCE(task != current))
328+
goto unlock;
329+
330+
if (WARN_ON_ONCE(cpuctx->task_ctx != ctx))
331+
goto unlock;
332+
}
333+
} else {
334+
WARN_ON_ONCE(&cpuctx->ctx != ctx);
335+
}
336+
337+
func(event, cpuctx, ctx, data);
338+
unlock:
339+
perf_ctx_unlock(cpuctx, task_ctx);
340+
}
341+
306342
#define PERF_FLAG_ALL (PERF_FLAG_FD_NO_GROUP |\
307343
PERF_FLAG_FD_OUTPUT |\
308344
PERF_FLAG_PID_CGROUP |\
@@ -3513,9 +3549,10 @@ static int perf_event_read(struct perf_event *event, bool group)
35133549
.group = group,
35143550
.ret = 0,
35153551
};
3516-
smp_call_function_single(event->oncpu,
3517-
__perf_event_read, &data, 1);
3518-
ret = data.ret;
3552+
ret = smp_call_function_single(event->oncpu, __perf_event_read, &data, 1);
3553+
/* The event must have been read from an online CPU: */
3554+
WARN_ON_ONCE(ret);
3555+
ret = ret ? : data.ret;
35193556
} else if (event->state == PERF_EVENT_STATE_INACTIVE) {
35203557
struct perf_event_context *ctx = event->ctx;
35213558
unsigned long flags;
@@ -6583,15 +6620,6 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event)
65836620
kfree(buf);
65846621
}
65856622

6586-
/*
6587-
* Whether this @filter depends on a dynamic object which is not loaded
6588-
* yet or its load addresses are not known.
6589-
*/
6590-
static bool perf_addr_filter_needs_mmap(struct perf_addr_filter *filter)
6591-
{
6592-
return filter->filter && filter->inode;
6593-
}
6594-
65956623
/*
65966624
* Check whether inode and address range match filter criteria.
65976625
*/
@@ -6653,6 +6681,13 @@ static void perf_addr_filters_adjust(struct vm_area_struct *vma)
66536681
struct perf_event_context *ctx;
66546682
int ctxn;
66556683

6684+
/*
6685+
* Data tracing isn't supported yet and as such there is no need
6686+
* to keep track of anything that isn't related to executable code:
6687+
*/
6688+
if (!(vma->vm_flags & VM_EXEC))
6689+
return;
6690+
66566691
rcu_read_lock();
66576692
for_each_task_context_nr(ctxn) {
66586693
ctx = rcu_dereference(current->perf_event_ctxp[ctxn]);
@@ -7805,7 +7840,11 @@ static void perf_event_addr_filters_apply(struct perf_event *event)
78057840
list_for_each_entry(filter, &ifh->list, entry) {
78067841
event->addr_filters_offs[count] = 0;
78077842

7808-
if (perf_addr_filter_needs_mmap(filter))
7843+
/*
7844+
* Adjust base offset if the filter is associated to a binary
7845+
* that needs to be mapped:
7846+
*/
7847+
if (filter->inode)
78097848
event->addr_filters_offs[count] =
78107849
perf_addr_filter_apply(filter, mm);
78117850

@@ -7936,8 +7975,10 @@ perf_event_parse_addr_filter(struct perf_event *event, char *fstr,
79367975
goto fail;
79377976
}
79387977

7939-
if (token == IF_SRC_FILE) {
7940-
filename = match_strdup(&args[2]);
7978+
if (token == IF_SRC_FILE || token == IF_SRC_FILEADDR) {
7979+
int fpos = filter->range ? 2 : 1;
7980+
7981+
filename = match_strdup(&args[fpos]);
79417982
if (!filename) {
79427983
ret = -ENOMEM;
79437984
goto fail;

kernel/events/uprobes.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,10 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
172172
mmu_notifier_invalidate_range_start(mm, mmun_start, mmun_end);
173173
err = -EAGAIN;
174174
ptep = page_check_address(page, mm, addr, &ptl, 0);
175-
if (!ptep)
175+
if (!ptep) {
176+
mem_cgroup_cancel_charge(kpage, memcg, false);
176177
goto unlock;
178+
}
177179

178180
get_page(kpage);
179181
page_add_new_anon_rmap(kpage, vma, addr, false);
@@ -200,7 +202,6 @@ static int __replace_page(struct vm_area_struct *vma, unsigned long addr,
200202

201203
err = 0;
202204
unlock:
203-
mem_cgroup_cancel_charge(kpage, memcg, false);
204205
mmu_notifier_invalidate_range_end(mm, mmun_start, mmun_end);
205206
unlock_page(page);
206207
return err;

tools/arch/arm64/include/uapi/asm/kvm.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,11 @@ struct kvm_regs {
8787
/* Supported VGICv3 address types */
8888
#define KVM_VGIC_V3_ADDR_TYPE_DIST 2
8989
#define KVM_VGIC_V3_ADDR_TYPE_REDIST 3
90+
#define KVM_VGIC_ITS_ADDR_TYPE 4
9091

9192
#define KVM_VGIC_V3_DIST_SIZE SZ_64K
9293
#define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
94+
#define KVM_VGIC_V3_ITS_SIZE (2 * SZ_64K)
9395

9496
#define KVM_ARM_VCPU_POWER_OFF 0 /* CPU is started in OFF state */
9597
#define KVM_ARM_VCPU_EL1_32BIT 1 /* CPU running a 32bit VM */

tools/arch/s390/include/uapi/asm/kvm.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,47 @@ struct kvm_s390_vm_cpu_machine {
9393
__u64 fac_list[256];
9494
};
9595

96+
#define KVM_S390_VM_CPU_PROCESSOR_FEAT 2
97+
#define KVM_S390_VM_CPU_MACHINE_FEAT 3
98+
99+
#define KVM_S390_VM_CPU_FEAT_NR_BITS 1024
100+
#define KVM_S390_VM_CPU_FEAT_ESOP 0
101+
#define KVM_S390_VM_CPU_FEAT_SIEF2 1
102+
#define KVM_S390_VM_CPU_FEAT_64BSCAO 2
103+
#define KVM_S390_VM_CPU_FEAT_SIIF 3
104+
#define KVM_S390_VM_CPU_FEAT_GPERE 4
105+
#define KVM_S390_VM_CPU_FEAT_GSLS 5
106+
#define KVM_S390_VM_CPU_FEAT_IB 6
107+
#define KVM_S390_VM_CPU_FEAT_CEI 7
108+
#define KVM_S390_VM_CPU_FEAT_IBS 8
109+
#define KVM_S390_VM_CPU_FEAT_SKEY 9
110+
#define KVM_S390_VM_CPU_FEAT_CMMA 10
111+
#define KVM_S390_VM_CPU_FEAT_PFMFI 11
112+
#define KVM_S390_VM_CPU_FEAT_SIGPIF 12
113+
struct kvm_s390_vm_cpu_feat {
114+
__u64 feat[16];
115+
};
116+
117+
#define KVM_S390_VM_CPU_PROCESSOR_SUBFUNC 4
118+
#define KVM_S390_VM_CPU_MACHINE_SUBFUNC 5
119+
/* for "test bit" instructions MSB 0 bit ordering, for "query" raw blocks */
120+
struct kvm_s390_vm_cpu_subfunc {
121+
__u8 plo[32]; /* always */
122+
__u8 ptff[16]; /* with TOD-clock steering */
123+
__u8 kmac[16]; /* with MSA */
124+
__u8 kmc[16]; /* with MSA */
125+
__u8 km[16]; /* with MSA */
126+
__u8 kimd[16]; /* with MSA */
127+
__u8 klmd[16]; /* with MSA */
128+
__u8 pckmo[16]; /* with MSA3 */
129+
__u8 kmctr[16]; /* with MSA4 */
130+
__u8 kmf[16]; /* with MSA4 */
131+
__u8 kmo[16]; /* with MSA4 */
132+
__u8 pcc[16]; /* with MSA4 */
133+
__u8 ppno[16]; /* with MSA5 */
134+
__u8 reserved[1824];
135+
};
136+
96137
/* kvm attributes for crypto */
97138
#define KVM_S390_VM_CRYPTO_ENABLE_AES_KW 0
98139
#define KVM_S390_VM_CRYPTO_ENABLE_DEA_KW 1

tools/arch/s390/include/uapi/asm/sie.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
exit_code_ipa0(0xB2, 0x4c, "TAR"), \
141141
exit_code_ipa0(0xB2, 0x50, "CSP"), \
142142
exit_code_ipa0(0xB2, 0x54, "MVPG"), \
143+
exit_code_ipa0(0xB2, 0x56, "STHYI"), \
143144
exit_code_ipa0(0xB2, 0x58, "BSG"), \
144145
exit_code_ipa0(0xB2, 0x5a, "BSA"), \
145146
exit_code_ipa0(0xB2, 0x5f, "CHSC"), \

tools/perf/arch/powerpc/util/sym-handling.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ void arch__fix_tev_from_maps(struct perf_probe_event *pev,
9797
}
9898
}
9999

100+
#ifdef HAVE_LIBELF_SUPPORT
100101
void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
101102
int ntevs)
102103
{
@@ -118,5 +119,6 @@ void arch__post_process_probe_trace_events(struct perf_probe_event *pev,
118119
}
119120
}
120121
}
122+
#endif /* HAVE_LIBELF_SUPPORT */
121123

122124
#endif

tools/perf/arch/x86/util/intel-pt.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
501501
struct intel_pt_recording *ptr =
502502
container_of(itr, struct intel_pt_recording, itr);
503503
struct perf_pmu *intel_pt_pmu = ptr->intel_pt_pmu;
504-
bool have_timing_info;
504+
bool have_timing_info, need_immediate = false;
505505
struct perf_evsel *evsel, *intel_pt_evsel = NULL;
506506
const struct cpu_map *cpus = evlist->cpus;
507507
bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
@@ -655,6 +655,7 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
655655
ptr->have_sched_switch = 3;
656656
} else {
657657
opts->record_switch_events = true;
658+
need_immediate = true;
658659
if (cpu_wide)
659660
ptr->have_sched_switch = 3;
660661
else
@@ -700,6 +701,9 @@ static int intel_pt_recording_options(struct auxtrace_record *itr,
700701
tracking_evsel->attr.freq = 0;
701702
tracking_evsel->attr.sample_period = 1;
702703

704+
if (need_immediate)
705+
tracking_evsel->immediate = true;
706+
703707
/* In per-cpu case, always need the time of mmap events etc */
704708
if (!cpu_map__empty(cpus)) {
705709
perf_evsel__set_sample_bit(tracking_evsel, TIME);

tools/perf/builtin-mem.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ static int __cmd_record(int argc, const char **argv, struct perf_mem *mem)
8888
if (mem->operation & MEM_OPERATION_LOAD)
8989
perf_mem_events[PERF_MEM_EVENTS__LOAD].record = true;
9090

91+
if (mem->operation & MEM_OPERATION_STORE)
92+
perf_mem_events[PERF_MEM_EVENTS__STORE].record = true;
93+
9194
if (perf_mem_events[PERF_MEM_EVENTS__LOAD].record)
9295
rec_argv[i++] = "-W";
9396

tools/perf/builtin-script.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -371,14 +371,16 @@ static int perf_session__check_output_opt(struct perf_session *session)
371371

372372
if (!no_callchain) {
373373
bool use_callchain = false;
374+
bool not_pipe = false;
374375

375376
evlist__for_each_entry(session->evlist, evsel) {
377+
not_pipe = true;
376378
if (evsel->attr.sample_type & PERF_SAMPLE_CALLCHAIN) {
377379
use_callchain = true;
378380
break;
379381
}
380382
}
381-
if (!use_callchain)
383+
if (not_pipe && !use_callchain)
382384
symbol_conf.use_callchain = false;
383385
}
384386

@@ -1690,8 +1692,13 @@ static int list_available_scripts(const struct option *opt __maybe_unused,
16901692
snprintf(scripts_path, MAXPATHLEN, "%s/scripts", get_argv_exec_path());
16911693

16921694
scripts_dir = opendir(scripts_path);
1693-
if (!scripts_dir)
1694-
return -1;
1695+
if (!scripts_dir) {
1696+
fprintf(stdout,
1697+
"open(%s) failed.\n"
1698+
"Check \"PERF_EXEC_PATH\" env to set scripts dir.\n",
1699+
scripts_path);
1700+
exit(-1);
1701+
}
16951702

16961703
for_each_lang(scripts_path, scripts_dir, lang_dirent) {
16971704
snprintf(lang_path, MAXPATHLEN, "%s/%s/bin", scripts_path,

0 commit comments

Comments
 (0)