* refs/heads/tmp-4b8fc9f UPSTREAM: locking: avoid passing around 'thread_info' in mutex debugging code ANDROID: arm64: fix undeclared 'init_thread_info' error UPSTREAM: kdb: use task_cpu() instead of task_thread_info()->cpu Linux 4.4.82 net: account for current skb length when deciding about UFO ipv4: Should use consistent conditional judgement for ip fragment in __ip_append_data and ip_finish_output mm/mempool: avoid KASAN marking mempool poison checks as use-after-free KVM: arm/arm64: Handle hva aging while destroying the vm sparc64: Prevent perf from running during super critical sections udp: consistently apply ufo or fragmentation revert "ipv4: Should use consistent conditional judgement for ip fragment in __ip_append_data and ip_finish_output" revert "net: account for current skb length when deciding about UFO" packet: fix tp_reserve race in packet_set_ring net: avoid skb_warn_bad_offload false positives on UFO tcp: fastopen: tcp_connect() must refresh the route net: sched: set xt_tgchk_param par.nft_compat as 0 in ipt_init_target bpf, s390: fix jit branch offset related to ldimm64 net: fix keepalive code vs TCP_FASTOPEN_CONNECT tcp: avoid setting cwnd to invalid ssthresh after cwnd reduction states ANDROID: keychord: Fix for a memory leak in keychord. ANDROID: keychord: Fix races in keychord_write. Use %zu to print resid (size_t). ANDROID: keychord: Fix a slab out-of-bounds read. Linux 4.4.81 workqueue: implicit ordered attribute should be overridable net: account for current skb length when deciding about UFO ipv4: Should use consistent conditional judgement for ip fragment in __ip_append_data and ip_finish_output mm: don't dereference struct page fields of invalid pages signal: protect SIGNAL_UNKILLABLE from unintentional clearing. lib/Kconfig.debug: fix frv build failure mm, slab: make sure that KMALLOC_MAX_SIZE will fit into MAX_ORDER ARM: 8632/1: ftrace: fix syscall name matching virtio_blk: fix panic in initialization error path drm/virtio: fix framebuffer sparse warning scsi: qla2xxx: Get mutex lock before checking optrom_state phy state machine: failsafe leave invalid RUNNING state x86/boot: Add missing declaration of string functions tg3: Fix race condition in tg3_get_stats64(). net: phy: dp83867: fix irq generation sh_eth: R8A7740 supports packet shecksumming wext: handle NULL extra data in iwe_stream_add_point better sparc64: Measure receiver forward progress to avoid send mondo timeout xen-netback: correctly schedule rate-limited queues net: phy: Fix PHY unbind crash net: phy: Correctly process PHY_HALTED in phy_stop_machine() net/mlx5: Fix command bad flow on command entry allocation failure sctp: fix the check for _sctp_walk_params and _sctp_walk_errors sctp: don't dereference ptr before leaving _sctp_walk_{params, errors}() dccp: fix a memleak for dccp_feat_init err process dccp: fix a memleak that dccp_ipv4 doesn't put reqsk properly dccp: fix a memleak that dccp_ipv6 doesn't put reqsk properly net: ethernet: nb8800: Handle all 4 RGMII modes identically ipv6: Don't increase IPSTATS_MIB_FRAGFAILS twice in ip6_fragment() packet: fix use-after-free in prb_retire_rx_blk_timer_expired() openvswitch: fix potential out of bound access in parse_ct mcs7780: Fix initialization when CONFIG_VMAP_STACK is enabled rtnetlink: allocate more memory for dev_set_mac_address() ipv4: initialize fib_trie prior to register_netdev_notifier call. ipv6: avoid overflow of offset in ip6_find_1stfragopt net: Zero terminate ifr_name in dev_ifname(). ipv4: ipv6: initialize treq->txhash in cookie_v[46]_check() saa7164: fix double fetch PCIe access condition drm: rcar-du: fix backport bug f2fs: sanity check checkpoint segno and blkoff media: lirc: LIRC_GET_REC_RESOLUTION should return microseconds mm, mprotect: flush TLB if potentially racing with a parallel reclaim leaving stale TLB entries iser-target: Avoid isert_conn->cm_id dereference in isert_login_recv_done iscsi-target: Fix delayed logout processing greater than SECONDS_FOR_LOGOUT_COMP iscsi-target: Fix initial login PDU asynchronous socket close OOPs iscsi-target: Fix early sk_data_ready LOGIN_FLAGS_READY race iscsi-target: Always wait for kthread_should_stop() before kthread exit target: Avoid mappedlun symlink creation during lun shutdown media: platform: davinci: return -EINVAL for VPFE_CMD_S_CCDC_RAW_PARAMS ioctl ARM: dts: armada-38x: Fix irq type for pca955 ext4: fix overflow caused by missing cast in ext4_resize_fs() ext4: fix SEEK_HOLE/SEEK_DATA for blocksize < pagesize mm/page_alloc: Remove kernel address exposure in free_reserved_area() KVM: async_pf: make rcu irq exit if not triggered from idle task ASoC: do not close shared backend dailink ALSA: hda - Fix speaker output from VAIO VPCL14M1R workqueue: restore WQ_UNBOUND/max_active==1 to be ordered libata: array underflow in ata_find_dev() ANDROID: binder: don't queue async transactions to thread. ANDROID: binder: don't enqueue death notifications to thread todo. ANDROID: binder: call poll_wait() unconditionally. android: configs: move quota-related configs to recommended BACKPORT: arm64: split thread_info from task stack UPSTREAM: arm64: assembler: introduce ldr_this_cpu UPSTREAM: arm64: make cpu number a percpu variable UPSTREAM: arm64: smp: prepare for smp_processor_id() rework BACKPORT: arm64: move sp_el0 and tpidr_el1 into cpu_suspend_ctx UPSTREAM: arm64: prep stack walkers for THREAD_INFO_IN_TASK UPSTREAM: arm64: unexport walk_stackframe UPSTREAM: arm64: traps: simplify die() and __die() UPSTREAM: arm64: factor out current_stack_pointer BACKPORT: arm64: asm-offsets: remove unused definitions UPSTREAM: arm64: thread_info remove stale items UPSTREAM: thread_info: include <current.h> for THREAD_INFO_IN_TASK UPSTREAM: thread_info: factor out restart_block UPSTREAM: kthread: Pin the stack via try_get_task_stack()/put_task_stack() in to_live_kthread() function UPSTREAM: sched/core: Add try_get_task_stack() and put_task_stack() UPSTREAM: sched/core: Allow putting thread_info into task_struct UPSTREAM: printk: when dumping regs, show the stack, not thread_info UPSTREAM: fix up initial thread stack pointer vs thread_info confusion UPSTREAM: Clarify naming of thread info/stack allocators ANDROID: sdcardfs: override credential for ioctl to lower fs Conflicts: android/configs/android-base.cfg arch/arm64/Kconfig arch/arm64/include/asm/suspend.h arch/arm64/kernel/head.S arch/arm64/kernel/smp.c arch/arm64/kernel/suspend.c arch/arm64/kernel/traps.c arch/arm64/mm/proc.S kernel/fork.c sound/soc/soc-pcm.c Change-Id: I273e216c94899a838bbd208391c6cbe20b2bf683 Signed-off-by: Blagovest Kolenichev <bkolenichev@codeaurora.org>
180 lines
4.3 KiB
C
180 lines
4.3 KiB
C
/* Copyright (c) 2013-2014, 2017 The Linux Foundation. All rights reserved.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 and
|
|
* only version 2 as published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
#include <linux/uaccess.h>
|
|
#include <linux/debugfs.h>
|
|
#include <linux/cpu.h>
|
|
#include <linux/tracepoint.h>
|
|
#include <trace/events/sched.h>
|
|
#define CREATE_TRACE_POINTS
|
|
#include "perf_trace_counters.h"
|
|
|
|
static unsigned int tp_pid_state;
|
|
|
|
DEFINE_PER_CPU(u32, cntenset_val);
|
|
DEFINE_PER_CPU(u32, previous_ccnt);
|
|
DEFINE_PER_CPU(u32[NUM_L1_CTRS], previous_l1_cnts);
|
|
DEFINE_PER_CPU(u32, old_pid);
|
|
DEFINE_PER_CPU(u32, hotplug_flag);
|
|
|
|
static int tracectr_cpu_hotplug_notifier(struct notifier_block *self,
|
|
unsigned long action, void *hcpu)
|
|
{
|
|
unsigned long cpu = (unsigned long)hcpu;
|
|
|
|
if ((action & (~CPU_TASKS_FROZEN)) == CPU_STARTING)
|
|
per_cpu(hotplug_flag, cpu) = 1;
|
|
|
|
return NOTIFY_OK;
|
|
}
|
|
|
|
static struct notifier_block tracectr_cpu_hotplug_notifier_block = {
|
|
.notifier_call = tracectr_cpu_hotplug_notifier,
|
|
};
|
|
|
|
static void setup_prev_cnts(u32 cpu, u32 cnten_val)
|
|
{
|
|
int i;
|
|
|
|
if (cnten_val & CC)
|
|
asm volatile("mrs %0, pmccntr_el0"
|
|
: "=r"(per_cpu(previous_ccnt, cpu)));
|
|
|
|
for (i = 0; i < NUM_L1_CTRS; i++) {
|
|
if (cnten_val & (1 << i)) {
|
|
/* Select */
|
|
asm volatile("msr pmselr_el0, %0" : : "r"(i));
|
|
isb();
|
|
/* Read value */
|
|
asm volatile("mrs %0, pmxevcntr_el0"
|
|
: "=r"(per_cpu(previous_l1_cnts[i], cpu)));
|
|
}
|
|
}
|
|
}
|
|
|
|
void tracectr_notifier(void *ignore, bool preempt,
|
|
struct task_struct *prev, struct task_struct *next)
|
|
{
|
|
u32 cnten_val;
|
|
int current_pid;
|
|
u32 cpu = task_cpu(next);
|
|
|
|
if (tp_pid_state != 1)
|
|
return;
|
|
current_pid = next->pid;
|
|
if (per_cpu(old_pid, cpu) != -1) {
|
|
asm volatile("mrs %0, pmcntenset_el0" : "=r" (cnten_val));
|
|
per_cpu(cntenset_val, cpu) = cnten_val;
|
|
/* Disable all the counters that were enabled */
|
|
asm volatile("msr pmcntenclr_el0, %0" : : "r" (cnten_val));
|
|
|
|
if (per_cpu(hotplug_flag, cpu) == 1) {
|
|
per_cpu(hotplug_flag, cpu) = 0;
|
|
setup_prev_cnts(cpu, cnten_val);
|
|
} else {
|
|
trace_sched_switch_with_ctrs(per_cpu(old_pid, cpu),
|
|
current_pid);
|
|
}
|
|
|
|
/* Enable all the counters that were disabled */
|
|
asm volatile("msr pmcntenset_el0, %0" : : "r" (cnten_val));
|
|
}
|
|
per_cpu(old_pid, cpu) = current_pid;
|
|
}
|
|
|
|
static void enable_tp_pid(void)
|
|
{
|
|
if (tp_pid_state == 0) {
|
|
tp_pid_state = 1;
|
|
register_trace_sched_switch(tracectr_notifier, NULL);
|
|
}
|
|
}
|
|
|
|
static void disable_tp_pid(void)
|
|
{
|
|
if (tp_pid_state == 1) {
|
|
tp_pid_state = 0;
|
|
unregister_trace_sched_switch(tracectr_notifier, NULL);
|
|
}
|
|
}
|
|
|
|
static ssize_t read_enabled_perftp_file_bool(struct file *file,
|
|
char __user *user_buf, size_t count, loff_t *ppos)
|
|
{
|
|
char buf[2];
|
|
buf[1] = '\n';
|
|
if (tp_pid_state == 0)
|
|
buf[0] = '0';
|
|
else
|
|
buf[0] = '1';
|
|
return simple_read_from_buffer(user_buf, count, ppos, buf, 2);
|
|
}
|
|
|
|
static ssize_t write_enabled_perftp_file_bool(struct file *file,
|
|
const char __user *user_buf, size_t count, loff_t *ppos)
|
|
{
|
|
char buf[32];
|
|
size_t buf_size;
|
|
|
|
buf[0] = 0;
|
|
buf_size = min(count, (sizeof(buf)-1));
|
|
if (copy_from_user(buf, user_buf, buf_size))
|
|
return -EFAULT;
|
|
switch (buf[0]) {
|
|
case 'y':
|
|
case 'Y':
|
|
case '1':
|
|
enable_tp_pid();
|
|
break;
|
|
case 'n':
|
|
case 'N':
|
|
case '0':
|
|
disable_tp_pid();
|
|
break;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
static const struct file_operations fops_perftp = {
|
|
.read = read_enabled_perftp_file_bool,
|
|
.write = write_enabled_perftp_file_bool,
|
|
.llseek = default_llseek,
|
|
};
|
|
|
|
int __init init_tracecounters(void)
|
|
{
|
|
struct dentry *dir;
|
|
struct dentry *file;
|
|
unsigned int value = 1;
|
|
int cpu;
|
|
|
|
dir = debugfs_create_dir("perf_debug_tp", NULL);
|
|
if (!dir)
|
|
return -ENOMEM;
|
|
file = debugfs_create_file("enabled", 0660, dir,
|
|
&value, &fops_perftp);
|
|
if (!file) {
|
|
debugfs_remove(dir);
|
|
return -ENOMEM;
|
|
}
|
|
for_each_possible_cpu(cpu)
|
|
per_cpu(old_pid, cpu) = -1;
|
|
register_cpu_notifier(&tracectr_cpu_hotplug_notifier_block);
|
|
return 0;
|
|
}
|
|
|
|
int __exit exit_tracecounters(void)
|
|
{
|
|
unregister_cpu_notifier(&tracectr_cpu_hotplug_notifier_block);
|
|
return 0;
|
|
}
|
|
late_initcall(init_tracecounters);
|