Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"Misc fixes: PMU driver corner cases, tooling fixes, and an 'AUX'
(Intel PT) race related core fix"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/intel/cqm: Do not access cpu_data() from CPU_UP_PREPARE handler
perf/x86/intel: Fix memory leak on hot-plug allocation fail
perf: Fix PERF_EVENT_IOC_PERIOD migration race
perf: Fix double-free of the AUX buffer
perf: Fix fasync handling on inherited events
perf tools: Fix test build error when bindir contains double slash
perf stat: Fix transaction lenght metrics
perf: Fix running time accounting

+96 -46
+16 -7
arch/x86/kernel/cpu/perf_event_intel.c
··· 2534 2534 if (x86_pmu.extra_regs || x86_pmu.lbr_sel_map) { 2535 2535 cpuc->shared_regs = allocate_shared_regs(cpu); 2536 2536 if (!cpuc->shared_regs) 2537 - return NOTIFY_BAD; 2537 + goto err; 2538 2538 } 2539 2539 2540 2540 if (x86_pmu.flags & PMU_FL_EXCL_CNTRS) { ··· 2542 2542 2543 2543 cpuc->constraint_list = kzalloc(sz, GFP_KERNEL); 2544 2544 if (!cpuc->constraint_list) 2545 - return NOTIFY_BAD; 2545 + goto err_shared_regs; 2546 2546 2547 2547 cpuc->excl_cntrs = allocate_excl_cntrs(cpu); 2548 - if (!cpuc->excl_cntrs) { 2549 - kfree(cpuc->constraint_list); 2550 - kfree(cpuc->shared_regs); 2551 - return NOTIFY_BAD; 2552 - } 2548 + if (!cpuc->excl_cntrs) 2549 + goto err_constraint_list; 2550 + 2553 2551 cpuc->excl_thread_id = 0; 2554 2552 } 2555 2553 2556 2554 return NOTIFY_OK; 2555 + 2556 + err_constraint_list: 2557 + kfree(cpuc->constraint_list); 2558 + cpuc->constraint_list = NULL; 2559 + 2560 + err_shared_regs: 2561 + kfree(cpuc->shared_regs); 2562 + cpuc->shared_regs = NULL; 2563 + 2564 + err: 2565 + return NOTIFY_BAD; 2557 2566 } 2558 2567 2559 2568 static void intel_pmu_cpu_starting(int cpu)
+3 -5
arch/x86/kernel/cpu/perf_event_intel_cqm.c
··· 1255 1255 cpumask_set_cpu(cpu, &cqm_cpumask); 1256 1256 } 1257 1257 1258 - static void intel_cqm_cpu_prepare(unsigned int cpu) 1258 + static void intel_cqm_cpu_starting(unsigned int cpu) 1259 1259 { 1260 1260 struct intel_pqr_state *state = &per_cpu(pqr_state, cpu); 1261 1261 struct cpuinfo_x86 *c = &cpu_data(cpu); ··· 1296 1296 unsigned int cpu = (unsigned long)hcpu; 1297 1297 1298 1298 switch (action & ~CPU_TASKS_FROZEN) { 1299 - case CPU_UP_PREPARE: 1300 - intel_cqm_cpu_prepare(cpu); 1301 - break; 1302 1299 case CPU_DOWN_PREPARE: 1303 1300 intel_cqm_cpu_exit(cpu); 1304 1301 break; 1305 1302 case CPU_STARTING: 1303 + intel_cqm_cpu_starting(cpu); 1306 1304 cqm_pick_event_reader(cpu); 1307 1305 break; 1308 1306 } ··· 1371 1373 goto out; 1372 1374 1373 1375 for_each_online_cpu(i) { 1374 - intel_cqm_cpu_prepare(i); 1376 + intel_cqm_cpu_starting(i); 1375 1377 cqm_pick_event_reader(i); 1376 1378 } 1377 1379
+67 -24
kernel/events/core.c
··· 1868 1868 1869 1869 perf_pmu_disable(event->pmu); 1870 1870 1871 - event->tstamp_running += tstamp - event->tstamp_stopped; 1872 - 1873 1871 perf_set_shadow_time(event, ctx, tstamp); 1874 1872 1875 1873 perf_log_itrace_start(event); ··· 1878 1880 ret = -EAGAIN; 1879 1881 goto out; 1880 1882 } 1883 + 1884 + event->tstamp_running += tstamp - event->tstamp_stopped; 1881 1885 1882 1886 if (!is_software_event(event)) 1883 1887 cpuctx->active_oncpu++; ··· 3958 3958 perf_event_for_each_child(sibling, func); 3959 3959 } 3960 3960 3961 - static int perf_event_period(struct perf_event *event, u64 __user *arg) 3962 - { 3963 - struct perf_event_context *ctx = event->ctx; 3964 - int ret = 0, active; 3961 + struct period_event { 3962 + struct perf_event *event; 3965 3963 u64 value; 3964 + }; 3966 3965 3967 - if (!is_sampling_event(event)) 3968 - return -EINVAL; 3966 + static int __perf_event_period(void *info) 3967 + { 3968 + struct period_event *pe = info; 3969 + struct perf_event *event = pe->event; 3970 + struct perf_event_context *ctx = event->ctx; 3971 + u64 value = pe->value; 3972 + bool active; 3969 3973 3970 - if (copy_from_user(&value, arg, sizeof(value))) 3971 - return -EFAULT; 3972 - 3973 - if (!value) 3974 - return -EINVAL; 3975 - 3976 - raw_spin_lock_irq(&ctx->lock); 3974 + raw_spin_lock(&ctx->lock); 3977 3975 if (event->attr.freq) { 3978 - if (value > sysctl_perf_event_sample_rate) { 3979 - ret = -EINVAL; 3980 - goto unlock; 3981 - } 3982 - 3983 3976 event->attr.sample_freq = value; 3984 3977 } else { 3985 3978 event->attr.sample_period = value; ··· 3991 3998 event->pmu->start(event, PERF_EF_RELOAD); 3992 3999 perf_pmu_enable(ctx->pmu); 3993 4000 } 4001 + raw_spin_unlock(&ctx->lock); 3994 4002 3995 - unlock: 4003 + return 0; 4004 + } 4005 + 4006 + static int perf_event_period(struct perf_event *event, u64 __user *arg) 4007 + { 4008 + struct period_event pe = { .event = event, }; 4009 + struct perf_event_context *ctx = event->ctx; 4010 + struct task_struct *task; 4011 + u64 value; 4012 + 4013 + if (!is_sampling_event(event)) 4014 + return -EINVAL; 4015 + 4016 + if (copy_from_user(&value, arg, sizeof(value))) 4017 + return -EFAULT; 4018 + 4019 + if (!value) 4020 + return -EINVAL; 4021 + 4022 + if (event->attr.freq && value > sysctl_perf_event_sample_rate) 4023 + return -EINVAL; 4024 + 4025 + task = ctx->task; 4026 + pe.value = value; 4027 + 4028 + if (!task) { 4029 + cpu_function_call(event->cpu, __perf_event_period, &pe); 4030 + return 0; 4031 + } 4032 + 4033 + retry: 4034 + if (!task_function_call(task, __perf_event_period, &pe)) 4035 + return 0; 4036 + 4037 + raw_spin_lock_irq(&ctx->lock); 4038 + if (ctx->is_active) { 4039 + raw_spin_unlock_irq(&ctx->lock); 4040 + task = ctx->task; 4041 + goto retry; 4042 + } 4043 + 4044 + __perf_event_period(&pe); 3996 4045 raw_spin_unlock_irq(&ctx->lock); 3997 4046 3998 - return ret; 4047 + return 0; 3999 4048 } 4000 4049 4001 4050 static const struct file_operations perf_fops; ··· 4775 4740 * to user-space before waking everybody up. 4776 4741 */ 4777 4742 4743 + static inline struct fasync_struct **perf_event_fasync(struct perf_event *event) 4744 + { 4745 + /* only the parent has fasync state */ 4746 + if (event->parent) 4747 + event = event->parent; 4748 + return &event->fasync; 4749 + } 4750 + 4778 4751 void perf_event_wakeup(struct perf_event *event) 4779 4752 { 4780 4753 ring_buffer_wakeup(event); 4781 4754 4782 4755 if (event->pending_kill) { 4783 - kill_fasync(&event->fasync, SIGIO, event->pending_kill); 4756 + kill_fasync(perf_event_fasync(event), SIGIO, event->pending_kill); 4784 4757 event->pending_kill = 0; 4785 4758 } 4786 4759 } ··· 6167 6124 else 6168 6125 perf_event_output(event, data, regs); 6169 6126 6170 - if (event->fasync && event->pending_kill) { 6127 + if (*perf_event_fasync(event) && event->pending_kill) { 6171 6128 event->pending_wakeup = 1; 6172 6129 irq_work_queue(&event->pending); 6173 6130 }
+6 -4
kernel/events/ring_buffer.c
··· 559 559 rb->aux_priv = NULL; 560 560 } 561 561 562 - for (pg = 0; pg < rb->aux_nr_pages; pg++) 563 - rb_free_aux_page(rb, pg); 562 + if (rb->aux_nr_pages) { 563 + for (pg = 0; pg < rb->aux_nr_pages; pg++) 564 + rb_free_aux_page(rb, pg); 564 565 565 - kfree(rb->aux_pages); 566 - rb->aux_nr_pages = 0; 566 + kfree(rb->aux_pages); 567 + rb->aux_nr_pages = 0; 568 + } 567 569 } 568 570 569 571 void rb_free_aux(struct ring_buffer *rb)
+1 -1
tools/perf/config/Makefile
··· 638 638 prefix ?= $(HOME) 639 639 endif 640 640 bindir_relative = bin 641 - bindir = $(prefix)/$(bindir_relative) 641 + bindir = $(abspath $(prefix)/$(bindir_relative)) 642 642 mandir = share/man 643 643 infodir = share/info 644 644 perfexecdir = libexec/perf-core
+3 -5
tools/perf/util/stat-shadow.c
··· 85 85 else if (perf_evsel__match(counter, HARDWARE, HW_CPU_CYCLES)) 86 86 update_stats(&runtime_cycles_stats[ctx][cpu], count[0]); 87 87 else if (perf_stat_evsel__is(counter, CYCLES_IN_TX)) 88 - update_stats(&runtime_transaction_stats[ctx][cpu], count[0]); 88 + update_stats(&runtime_cycles_in_tx_stats[ctx][cpu], count[0]); 89 89 else if (perf_stat_evsel__is(counter, TRANSACTION_START)) 90 90 update_stats(&runtime_transaction_stats[ctx][cpu], count[0]); 91 91 else if (perf_stat_evsel__is(counter, ELISION_START)) ··· 398 398 " # %5.2f%% aborted cycles ", 399 399 100.0 * ((total2-avg) / total)); 400 400 } else if (perf_stat_evsel__is(evsel, TRANSACTION_START) && 401 - avg > 0 && 402 401 runtime_cycles_in_tx_stats[ctx][cpu].n != 0) { 403 402 total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]); 404 403 405 - if (total) 404 + if (avg) 406 405 ratio = total / avg; 407 406 408 407 fprintf(out, " # %8.0f cycles / transaction ", ratio); 409 408 } else if (perf_stat_evsel__is(evsel, ELISION_START) && 410 - avg > 0 && 411 409 runtime_cycles_in_tx_stats[ctx][cpu].n != 0) { 412 410 total = avg_stats(&runtime_cycles_in_tx_stats[ctx][cpu]); 413 411 414 - if (total) 412 + if (avg) 415 413 ratio = total / avg; 416 414 417 415 fprintf(out, " # %8.0f cycles / elision ", ratio);