From: Viresh K. <vir...@li...> - 2021-01-14 11:59:12
|
Hello, The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove oprofile and dcookies (whose only user is oprofile) support from the kernel. This was suggested here [1] earlier. This is build/boot tested by kernel test robot (Intel) and Linaro's Tuxmake[2] for a lot of architectures and no failures were reported. -- Viresh [1] https://lore.kernel.org/lkml/CAHk-=whw...@ma.../ [2] https://lwn.net/Articles/841624/ Viresh Kumar (18): arch: alpha: Remove CONFIG_OPROFILE support arch: arm: Remove CONFIG_OPROFILE support arch: arc: Remove CONFIG_OPROFILE support arch: hexagon: Don't select HAVE_OPROFILE arch: ia64: Remove CONFIG_OPROFILE support arch: ia64: Remove rest of perfmon support arch: microblaze: Remove CONFIG_OPROFILE support arch: mips: Remove CONFIG_OPROFILE support arch: parisc: Remove CONFIG_OPROFILE support arch: powerpc: Stop building and using oprofile arch: powerpc: Remove oprofile arch: s390: Remove CONFIG_OPROFILE support arch: sh: Remove CONFIG_OPROFILE support arch: sparc: Remove CONFIG_OPROFILE support arch: x86: Remove CONFIG_OPROFILE support arch: xtensa: Remove CONFIG_OPROFILE support drivers: Remove CONFIG_OPROFILE support fs: Remove dcookies support Documentation/RCU/NMI-RCU.rst | 3 +- .../admin-guide/kernel-parameters.txt | 14 - Documentation/kbuild/makefiles.rst | 1 - Documentation/process/magic-number.rst | 1 - .../it_IT/process/magic-number.rst | 1 - .../zh_CN/process/magic-number.rst | 1 - MAINTAINERS | 11 - arch/Kconfig | 32 - arch/alpha/Kconfig | 1 - arch/alpha/Makefile | 1 - arch/alpha/oprofile/Makefile | 20 - arch/alpha/oprofile/common.c | 189 -- arch/alpha/oprofile/op_impl.h | 55 - arch/alpha/oprofile/op_model_ev4.c | 114 -- arch/alpha/oprofile/op_model_ev5.c | 209 -- arch/alpha/oprofile/op_model_ev6.c | 101 - arch/alpha/oprofile/op_model_ev67.c | 261 --- arch/arc/Kconfig | 1 - arch/arc/Makefile | 2 - arch/arc/oprofile/Makefile | 10 - arch/arc/oprofile/common.c | 23 - arch/arm/Kconfig | 1 - arch/arm/Makefile | 2 - arch/arm/configs/bcm2835_defconfig | 1 - arch/arm/configs/cns3420vb_defconfig | 1 - arch/arm/configs/corgi_defconfig | 1 - arch/arm/configs/imx_v4_v5_defconfig | 1 - arch/arm/configs/keystone_defconfig | 1 - arch/arm/configs/multi_v5_defconfig | 1 - arch/arm/configs/mv78xx0_defconfig | 1 - arch/arm/configs/mvebu_v5_defconfig | 1 - arch/arm/configs/omap1_defconfig | 1 - arch/arm/configs/omap2plus_defconfig | 1 - arch/arm/configs/orion5x_defconfig | 1 - arch/arm/configs/pxa_defconfig | 1 - arch/arm/configs/qcom_defconfig | 1 - arch/arm/configs/socfpga_defconfig | 1 - arch/arm/configs/spitz_defconfig | 1 - arch/arm/configs/vexpress_defconfig | 1 - arch/arm/oprofile/Makefile | 14 - arch/arm/oprofile/common.c | 132 -- arch/hexagon/Kconfig | 1 - arch/ia64/Kconfig | 1 - arch/ia64/Makefile | 1 - arch/ia64/configs/bigsur_defconfig | 1 - arch/ia64/include/asm/hw_irq.h | 1 - arch/ia64/include/asm/perfmon.h | 111 -- arch/ia64/include/uapi/asm/perfmon.h | 178 -- .../include/uapi/asm/perfmon_default_smpl.h | 84 - arch/ia64/kernel/palinfo.c | 41 - arch/ia64/kernel/perfmon_default_smpl.c | 297 --- arch/ia64/kernel/perfmon_generic.h | 46 - arch/ia64/kernel/perfmon_itanium.h | 2 +- arch/ia64/kernel/perfmon_mckinley.h | 188 -- arch/ia64/kernel/perfmon_montecito.h | 270 --- arch/ia64/oprofile/Makefile | 10 - arch/ia64/oprofile/backtrace.c | 131 -- arch/ia64/oprofile/init.c | 28 - arch/microblaze/Kconfig | 1 - arch/microblaze/Makefile | 2 - arch/microblaze/oprofile/Makefile | 14 - .../microblaze/oprofile/microblaze_oprofile.c | 22 - arch/mips/Kconfig | 3 +- arch/mips/Makefile | 1 - arch/mips/configs/fuloong2e_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/lemote2f_defconfig | 1 - arch/mips/configs/mtx1_defconfig | 1 - arch/mips/configs/rs90_defconfig | 1 - .../include/asm/mach-loongson2ef/loongson.h | 9 - arch/mips/loongson2ef/fuloong-2e/irq.c | 2 +- arch/mips/loongson2ef/lemote-2f/irq.c | 1 - arch/mips/oprofile/Makefile | 18 - arch/mips/oprofile/backtrace.c | 177 -- arch/mips/oprofile/common.c | 147 -- arch/mips/oprofile/op_impl.h | 41 - arch/mips/oprofile/op_model_loongson2.c | 161 -- arch/mips/oprofile/op_model_loongson3.c | 213 -- arch/mips/oprofile/op_model_mipsxx.c | 479 ----- arch/parisc/Kconfig | 1 - arch/parisc/Makefile | 2 - arch/parisc/oprofile/Makefile | 10 - arch/parisc/oprofile/init.c | 23 - arch/powerpc/Kconfig | 1 - arch/powerpc/Makefile | 2 - arch/powerpc/configs/44x/akebono_defconfig | 1 - arch/powerpc/configs/44x/currituck_defconfig | 1 - arch/powerpc/configs/44x/fsp2_defconfig | 1 - arch/powerpc/configs/44x/iss476-smp_defconfig | 1 - arch/powerpc/configs/cell_defconfig | 1 - arch/powerpc/configs/g5_defconfig | 1 - arch/powerpc/configs/maple_defconfig | 1 - arch/powerpc/configs/pasemi_defconfig | 1 - arch/powerpc/configs/pmac32_defconfig | 1 - arch/powerpc/configs/powernv_defconfig | 1 - arch/powerpc/configs/ppc64_defconfig | 1 - arch/powerpc/configs/ppc64e_defconfig | 1 - arch/powerpc/configs/ppc6xx_defconfig | 1 - arch/powerpc/configs/ps3_defconfig | 1 - arch/powerpc/configs/pseries_defconfig | 1 - arch/powerpc/include/asm/cputable.h | 20 - arch/powerpc/include/asm/oprofile_impl.h | 135 -- arch/powerpc/include/asm/spu.h | 33 - arch/powerpc/kernel/cputable.c | 67 - arch/powerpc/kernel/dt_cpu_ftrs.c | 2 - arch/powerpc/oprofile/Makefile | 19 - arch/powerpc/oprofile/backtrace.c | 120 -- arch/powerpc/oprofile/cell/pr_util.h | 110 -- arch/powerpc/oprofile/cell/spu_profiler.c | 248 --- arch/powerpc/oprofile/cell/spu_task_sync.c | 657 ------- arch/powerpc/oprofile/cell/vma_map.c | 279 --- arch/powerpc/oprofile/common.c | 243 --- arch/powerpc/oprofile/op_model_7450.c | 207 -- arch/powerpc/oprofile/op_model_cell.c | 1709 ----------------- arch/powerpc/oprofile/op_model_fsl_emb.c | 380 ---- arch/powerpc/oprofile/op_model_pa6t.c | 227 --- arch/powerpc/oprofile/op_model_power4.c | 438 ----- arch/powerpc/platforms/cell/Kconfig | 5 - arch/powerpc/platforms/cell/spu_notify.c | 55 - arch/powerpc/platforms/cell/spufs/run.c | 4 +- arch/powerpc/platforms/cell/spufs/sched.c | 5 - arch/powerpc/platforms/cell/spufs/spufs.h | 1 - arch/s390/Kconfig | 1 - arch/s390/Makefile | 3 - arch/s390/configs/debug_defconfig | 1 - arch/s390/configs/defconfig | 1 - arch/s390/oprofile/Makefile | 10 - arch/s390/oprofile/init.c | 37 - arch/sh/Kconfig | 1 - arch/sh/Makefile | 1 - arch/sh/configs/espt_defconfig | 1 - arch/sh/configs/migor_defconfig | 1 - arch/sh/configs/r7780mp_defconfig | 1 - arch/sh/configs/r7785rp_defconfig | 1 - arch/sh/configs/rsk7201_defconfig | 1 - arch/sh/configs/rsk7203_defconfig | 1 - arch/sh/configs/rts7751r2d1_defconfig | 1 - arch/sh/configs/rts7751r2dplus_defconfig | 1 - arch/sh/configs/sdk7786_defconfig | 1 - arch/sh/configs/se7206_defconfig | 1 - arch/sh/configs/sh03_defconfig | 1 - arch/sh/configs/sh7724_generic_defconfig | 1 - arch/sh/configs/sh7763rdp_defconfig | 1 - arch/sh/configs/sh7770_generic_defconfig | 1 - arch/sh/configs/shx3_defconfig | 1 - arch/sh/oprofile/Makefile | 16 - arch/sh/oprofile/backtrace.c | 80 - arch/sh/oprofile/common.c | 64 - arch/sparc/Kconfig | 1 - arch/sparc/Makefile | 1 - arch/sparc/configs/sparc64_defconfig | 1 - arch/sparc/oprofile/Makefile | 10 - arch/sparc/oprofile/init.c | 87 - arch/x86/Kconfig | 1 - arch/x86/Makefile | 3 - arch/x86/include/asm/nmi.h | 1 - arch/x86/kernel/cpu/perfctr-watchdog.c | 11 +- arch/x86/oprofile/Makefile | 12 - arch/x86/oprofile/backtrace.c | 127 -- arch/x86/oprofile/init.c | 38 - arch/x86/oprofile/nmi_int.c | 780 -------- arch/x86/oprofile/op_counter.h | 30 - arch/x86/oprofile/op_model_amd.c | 542 ------ arch/x86/oprofile/op_model_p4.c | 723 ------- arch/x86/oprofile/op_model_ppro.c | 245 --- arch/x86/oprofile/op_x86_model.h | 90 - arch/xtensa/Kconfig | 1 - arch/xtensa/Makefile | 1 - arch/xtensa/configs/audio_kc705_defconfig | 1 - arch/xtensa/configs/generic_kc705_defconfig | 1 - arch/xtensa/configs/smp_lx200_defconfig | 1 - arch/xtensa/configs/xip_kc705_defconfig | 1 - arch/xtensa/kernel/stacktrace.c | 2 +- arch/xtensa/oprofile/Makefile | 10 - arch/xtensa/oprofile/backtrace.c | 27 - arch/xtensa/oprofile/init.c | 26 - drivers/oprofile/buffer_sync.c | 591 ------ drivers/oprofile/buffer_sync.h | 22 - drivers/oprofile/cpu_buffer.c | 465 ----- drivers/oprofile/cpu_buffer.h | 121 -- drivers/oprofile/event_buffer.c | 209 -- drivers/oprofile/event_buffer.h | 40 - drivers/oprofile/nmi_timer_int.c | 157 -- drivers/oprofile/oprof.c | 286 --- drivers/oprofile/oprof.h | 50 - drivers/oprofile/oprofile_files.c | 201 -- drivers/oprofile/oprofile_perf.c | 328 ---- drivers/oprofile/oprofile_stats.c | 84 - drivers/oprofile/oprofile_stats.h | 33 - drivers/oprofile/oprofilefs.c | 300 --- drivers/oprofile/timer_int.c | 122 -- fs/Makefile | 1 - fs/dcookies.c | 356 ---- include/linux/dcookies.h | 69 - include/linux/oprofile.h | 209 -- init/Kconfig | 2 +- kernel/sys.c | 1 - usr/include/Makefile | 2 - 198 files changed, 8 insertions(+), 15566 deletions(-) delete mode 100644 arch/alpha/oprofile/Makefile delete mode 100644 arch/alpha/oprofile/common.c delete mode 100644 arch/alpha/oprofile/op_impl.h delete mode 100644 arch/alpha/oprofile/op_model_ev4.c delete mode 100644 arch/alpha/oprofile/op_model_ev5.c delete mode 100644 arch/alpha/oprofile/op_model_ev6.c delete mode 100644 arch/alpha/oprofile/op_model_ev67.c delete mode 100644 arch/arc/oprofile/Makefile delete mode 100644 arch/arc/oprofile/common.c delete mode 100644 arch/arm/oprofile/Makefile delete mode 100644 arch/arm/oprofile/common.c delete mode 100644 arch/ia64/include/asm/perfmon.h delete mode 100644 arch/ia64/include/uapi/asm/perfmon.h delete mode 100644 arch/ia64/include/uapi/asm/perfmon_default_smpl.h delete mode 100644 arch/ia64/kernel/perfmon_default_smpl.c delete mode 100644 arch/ia64/kernel/perfmon_generic.h delete mode 100644 arch/ia64/kernel/perfmon_mckinley.h delete mode 100644 arch/ia64/kernel/perfmon_montecito.h delete mode 100644 arch/ia64/oprofile/Makefile delete mode 100644 arch/ia64/oprofile/backtrace.c delete mode 100644 arch/ia64/oprofile/init.c delete mode 100644 arch/microblaze/oprofile/Makefile delete mode 100644 arch/microblaze/oprofile/microblaze_oprofile.c delete mode 100644 arch/mips/oprofile/Makefile delete mode 100644 arch/mips/oprofile/backtrace.c delete mode 100644 arch/mips/oprofile/common.c delete mode 100644 arch/mips/oprofile/op_impl.h delete mode 100644 arch/mips/oprofile/op_model_loongson2.c delete mode 100644 arch/mips/oprofile/op_model_loongson3.c delete mode 100644 arch/mips/oprofile/op_model_mipsxx.c delete mode 100644 arch/parisc/oprofile/Makefile delete mode 100644 arch/parisc/oprofile/init.c delete mode 100644 arch/powerpc/include/asm/oprofile_impl.h delete mode 100644 arch/powerpc/oprofile/Makefile delete mode 100644 arch/powerpc/oprofile/backtrace.c delete mode 100644 arch/powerpc/oprofile/cell/pr_util.h delete mode 100644 arch/powerpc/oprofile/cell/spu_profiler.c delete mode 100644 arch/powerpc/oprofile/cell/spu_task_sync.c delete mode 100644 arch/powerpc/oprofile/cell/vma_map.c delete mode 100644 arch/powerpc/oprofile/common.c delete mode 100644 arch/powerpc/oprofile/op_model_7450.c delete mode 100644 arch/powerpc/oprofile/op_model_cell.c delete mode 100644 arch/powerpc/oprofile/op_model_fsl_emb.c delete mode 100644 arch/powerpc/oprofile/op_model_pa6t.c delete mode 100644 arch/powerpc/oprofile/op_model_power4.c delete mode 100644 arch/powerpc/platforms/cell/spu_notify.c delete mode 100644 arch/s390/oprofile/Makefile delete mode 100644 arch/s390/oprofile/init.c delete mode 100644 arch/sh/oprofile/Makefile delete mode 100644 arch/sh/oprofile/backtrace.c delete mode 100644 arch/sh/oprofile/common.c delete mode 100644 arch/sparc/oprofile/Makefile delete mode 100644 arch/sparc/oprofile/init.c delete mode 100644 arch/x86/oprofile/Makefile delete mode 100644 arch/x86/oprofile/backtrace.c delete mode 100644 arch/x86/oprofile/init.c delete mode 100644 arch/x86/oprofile/nmi_int.c delete mode 100644 arch/x86/oprofile/op_counter.h delete mode 100644 arch/x86/oprofile/op_model_amd.c delete mode 100644 arch/x86/oprofile/op_model_p4.c delete mode 100644 arch/x86/oprofile/op_model_ppro.c delete mode 100644 arch/x86/oprofile/op_x86_model.h delete mode 100644 arch/xtensa/oprofile/Makefile delete mode 100644 arch/xtensa/oprofile/backtrace.c delete mode 100644 arch/xtensa/oprofile/init.c delete mode 100644 drivers/oprofile/buffer_sync.c delete mode 100644 drivers/oprofile/buffer_sync.h delete mode 100644 drivers/oprofile/cpu_buffer.c delete mode 100644 drivers/oprofile/cpu_buffer.h delete mode 100644 drivers/oprofile/event_buffer.c delete mode 100644 drivers/oprofile/event_buffer.h delete mode 100644 drivers/oprofile/nmi_timer_int.c delete mode 100644 drivers/oprofile/oprof.c delete mode 100644 drivers/oprofile/oprof.h delete mode 100644 drivers/oprofile/oprofile_files.c delete mode 100644 drivers/oprofile/oprofile_perf.c delete mode 100644 drivers/oprofile/oprofile_stats.c delete mode 100644 drivers/oprofile/oprofile_stats.h delete mode 100644 drivers/oprofile/oprofilefs.c delete mode 100644 drivers/oprofile/timer_int.c delete mode 100644 fs/dcookies.c delete mode 100644 include/linux/dcookies.h delete mode 100644 include/linux/oprofile.h base-commit: 7c53f6b671f4aba70ff15e1b05148b10d58c2837 -- 2.25.0.rc1.19.g042ed3e048af |
From: Linus T. <tor...@li...> - 2021-01-14 18:23:44
|
On Thu, Jan 14, 2021 at 3:34 AM Viresh Kumar <vir...@li...> wrote: > > This is build/boot tested by kernel test robot (Intel) and Linaro's > Tuxmake[2] for a lot of architectures and no failures were reported. Can you make sure this is in linux-next, and we'll get this in for 5.12? Linus |
From: Arnd B. <ar...@ke...> - 2021-01-14 19:18:32
|
On Thu, Jan 14, 2021 at 6:51 PM Linus Torvalds <tor...@li...> wrote: > > On Thu, Jan 14, 2021 at 3:34 AM Viresh Kumar <vir...@li...> wrote: > > > > This is build/boot tested by kernel test robot (Intel) and Linaro's > > Tuxmake[2] for a lot of architectures and no failures were reported. > > Can you make sure this is in linux-next, and we'll get this in for 5.12? Hi Viresh, I can add it to the asm-generic tree for linux-next if you send me a pull request. Arnd |
From: Viresh K. <vir...@li...> - 2021-01-18 06:57:20
|
On 14-01-21, 09:51, Linus Torvalds wrote: > On Thu, Jan 14, 2021 at 3:34 AM Viresh Kumar <vir...@li...> wrote: > > > > This is build/boot tested by kernel test robot (Intel) and Linaro's > > Tuxmake[2] for a lot of architectures and no failures were reported. > > Can you make sure this is in linux-next, and we'll get this in for 5.12? This series is in linux-next now. -- viresh |
From: Viresh K. <vir...@li...> - 2021-01-14 11:59:56
|
The dcookies stuff was only used by the kernel's old oprofile code. Now that oprofile's support is removed from the kernel, there is no need for dcookies as well. Remove it. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- fs/Makefile | 1 - fs/dcookies.c | 356 --------------------------------------- include/linux/dcookies.h | 69 -------- kernel/sys.c | 1 - 4 files changed, 427 deletions(-) delete mode 100644 fs/dcookies.c delete mode 100644 include/linux/dcookies.h diff --git a/fs/Makefile b/fs/Makefile index 999d1a23f036..3215fe205256 100644 --- a/fs/Makefile +++ b/fs/Makefile @@ -64,7 +64,6 @@ obj-$(CONFIG_SYSFS) += sysfs/ obj-$(CONFIG_CONFIGFS_FS) += configfs/ obj-y += devpts/ -obj-$(CONFIG_PROFILING) += dcookies.o obj-$(CONFIG_DLM) += dlm/ # Do not add any filesystems before this line diff --git a/fs/dcookies.c b/fs/dcookies.c deleted file mode 100644 index 6eeb61100a09..000000000000 --- a/fs/dcookies.c +++ /dev/null @@ -1,356 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * dcookies.c - * - * Copyright 2002 John Levon <le...@mo...> - * - * Persistent cookie-path mappings. These are used by - * profilers to convert a per-task EIP value into something - * non-transitory that can be processed at a later date. - * This is done by locking the dentry/vfsmnt pair in the - * kernel until released by the tasks needing the persistent - * objects. The tag is simply an unsigned long that refers - * to the pair and can be looked up from userspace. - */ - -#include <linux/syscalls.h> -#include <linux/export.h> -#include <linux/slab.h> -#include <linux/list.h> -#include <linux/mount.h> -#include <linux/capability.h> -#include <linux/dcache.h> -#include <linux/mm.h> -#include <linux/err.h> -#include <linux/errno.h> -#include <linux/dcookies.h> -#include <linux/mutex.h> -#include <linux/path.h> -#include <linux/compat.h> -#include <linux/uaccess.h> - -/* The dcookies are allocated from a kmem_cache and - * hashed onto a small number of lists. None of the - * code here is particularly performance critical - */ -struct dcookie_struct { - struct path path; - struct list_head hash_list; -}; - -static LIST_HEAD(dcookie_users); -static DEFINE_MUTEX(dcookie_mutex); -static struct kmem_cache *dcookie_cache __read_mostly; -static struct list_head *dcookie_hashtable __read_mostly; -static size_t hash_size __read_mostly; - -static inline int is_live(void) -{ - return !(list_empty(&dcookie_users)); -} - - -/* The dentry is locked, its address will do for the cookie */ -static inline unsigned long dcookie_value(struct dcookie_struct * dcs) -{ - return (unsigned long)dcs->path.dentry; -} - - -static size_t dcookie_hash(unsigned long dcookie) -{ - return (dcookie >> L1_CACHE_SHIFT) & (hash_size - 1); -} - - -static struct dcookie_struct * find_dcookie(unsigned long dcookie) -{ - struct dcookie_struct *found = NULL; - struct dcookie_struct * dcs; - struct list_head * pos; - struct list_head * list; - - list = dcookie_hashtable + dcookie_hash(dcookie); - - list_for_each(pos, list) { - dcs = list_entry(pos, struct dcookie_struct, hash_list); - if (dcookie_value(dcs) == dcookie) { - found = dcs; - break; - } - } - - return found; -} - - -static void hash_dcookie(struct dcookie_struct * dcs) -{ - struct list_head * list = dcookie_hashtable + dcookie_hash(dcookie_value(dcs)); - list_add(&dcs->hash_list, list); -} - - -static struct dcookie_struct *alloc_dcookie(const struct path *path) -{ - struct dcookie_struct *dcs = kmem_cache_alloc(dcookie_cache, - GFP_KERNEL); - struct dentry *d; - if (!dcs) - return NULL; - - d = path->dentry; - spin_lock(&d->d_lock); - d->d_flags |= DCACHE_COOKIE; - spin_unlock(&d->d_lock); - - dcs->path = *path; - path_get(path); - hash_dcookie(dcs); - return dcs; -} - - -/* This is the main kernel-side routine that retrieves the cookie - * value for a dentry/vfsmnt pair. - */ -int get_dcookie(const struct path *path, unsigned long *cookie) -{ - int err = 0; - struct dcookie_struct * dcs; - - mutex_lock(&dcookie_mutex); - - if (!is_live()) { - err = -EINVAL; - goto out; - } - - if (path->dentry->d_flags & DCACHE_COOKIE) { - dcs = find_dcookie((unsigned long)path->dentry); - } else { - dcs = alloc_dcookie(path); - if (!dcs) { - err = -ENOMEM; - goto out; - } - } - - *cookie = dcookie_value(dcs); - -out: - mutex_unlock(&dcookie_mutex); - return err; -} - - -/* And here is where the userspace process can look up the cookie value - * to retrieve the path. - */ -static int do_lookup_dcookie(u64 cookie64, char __user *buf, size_t len) -{ - unsigned long cookie = (unsigned long)cookie64; - int err = -EINVAL; - char * kbuf; - char * path; - size_t pathlen; - struct dcookie_struct * dcs; - - /* we could leak path information to users - * without dir read permission without this - */ - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - mutex_lock(&dcookie_mutex); - - if (!is_live()) { - err = -EINVAL; - goto out; - } - - if (!(dcs = find_dcookie(cookie))) - goto out; - - err = -ENOMEM; - kbuf = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!kbuf) - goto out; - - /* FIXME: (deleted) ? */ - path = d_path(&dcs->path, kbuf, PAGE_SIZE); - - mutex_unlock(&dcookie_mutex); - - if (IS_ERR(path)) { - err = PTR_ERR(path); - goto out_free; - } - - err = -ERANGE; - - pathlen = kbuf + PAGE_SIZE - path; - if (pathlen <= len) { - err = pathlen; - if (copy_to_user(buf, path, pathlen)) - err = -EFAULT; - } - -out_free: - kfree(kbuf); - return err; -out: - mutex_unlock(&dcookie_mutex); - return err; -} - -SYSCALL_DEFINE3(lookup_dcookie, u64, cookie64, char __user *, buf, size_t, len) -{ - return do_lookup_dcookie(cookie64, buf, len); -} - -#ifdef CONFIG_COMPAT -COMPAT_SYSCALL_DEFINE4(lookup_dcookie, u32, w0, u32, w1, char __user *, buf, compat_size_t, len) -{ -#ifdef __BIG_ENDIAN - return do_lookup_dcookie(((u64)w0 << 32) | w1, buf, len); -#else - return do_lookup_dcookie(((u64)w1 << 32) | w0, buf, len); -#endif -} -#endif - -static int dcookie_init(void) -{ - struct list_head * d; - unsigned int i, hash_bits; - int err = -ENOMEM; - - dcookie_cache = kmem_cache_create("dcookie_cache", - sizeof(struct dcookie_struct), - 0, 0, NULL); - - if (!dcookie_cache) - goto out; - - dcookie_hashtable = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!dcookie_hashtable) - goto out_kmem; - - err = 0; - - /* - * Find the power-of-two list-heads that can fit into the allocation.. - * We don't guarantee that "sizeof(struct list_head)" is necessarily - * a power-of-two. - */ - hash_size = PAGE_SIZE / sizeof(struct list_head); - hash_bits = 0; - do { - hash_bits++; - } while ((hash_size >> hash_bits) != 0); - hash_bits--; - - /* - * Re-calculate the actual number of entries and the mask - * from the number of bits we can fit. - */ - hash_size = 1UL << hash_bits; - - /* And initialize the newly allocated array */ - d = dcookie_hashtable; - i = hash_size; - do { - INIT_LIST_HEAD(d); - d++; - i--; - } while (i); - -out: - return err; -out_kmem: - kmem_cache_destroy(dcookie_cache); - goto out; -} - - -static void free_dcookie(struct dcookie_struct * dcs) -{ - struct dentry *d = dcs->path.dentry; - - spin_lock(&d->d_lock); - d->d_flags &= ~DCACHE_COOKIE; - spin_unlock(&d->d_lock); - - path_put(&dcs->path); - kmem_cache_free(dcookie_cache, dcs); -} - - -static void dcookie_exit(void) -{ - struct list_head * list; - struct list_head * pos; - struct list_head * pos2; - struct dcookie_struct * dcs; - size_t i; - - for (i = 0; i < hash_size; ++i) { - list = dcookie_hashtable + i; - list_for_each_safe(pos, pos2, list) { - dcs = list_entry(pos, struct dcookie_struct, hash_list); - list_del(&dcs->hash_list); - free_dcookie(dcs); - } - } - - kfree(dcookie_hashtable); - kmem_cache_destroy(dcookie_cache); -} - - -struct dcookie_user { - struct list_head next; -}; - -struct dcookie_user * dcookie_register(void) -{ - struct dcookie_user * user; - - mutex_lock(&dcookie_mutex); - - user = kmalloc(sizeof(struct dcookie_user), GFP_KERNEL); - if (!user) - goto out; - - if (!is_live() && dcookie_init()) - goto out_free; - - list_add(&user->next, &dcookie_users); - -out: - mutex_unlock(&dcookie_mutex); - return user; -out_free: - kfree(user); - user = NULL; - goto out; -} - - -void dcookie_unregister(struct dcookie_user * user) -{ - mutex_lock(&dcookie_mutex); - - list_del(&user->next); - kfree(user); - - if (!is_live()) - dcookie_exit(); - - mutex_unlock(&dcookie_mutex); -} - -EXPORT_SYMBOL_GPL(dcookie_register); -EXPORT_SYMBOL_GPL(dcookie_unregister); -EXPORT_SYMBOL_GPL(get_dcookie); diff --git a/include/linux/dcookies.h b/include/linux/dcookies.h deleted file mode 100644 index ddfdac20cad0..000000000000 --- a/include/linux/dcookies.h +++ /dev/null @@ -1,69 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * dcookies.h - * - * Persistent cookie-path mappings - * - * Copyright 2002 John Levon <le...@mo...> - */ - -#ifndef DCOOKIES_H -#define DCOOKIES_H - - -#ifdef CONFIG_PROFILING - -#include <linux/dcache.h> -#include <linux/types.h> - -struct dcookie_user; -struct path; - -/** - * dcookie_register - register a user of dcookies - * - * Register as a dcookie user. Returns %NULL on failure. - */ -struct dcookie_user * dcookie_register(void); - -/** - * dcookie_unregister - unregister a user of dcookies - * - * Unregister as a dcookie user. This may invalidate - * any dcookie values returned from get_dcookie(). - */ -void dcookie_unregister(struct dcookie_user * user); - -/** - * get_dcookie - acquire a dcookie - * - * Convert the given dentry/vfsmount pair into - * a cookie value. - * - * Returns -EINVAL if no living task has registered as a - * dcookie user. - * - * Returns 0 on success, with *cookie filled in - */ -int get_dcookie(const struct path *path, unsigned long *cookie); - -#else - -static inline struct dcookie_user * dcookie_register(void) -{ - return NULL; -} - -static inline void dcookie_unregister(struct dcookie_user * user) -{ - return; -} - -static inline int get_dcookie(const struct path *path, unsigned long *cookie) -{ - return -ENOSYS; -} - -#endif /* CONFIG_PROFILING */ - -#endif /* DCOOKIES_H */ diff --git a/kernel/sys.c b/kernel/sys.c index 51f00fe20e4d..6928d23c46ea 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -24,7 +24,6 @@ #include <linux/times.h> #include <linux/posix-timers.h> #include <linux/security.h> -#include <linux/dcookies.h> #include <linux/suspend.h> #include <linux/tty.h> #include <linux/signal.h> -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:00:54
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/microblaze/Kconfig | 1 - arch/microblaze/Makefile | 2 -- arch/microblaze/oprofile/Makefile | 14 ------------ .../microblaze/oprofile/microblaze_oprofile.c | 22 ------------------- 4 files changed, 39 deletions(-) delete mode 100644 arch/microblaze/oprofile/Makefile delete mode 100644 arch/microblaze/oprofile/microblaze_oprofile.c diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index f82795592ce5..25a5a3fb14aa 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -30,7 +30,6 @@ config MICROBLAZE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_TRACER - select HAVE_OPROFILE select HAVE_PCI select IRQ_DOMAIN select XILINX_INTC diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile index bb980891816d..b41f323e1fde 100644 --- a/arch/microblaze/Makefile +++ b/arch/microblaze/Makefile @@ -54,8 +54,6 @@ core-y += arch/microblaze/kernel/ core-y += arch/microblaze/mm/ core-$(CONFIG_PCI) += arch/microblaze/pci/ -drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/ - boot := arch/microblaze/boot # Are we making a simpleImage.<boardname> target? If so, crack out the boardname diff --git a/arch/microblaze/oprofile/Makefile b/arch/microblaze/oprofile/Makefile deleted file mode 100644 index 107f2f55d995..000000000000 --- a/arch/microblaze/oprofile/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# arch/microblaze/oprofile/Makefile -# - -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) microblaze_oprofile.o diff --git a/arch/microblaze/oprofile/microblaze_oprofile.c b/arch/microblaze/oprofile/microblaze_oprofile.c deleted file mode 100644 index def17e59888e..000000000000 --- a/arch/microblaze/oprofile/microblaze_oprofile.c +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Microblaze oprofile code - * - * Copyright (C) 2009 Michal Simek <mo...@mo...> - * Copyright (C) 2009 PetaLogix - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include <linux/oprofile.h> -#include <linux/init.h> - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - return -1; -} - -void oprofile_arch_exit(void) -{ -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Michal S. <mo...@mo...> - 2021-01-14 13:07:23
|
On 14. 01. 21 12:35, Viresh Kumar wrote: > The "oprofile" user-space tools don't use the kernel OPROFILE support > any more, and haven't in a long time. User-space has been converted to > the perf interfaces. > > Remove the old oprofile's architecture specific support. > > Suggested-by: Christoph Hellwig <hc...@in...> > Suggested-by: Linus Torvalds <tor...@li...> > Signed-off-by: Viresh Kumar <vir...@li...> > --- > arch/microblaze/Kconfig | 1 - > arch/microblaze/Makefile | 2 -- > arch/microblaze/oprofile/Makefile | 14 ------------ > .../microblaze/oprofile/microblaze_oprofile.c | 22 ------------------- > 4 files changed, 39 deletions(-) > delete mode 100644 arch/microblaze/oprofile/Makefile > delete mode 100644 arch/microblaze/oprofile/microblaze_oprofile.c > > diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig > index f82795592ce5..25a5a3fb14aa 100644 > --- a/arch/microblaze/Kconfig > +++ b/arch/microblaze/Kconfig > @@ -30,7 +30,6 @@ config MICROBLAZE > select HAVE_FTRACE_MCOUNT_RECORD > select HAVE_FUNCTION_GRAPH_TRACER > select HAVE_FUNCTION_TRACER > - select HAVE_OPROFILE > select HAVE_PCI > select IRQ_DOMAIN > select XILINX_INTC > diff --git a/arch/microblaze/Makefile b/arch/microblaze/Makefile > index bb980891816d..b41f323e1fde 100644 > --- a/arch/microblaze/Makefile > +++ b/arch/microblaze/Makefile > @@ -54,8 +54,6 @@ core-y += arch/microblaze/kernel/ > core-y += arch/microblaze/mm/ > core-$(CONFIG_PCI) += arch/microblaze/pci/ > > -drivers-$(CONFIG_OPROFILE) += arch/microblaze/oprofile/ > - > boot := arch/microblaze/boot > > # Are we making a simpleImage.<boardname> target? If so, crack out the boardname > diff --git a/arch/microblaze/oprofile/Makefile b/arch/microblaze/oprofile/Makefile > deleted file mode 100644 > index 107f2f55d995..000000000000 > --- a/arch/microblaze/oprofile/Makefile > +++ /dev/null > @@ -1,14 +0,0 @@ > -# SPDX-License-Identifier: GPL-2.0 > -# > -# arch/microblaze/oprofile/Makefile > -# > - > -obj-$(CONFIG_OPROFILE) += oprofile.o > - > -DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ > - oprof.o cpu_buffer.o buffer_sync.o \ > - event_buffer.o oprofile_files.o \ > - oprofilefs.o oprofile_stats.o \ > - timer_int.o ) > - > -oprofile-y := $(DRIVER_OBJS) microblaze_oprofile.o > diff --git a/arch/microblaze/oprofile/microblaze_oprofile.c b/arch/microblaze/oprofile/microblaze_oprofile.c > deleted file mode 100644 > index def17e59888e..000000000000 > --- a/arch/microblaze/oprofile/microblaze_oprofile.c > +++ /dev/null > @@ -1,22 +0,0 @@ > -/* > - * Microblaze oprofile code > - * > - * Copyright (C) 2009 Michal Simek <mo...@mo...> > - * Copyright (C) 2009 PetaLogix > - * > - * This file is subject to the terms and conditions of the GNU General Public > - * License. See the file "COPYING" in the main directory of this archive > - * for more details. > - */ > - > -#include <linux/oprofile.h> > -#include <linux/init.h> > - > -int __init oprofile_arch_init(struct oprofile_operations *ops) > -{ > - return -1; > -} > - > -void oprofile_arch_exit(void) > -{ > -} > Acked-by: Michal Simek <mic...@xi...> Thanks, Michal -- Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91 w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel - Xilinx Microblaze Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs |
From: Viresh K. <vir...@li...> - 2021-01-14 12:00:57
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove kernel's old oprofile support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- Documentation/RCU/NMI-RCU.rst | 3 +- .../admin-guide/kernel-parameters.txt | 14 - Documentation/process/magic-number.rst | 1 - .../it_IT/process/magic-number.rst | 1 - .../zh_CN/process/magic-number.rst | 1 - MAINTAINERS | 11 - arch/Kconfig | 32 - drivers/oprofile/buffer_sync.c | 591 ------------------ drivers/oprofile/buffer_sync.h | 22 - drivers/oprofile/cpu_buffer.c | 465 -------------- drivers/oprofile/cpu_buffer.h | 121 ---- drivers/oprofile/event_buffer.c | 209 ------- drivers/oprofile/event_buffer.h | 40 -- drivers/oprofile/nmi_timer_int.c | 157 ----- drivers/oprofile/oprof.c | 286 --------- drivers/oprofile/oprof.h | 50 -- drivers/oprofile/oprofile_files.c | 201 ------ drivers/oprofile/oprofile_perf.c | 328 ---------- drivers/oprofile/oprofile_stats.c | 84 --- drivers/oprofile/oprofile_stats.h | 33 - drivers/oprofile/oprofilefs.c | 300 --------- drivers/oprofile/timer_int.c | 122 ---- include/linux/oprofile.h | 209 ------- init/Kconfig | 2 +- 24 files changed, 2 insertions(+), 3281 deletions(-) delete mode 100644 drivers/oprofile/buffer_sync.c delete mode 100644 drivers/oprofile/buffer_sync.h delete mode 100644 drivers/oprofile/cpu_buffer.c delete mode 100644 drivers/oprofile/cpu_buffer.h delete mode 100644 drivers/oprofile/event_buffer.c delete mode 100644 drivers/oprofile/event_buffer.h delete mode 100644 drivers/oprofile/nmi_timer_int.c delete mode 100644 drivers/oprofile/oprof.c delete mode 100644 drivers/oprofile/oprof.h delete mode 100644 drivers/oprofile/oprofile_files.c delete mode 100644 drivers/oprofile/oprofile_perf.c delete mode 100644 drivers/oprofile/oprofile_stats.c delete mode 100644 drivers/oprofile/oprofile_stats.h delete mode 100644 drivers/oprofile/oprofilefs.c delete mode 100644 drivers/oprofile/timer_int.c delete mode 100644 include/linux/oprofile.h diff --git a/Documentation/RCU/NMI-RCU.rst b/Documentation/RCU/NMI-RCU.rst index 180958388ff9..2a92bc685ef1 100644 --- a/Documentation/RCU/NMI-RCU.rst +++ b/Documentation/RCU/NMI-RCU.rst @@ -8,8 +8,7 @@ Although RCU is usually used to protect read-mostly data structures, it is possible to use RCU to provide dynamic non-maskable interrupt handlers, as well as dynamic irq handlers. This document describes how to do this, drawing loosely from Zwane Mwaikambo's NMI-timer -work in "arch/x86/oprofile/nmi_timer_int.c" and in -"arch/x86/kernel/traps.c". +work in "arch/x86/kernel/traps.c". The relevant pieces of code are listed below, each followed by a brief explanation:: diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 9e3cdb271d06..e860c681766b 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3458,20 +3458,6 @@ For example, to override I2C bus2: omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100 - oprofile.timer= [HW] - Use timer interrupt instead of performance counters - - oprofile.cpu_type= Force an oprofile cpu type - This might be useful if you have an older oprofile - userland or if you want common events. - Format: { arch_perfmon } - arch_perfmon: [X86] Force use of architectural - perfmon on Intel CPUs instead of the - CPU specific event set. - timer: [X86] Force use of architectural NMI - timer mode (see also oprofile.timer - for generic hr timer mode) - oops=panic Always panic on oopses. Default is to just kill the process, but there is a small probability of deadlocking the machine. diff --git a/Documentation/process/magic-number.rst b/Documentation/process/magic-number.rst index e02ff5ffb653..c6dfe060ec2f 100644 --- a/Documentation/process/magic-number.rst +++ b/Documentation/process/magic-number.rst @@ -135,7 +135,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` diff --git a/Documentation/translations/it_IT/process/magic-number.rst b/Documentation/translations/it_IT/process/magic-number.rst index 0243d32a0b59..1af30f4228f2 100644 --- a/Documentation/translations/it_IT/process/magic-number.rst +++ b/Documentation/translations/it_IT/process/magic-number.rst @@ -141,7 +141,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` diff --git a/Documentation/translations/zh_CN/process/magic-number.rst b/Documentation/translations/zh_CN/process/magic-number.rst index de182bf4191c..7bb9d4165ed3 100644 --- a/Documentation/translations/zh_CN/process/magic-number.rst +++ b/Documentation/translations/zh_CN/process/magic-number.rst @@ -124,7 +124,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` diff --git a/MAINTAINERS b/MAINTAINERS index cc1e6a5ee6e6..ae2c2cef9d96 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1414,7 +1414,6 @@ F: arch/arm*/include/asm/hw_breakpoint.h F: arch/arm*/include/asm/perf_event.h F: arch/arm*/kernel/hw_breakpoint.c F: arch/arm*/kernel/perf_* -F: arch/arm/oprofile/common.c F: drivers/perf/ F: include/linux/perf/arm_pmu.h @@ -4083,7 +4082,6 @@ W: http://www.ibm.com/developerworks/power/cell/ F: arch/powerpc/include/asm/cell*.h F: arch/powerpc/include/asm/spu*.h F: arch/powerpc/include/uapi/asm/spu*.h -F: arch/powerpc/oprofile/*cell* F: arch/powerpc/platforms/cell/ CELLWISE CW2015 BATTERY DRIVER @@ -13311,15 +13309,6 @@ S: Maintained T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git F: sound/drivers/opl4/ -OPROFILE -M: Robert Richter <rr...@ke...> -L: opr...@li... -S: Maintained -F: arch/*/include/asm/oprofile*.h -F: arch/*/oprofile/ -F: drivers/oprofile/ -F: include/linux/oprofile.h - ORACLE CLUSTER FILESYSTEM 2 (OCFS2) M: Mark Fasheh <ma...@fa...> M: Joel Becker <jl...@ev...> diff --git a/arch/Kconfig b/arch/Kconfig index 24862d15f3a3..40277027a255 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -33,38 +33,6 @@ config HOTPLUG_SMT config GENERIC_ENTRY bool -config OPROFILE - tristate "OProfile system profiling" - depends on PROFILING - depends on HAVE_OPROFILE - select RING_BUFFER - select RING_BUFFER_ALLOW_SWAP - help - OProfile is a profiling system capable of profiling the - whole system, include the kernel, kernel modules, libraries, - and applications. - - If unsure, say N. - -config OPROFILE_EVENT_MULTIPLEX - bool "OProfile multiplexing support (EXPERIMENTAL)" - default n - depends on OPROFILE && X86 - help - The number of hardware counters is limited. The multiplexing - feature enables OProfile to gather more events than counters - are provided by the hardware. This is realized by switching - between events at a user specified time interval. - - If unsure, say N. - -config HAVE_OPROFILE - bool - -config OPROFILE_NMI_TIMER - def_bool y - depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !PPC64 - config KPROBES bool "Kprobes" depends on MODULES diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c deleted file mode 100644 index cc917865f13a..000000000000 --- a/drivers/oprofile/buffer_sync.c +++ /dev/null @@ -1,591 +0,0 @@ -/** - * @file buffer_sync.c - * - * @remark Copyright 2002-2009 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - * @author Barry Kasindorf - * @author Robert Richter <rob...@am...> - * - * This is the core of the buffer management. Each - * CPU buffer is processed and entered into the - * global event buffer. Such processing is necessary - * in several circumstances, mentioned below. - * - * The processing does the job of converting the - * transitory EIP value into a persistent dentry/offset - * value that the profiler can record at its leisure. - * - * See fs/dcookies.c for a description of the dentry/offset - * objects. - */ - -#include <linux/file.h> -#include <linux/mm.h> -#include <linux/workqueue.h> -#include <linux/notifier.h> -#include <linux/dcookies.h> -#include <linux/profile.h> -#include <linux/module.h> -#include <linux/fs.h> -#include <linux/oprofile.h> -#include <linux/sched.h> -#include <linux/sched/mm.h> -#include <linux/sched/task.h> -#include <linux/gfp.h> - -#include "oprofile_stats.h" -#include "event_buffer.h" -#include "cpu_buffer.h" -#include "buffer_sync.h" - -static LIST_HEAD(dying_tasks); -static LIST_HEAD(dead_tasks); -static cpumask_var_t marked_cpus; -static DEFINE_SPINLOCK(task_mortuary); -static void process_task_mortuary(void); - -/* Take ownership of the task struct and place it on the - * list for processing. Only after two full buffer syncs - * does the task eventually get freed, because by then - * we are sure we will not reference it again. - * Can be invoked from softirq via RCU callback due to - * call_rcu() of the task struct, hence the _irqsave. - */ -static int -task_free_notify(struct notifier_block *self, unsigned long val, void *data) -{ - unsigned long flags; - struct task_struct *task = data; - spin_lock_irqsave(&task_mortuary, flags); - list_add(&task->tasks, &dying_tasks); - spin_unlock_irqrestore(&task_mortuary, flags); - return NOTIFY_OK; -} - - -/* The task is on its way out. A sync of the buffer means we can catch - * any remaining samples for this task. - */ -static int -task_exit_notify(struct notifier_block *self, unsigned long val, void *data) -{ - /* To avoid latency problems, we only process the current CPU, - * hoping that most samples for the task are on this CPU - */ - sync_buffer(raw_smp_processor_id()); - return 0; -} - - -/* The task is about to try a do_munmap(). We peek at what it's going to - * do, and if it's an executable region, process the samples first, so - * we don't lose any. This does not have to be exact, it's a QoI issue - * only. - */ -static int -munmap_notify(struct notifier_block *self, unsigned long val, void *data) -{ - unsigned long addr = (unsigned long)data; - struct mm_struct *mm = current->mm; - struct vm_area_struct *mpnt; - - mmap_read_lock(mm); - - mpnt = find_vma(mm, addr); - if (mpnt && mpnt->vm_file && (mpnt->vm_flags & VM_EXEC)) { - mmap_read_unlock(mm); - /* To avoid latency problems, we only process the current CPU, - * hoping that most samples for the task are on this CPU - */ - sync_buffer(raw_smp_processor_id()); - return 0; - } - - mmap_read_unlock(mm); - return 0; -} - - -/* We need to be told about new modules so we don't attribute to a previously - * loaded module, or drop the samples on the floor. - */ -static int -module_load_notify(struct notifier_block *self, unsigned long val, void *data) -{ -#ifdef CONFIG_MODULES - if (val != MODULE_STATE_COMING) - return NOTIFY_DONE; - - /* FIXME: should we process all CPU buffers ? */ - mutex_lock(&buffer_mutex); - add_event_entry(ESCAPE_CODE); - add_event_entry(MODULE_LOADED_CODE); - mutex_unlock(&buffer_mutex); -#endif - return NOTIFY_OK; -} - - -static struct notifier_block task_free_nb = { - .notifier_call = task_free_notify, -}; - -static struct notifier_block task_exit_nb = { - .notifier_call = task_exit_notify, -}; - -static struct notifier_block munmap_nb = { - .notifier_call = munmap_notify, -}; - -static struct notifier_block module_load_nb = { - .notifier_call = module_load_notify, -}; - -static void free_all_tasks(void) -{ - /* make sure we don't leak task structs */ - process_task_mortuary(); - process_task_mortuary(); -} - -int sync_start(void) -{ - int err; - - if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) - return -ENOMEM; - - err = task_handoff_register(&task_free_nb); - if (err) - goto out1; - err = profile_event_register(PROFILE_TASK_EXIT, &task_exit_nb); - if (err) - goto out2; - err = profile_event_register(PROFILE_MUNMAP, &munmap_nb); - if (err) - goto out3; - err = register_module_notifier(&module_load_nb); - if (err) - goto out4; - - start_cpu_work(); - -out: - return err; -out4: - profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); -out3: - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); -out2: - task_handoff_unregister(&task_free_nb); - free_all_tasks(); -out1: - free_cpumask_var(marked_cpus); - goto out; -} - - -void sync_stop(void) -{ - end_cpu_work(); - unregister_module_notifier(&module_load_nb); - profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); - task_handoff_unregister(&task_free_nb); - barrier(); /* do all of the above first */ - - flush_cpu_work(); - - free_all_tasks(); - free_cpumask_var(marked_cpus); -} - - -/* Optimisation. We can manage without taking the dcookie sem - * because we cannot reach this code without at least one - * dcookie user still being registered (namely, the reader - * of the event buffer). */ -static inline unsigned long fast_get_dcookie(const struct path *path) -{ - unsigned long cookie; - - if (path->dentry->d_flags & DCACHE_COOKIE) - return (unsigned long)path->dentry; - get_dcookie(path, &cookie); - return cookie; -} - - -/* Look up the dcookie for the task's mm->exe_file, - * which corresponds loosely to "application name". This is - * not strictly necessary but allows oprofile to associate - * shared-library samples with particular applications - */ -static unsigned long get_exec_dcookie(struct mm_struct *mm) -{ - unsigned long cookie = NO_COOKIE; - struct file *exe_file; - - if (!mm) - goto done; - - exe_file = get_mm_exe_file(mm); - if (!exe_file) - goto done; - - cookie = fast_get_dcookie(&exe_file->f_path); - fput(exe_file); -done: - return cookie; -} - - -/* Convert the EIP value of a sample into a persistent dentry/offset - * pair that can then be added to the global event buffer. We make - * sure to do this lookup before a mm->mmap modification happens so - * we don't lose track. - * - * The caller must ensure the mm is not nil (ie: not a kernel thread). - */ -static unsigned long -lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset) -{ - unsigned long cookie = NO_COOKIE; - struct vm_area_struct *vma; - - mmap_read_lock(mm); - for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { - - if (addr < vma->vm_start || addr >= vma->vm_end) - continue; - - if (vma->vm_file) { - cookie = fast_get_dcookie(&vma->vm_file->f_path); - *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - - vma->vm_start; - } else { - /* must be an anonymous map */ - *offset = addr; - } - - break; - } - - if (!vma) - cookie = INVALID_COOKIE; - mmap_read_unlock(mm); - - return cookie; -} - -static unsigned long last_cookie = INVALID_COOKIE; - -static void add_cpu_switch(int i) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(CPU_SWITCH_CODE); - add_event_entry(i); - last_cookie = INVALID_COOKIE; -} - -static void add_kernel_ctx_switch(unsigned int in_kernel) -{ - add_event_entry(ESCAPE_CODE); - if (in_kernel) - add_event_entry(KERNEL_ENTER_SWITCH_CODE); - else - add_event_entry(KERNEL_EXIT_SWITCH_CODE); -} - -static void -add_user_ctx_switch(struct task_struct const *task, unsigned long cookie) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(CTX_SWITCH_CODE); - add_event_entry(task->pid); - add_event_entry(cookie); - /* Another code for daemon back-compat */ - add_event_entry(ESCAPE_CODE); - add_event_entry(CTX_TGID_CODE); - add_event_entry(task->tgid); -} - - -static void add_cookie_switch(unsigned long cookie) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(COOKIE_SWITCH_CODE); - add_event_entry(cookie); -} - - -static void add_trace_begin(void) -{ - add_event_entry(ESCAPE_CODE); - add_event_entry(TRACE_BEGIN_CODE); -} - -static void add_data(struct op_entry *entry, struct mm_struct *mm) -{ - unsigned long code, pc, val; - unsigned long cookie; - off_t offset; - - if (!op_cpu_buffer_get_data(entry, &code)) - return; - if (!op_cpu_buffer_get_data(entry, &pc)) - return; - if (!op_cpu_buffer_get_size(entry)) - return; - - if (mm) { - cookie = lookup_dcookie(mm, pc, &offset); - - if (cookie == NO_COOKIE) - offset = pc; - if (cookie == INVALID_COOKIE) { - atomic_inc(&oprofile_stats.sample_lost_no_mapping); - offset = pc; - } - if (cookie != last_cookie) { - add_cookie_switch(cookie); - last_cookie = cookie; - } - } else - offset = pc; - - add_event_entry(ESCAPE_CODE); - add_event_entry(code); - add_event_entry(offset); /* Offset from Dcookie */ - - while (op_cpu_buffer_get_data(entry, &val)) - add_event_entry(val); -} - -static inline void add_sample_entry(unsigned long offset, unsigned long event) -{ - add_event_entry(offset); - add_event_entry(event); -} - - -/* - * Add a sample to the global event buffer. If possible the - * sample is converted into a persistent dentry/offset pair - * for later lookup from userspace. Return 0 on failure. - */ -static int -add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel) -{ - unsigned long cookie; - off_t offset; - - if (in_kernel) { - add_sample_entry(s->eip, s->event); - return 1; - } - - /* add userspace sample */ - - if (!mm) { - atomic_inc(&oprofile_stats.sample_lost_no_mm); - return 0; - } - - cookie = lookup_dcookie(mm, s->eip, &offset); - - if (cookie == INVALID_COOKIE) { - atomic_inc(&oprofile_stats.sample_lost_no_mapping); - return 0; - } - - if (cookie != last_cookie) { - add_cookie_switch(cookie); - last_cookie = cookie; - } - - add_sample_entry(offset, s->event); - - return 1; -} - - -static void release_mm(struct mm_struct *mm) -{ - if (!mm) - return; - mmput(mm); -} - -static inline int is_code(unsigned long val) -{ - return val == ESCAPE_CODE; -} - - -/* Move tasks along towards death. Any tasks on dead_tasks - * will definitely have no remaining references in any - * CPU buffers at this point, because we use two lists, - * and to have reached the list, it must have gone through - * one full sync already. - */ -static void process_task_mortuary(void) -{ - unsigned long flags; - LIST_HEAD(local_dead_tasks); - struct task_struct *task; - struct task_struct *ttask; - - spin_lock_irqsave(&task_mortuary, flags); - - list_splice_init(&dead_tasks, &local_dead_tasks); - list_splice_init(&dying_tasks, &dead_tasks); - - spin_unlock_irqrestore(&task_mortuary, flags); - - list_for_each_entry_safe(task, ttask, &local_dead_tasks, tasks) { - list_del(&task->tasks); - free_task(task); - } -} - - -static void mark_done(int cpu) -{ - int i; - - cpumask_set_cpu(cpu, marked_cpus); - - for_each_online_cpu(i) { - if (!cpumask_test_cpu(i, marked_cpus)) - return; - } - - /* All CPUs have been processed at least once, - * we can process the mortuary once - */ - process_task_mortuary(); - - cpumask_clear(marked_cpus); -} - - -/* FIXME: this is not sufficient if we implement syscall barrier backtrace - * traversal, the code switch to sb_sample_start at first kernel enter/exit - * switch so we need a fifth state and some special handling in sync_buffer() - */ -typedef enum { - sb_bt_ignore = -2, - sb_buffer_start, - sb_bt_start, - sb_sample_start, -} sync_buffer_state; - -/* Sync one of the CPU's buffers into the global event buffer. - * Here we need to go through each batch of samples punctuated - * by context switch notes, taking the task's mmap_lock and doing - * lookup in task->mm->mmap to convert EIP into dcookie/offset - * value. - */ -void sync_buffer(int cpu) -{ - struct mm_struct *mm = NULL; - struct mm_struct *oldmm; - unsigned long val; - struct task_struct *new; - unsigned long cookie = 0; - int in_kernel = 1; - sync_buffer_state state = sb_buffer_start; - unsigned int i; - unsigned long available; - unsigned long flags; - struct op_entry entry; - struct op_sample *sample; - - mutex_lock(&buffer_mutex); - - add_cpu_switch(cpu); - - op_cpu_buffer_reset(cpu); - available = op_cpu_buffer_entries(cpu); - - for (i = 0; i < available; ++i) { - sample = op_cpu_buffer_read_entry(&entry, cpu); - if (!sample) - break; - - if (is_code(sample->eip)) { - flags = sample->event; - if (flags & TRACE_BEGIN) { - state = sb_bt_start; - add_trace_begin(); - } - if (flags & KERNEL_CTX_SWITCH) { - /* kernel/userspace switch */ - in_kernel = flags & IS_KERNEL; - if (state == sb_buffer_start) - state = sb_sample_start; - add_kernel_ctx_switch(flags & IS_KERNEL); - } - if (flags & USER_CTX_SWITCH - && op_cpu_buffer_get_data(&entry, &val)) { - /* userspace context switch */ - new = (struct task_struct *)val; - oldmm = mm; - release_mm(oldmm); - mm = get_task_mm(new); - if (mm != oldmm) - cookie = get_exec_dcookie(mm); - add_user_ctx_switch(new, cookie); - } - if (op_cpu_buffer_get_size(&entry)) - add_data(&entry, mm); - continue; - } - - if (state < sb_bt_start) - /* ignore sample */ - continue; - - if (add_sample(mm, sample, in_kernel)) - continue; - - /* ignore backtraces if failed to add a sample */ - if (state == sb_bt_start) { - state = sb_bt_ignore; - atomic_inc(&oprofile_stats.bt_lost_no_mapping); - } - } - release_mm(mm); - - mark_done(cpu); - - mutex_unlock(&buffer_mutex); -} - -/* The function can be used to add a buffer worth of data directly to - * the kernel buffer. The buffer is assumed to be a circular buffer. - * Take the entries from index start and end at index end, wrapping - * at max_entries. - */ -void oprofile_put_buff(unsigned long *buf, unsigned int start, - unsigned int stop, unsigned int max) -{ - int i; - - i = start; - - mutex_lock(&buffer_mutex); - while (i != stop) { - add_event_entry(buf[i++]); - - if (i >= max) - i = 0; - } - - mutex_unlock(&buffer_mutex); -} - diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h deleted file mode 100644 index 3110732c1835..000000000000 --- a/drivers/oprofile/buffer_sync.h +++ /dev/null @@ -1,22 +0,0 @@ -/** - * @file buffer_sync.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#ifndef OPROFILE_BUFFER_SYNC_H -#define OPROFILE_BUFFER_SYNC_H - -/* add the necessary profiling hooks */ -int sync_start(void); - -/* remove the hooks */ -void sync_stop(void); - -/* sync the given CPU's buffer */ -void sync_buffer(int cpu); - -#endif /* OPROFILE_BUFFER_SYNC_H */ diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c deleted file mode 100644 index 9210a95cb4e6..000000000000 --- a/drivers/oprofile/cpu_buffer.c +++ /dev/null @@ -1,465 +0,0 @@ -/** - * @file cpu_buffer.c - * - * @remark Copyright 2002-2009 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - * @author Barry Kasindorf <bar...@am...> - * @author Robert Richter <rob...@am...> - * - * Each CPU has a local buffer that stores PC value/event - * pairs. We also log context switches when we notice them. - * Eventually each CPU's buffer is processed into the global - * event buffer by sync_buffer(). - * - * We use a local buffer for two reasons: an NMI or similar - * interrupt cannot synchronise, and high sampling rates - * would lead to catastrophic global synchronisation if - * a global buffer was used. - */ - -#include <linux/sched.h> -#include <linux/oprofile.h> -#include <linux/errno.h> - -#include <asm/ptrace.h> - -#include "event_buffer.h" -#include "cpu_buffer.h" -#include "buffer_sync.h" -#include "oprof.h" - -#define OP_BUFFER_FLAGS 0 - -static struct trace_buffer *op_ring_buffer; -DEFINE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer); - -static void wq_sync_buffer(struct work_struct *work); - -#define DEFAULT_TIMER_EXPIRE (HZ / 10) -static int work_enabled; - -unsigned long oprofile_get_cpu_buffer_size(void) -{ - return oprofile_cpu_buffer_size; -} - -void oprofile_cpu_buffer_inc_smpl_lost(void) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - - cpu_buf->sample_lost_overflow++; -} - -void free_cpu_buffers(void) -{ - if (op_ring_buffer) - ring_buffer_free(op_ring_buffer); - op_ring_buffer = NULL; -} - -#define RB_EVENT_HDR_SIZE 4 - -int alloc_cpu_buffers(void) -{ - int i; - - unsigned long buffer_size = oprofile_cpu_buffer_size; - unsigned long byte_size = buffer_size * (sizeof(struct op_sample) + - RB_EVENT_HDR_SIZE); - - op_ring_buffer = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS); - if (!op_ring_buffer) - goto fail; - - for_each_possible_cpu(i) { - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); - - b->last_task = NULL; - b->last_is_kernel = -1; - b->tracing = 0; - b->buffer_size = buffer_size; - b->sample_received = 0; - b->sample_lost_overflow = 0; - b->backtrace_aborted = 0; - b->sample_invalid_eip = 0; - b->cpu = i; - INIT_DELAYED_WORK(&b->work, wq_sync_buffer); - } - return 0; - -fail: - free_cpu_buffers(); - return -ENOMEM; -} - -void start_cpu_work(void) -{ - int i; - - work_enabled = 1; - - for_each_online_cpu(i) { - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); - - /* - * Spread the work by 1 jiffy per cpu so they dont all - * fire at once. - */ - schedule_delayed_work_on(i, &b->work, DEFAULT_TIMER_EXPIRE + i); - } -} - -void end_cpu_work(void) -{ - work_enabled = 0; -} - -void flush_cpu_work(void) -{ - int i; - - for_each_online_cpu(i) { - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); - - /* these works are per-cpu, no need for flush_sync */ - flush_delayed_work(&b->work); - } -} - -/* - * This function prepares the cpu buffer to write a sample. - * - * Struct op_entry is used during operations on the ring buffer while - * struct op_sample contains the data that is stored in the ring - * buffer. Struct entry can be uninitialized. The function reserves a - * data array that is specified by size. Use - * op_cpu_buffer_write_commit() after preparing the sample. In case of - * errors a null pointer is returned, otherwise the pointer to the - * sample. - * - */ -struct op_sample -*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size) -{ - entry->event = ring_buffer_lock_reserve - (op_ring_buffer, sizeof(struct op_sample) + - size * sizeof(entry->sample->data[0])); - if (!entry->event) - return NULL; - entry->sample = ring_buffer_event_data(entry->event); - entry->size = size; - entry->data = entry->sample->data; - - return entry->sample; -} - -int op_cpu_buffer_write_commit(struct op_entry *entry) -{ - return ring_buffer_unlock_commit(op_ring_buffer, entry->event); -} - -struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu) -{ - struct ring_buffer_event *e; - e = ring_buffer_consume(op_ring_buffer, cpu, NULL, NULL); - if (!e) - return NULL; - - entry->event = e; - entry->sample = ring_buffer_event_data(e); - entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample)) - / sizeof(entry->sample->data[0]); - entry->data = entry->sample->data; - return entry->sample; -} - -unsigned long op_cpu_buffer_entries(int cpu) -{ - return ring_buffer_entries_cpu(op_ring_buffer, cpu); -} - -static int -op_add_code(struct oprofile_cpu_buffer *cpu_buf, unsigned long backtrace, - int is_kernel, struct task_struct *task) -{ - struct op_entry entry; - struct op_sample *sample; - unsigned long flags; - int size; - - flags = 0; - - if (backtrace) - flags |= TRACE_BEGIN; - - /* notice a switch from user->kernel or vice versa */ - is_kernel = !!is_kernel; - if (cpu_buf->last_is_kernel != is_kernel) { - cpu_buf->last_is_kernel = is_kernel; - flags |= KERNEL_CTX_SWITCH; - if (is_kernel) - flags |= IS_KERNEL; - } - - /* notice a task switch */ - if (cpu_buf->last_task != task) { - cpu_buf->last_task = task; - flags |= USER_CTX_SWITCH; - } - - if (!flags) - /* nothing to do */ - return 0; - - if (flags & USER_CTX_SWITCH) - size = 1; - else - size = 0; - - sample = op_cpu_buffer_write_reserve(&entry, size); - if (!sample) - return -ENOMEM; - - sample->eip = ESCAPE_CODE; - sample->event = flags; - - if (size) - op_cpu_buffer_add_data(&entry, (unsigned long)task); - - op_cpu_buffer_write_commit(&entry); - - return 0; -} - -static inline int -op_add_sample(struct oprofile_cpu_buffer *cpu_buf, - unsigned long pc, unsigned long event) -{ - struct op_entry entry; - struct op_sample *sample; - - sample = op_cpu_buffer_write_reserve(&entry, 0); - if (!sample) - return -ENOMEM; - - sample->eip = pc; - sample->event = event; - - return op_cpu_buffer_write_commit(&entry); -} - -/* - * This must be safe from any context. - * - * is_kernel is needed because on some architectures you cannot - * tell if you are in kernel or user space simply by looking at - * pc. We tag this in the buffer by generating kernel enter/exit - * events whenever is_kernel changes - */ -static int -log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc, - unsigned long backtrace, int is_kernel, unsigned long event, - struct task_struct *task) -{ - struct task_struct *tsk = task ? task : current; - cpu_buf->sample_received++; - - if (pc == ESCAPE_CODE) { - cpu_buf->sample_invalid_eip++; - return 0; - } - - if (op_add_code(cpu_buf, backtrace, is_kernel, tsk)) - goto fail; - - if (op_add_sample(cpu_buf, pc, event)) - goto fail; - - return 1; - -fail: - cpu_buf->sample_lost_overflow++; - return 0; -} - -static inline void oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf) -{ - cpu_buf->tracing = 1; -} - -static inline void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf) -{ - cpu_buf->tracing = 0; -} - -static inline void -__oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel, - struct task_struct *task) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - unsigned long backtrace = oprofile_backtrace_depth; - - /* - * if log_sample() fail we can't backtrace since we lost the - * source of this event - */ - if (!log_sample(cpu_buf, pc, backtrace, is_kernel, event, task)) - /* failed */ - return; - - if (!backtrace) - return; - - oprofile_begin_trace(cpu_buf); - oprofile_ops.backtrace(regs, backtrace); - oprofile_end_trace(cpu_buf); -} - -void oprofile_add_ext_hw_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel, - struct task_struct *task) -{ - __oprofile_add_ext_sample(pc, regs, event, is_kernel, task); -} - -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, - unsigned long event, int is_kernel) -{ - __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL); -} - -void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) -{ - int is_kernel; - unsigned long pc; - - if (likely(regs)) { - is_kernel = !user_mode(regs); - pc = profile_pc(regs); - } else { - is_kernel = 0; /* This value will not be used */ - pc = ESCAPE_CODE; /* as this causes an early return. */ - } - - __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL); -} - -/* - * Add samples with data to the ring buffer. - * - * Use oprofile_add_data(&entry, val) to add data and - * oprofile_write_commit(&entry) to commit the sample. - */ -void -oprofile_write_reserve(struct op_entry *entry, struct pt_regs * const regs, - unsigned long pc, int code, int size) -{ - struct op_sample *sample; - int is_kernel = !user_mode(regs); - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - - cpu_buf->sample_received++; - - /* no backtraces for samples with data */ - if (op_add_code(cpu_buf, 0, is_kernel, current)) - goto fail; - - sample = op_cpu_buffer_write_reserve(entry, size + 2); - if (!sample) - goto fail; - sample->eip = ESCAPE_CODE; - sample->event = 0; /* no flags */ - - op_cpu_buffer_add_data(entry, code); - op_cpu_buffer_add_data(entry, pc); - - return; - -fail: - entry->event = NULL; - cpu_buf->sample_lost_overflow++; -} - -int oprofile_add_data(struct op_entry *entry, unsigned long val) -{ - if (!entry->event) - return 0; - return op_cpu_buffer_add_data(entry, val); -} - -int oprofile_add_data64(struct op_entry *entry, u64 val) -{ - if (!entry->event) - return 0; - if (op_cpu_buffer_get_size(entry) < 2) - /* - * the function returns 0 to indicate a too small - * buffer, even if there is some space left - */ - return 0; - if (!op_cpu_buffer_add_data(entry, (u32)val)) - return 0; - return op_cpu_buffer_add_data(entry, (u32)(val >> 32)); -} - -int oprofile_write_commit(struct op_entry *entry) -{ - if (!entry->event) - return -EINVAL; - return op_cpu_buffer_write_commit(entry); -} - -void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - log_sample(cpu_buf, pc, 0, is_kernel, event, NULL); -} - -void oprofile_add_trace(unsigned long pc) -{ - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); - - if (!cpu_buf->tracing) - return; - - /* - * broken frame can give an eip with the same value as an - * escape code, abort the trace if we get it - */ - if (pc == ESCAPE_CODE) - goto fail; - - if (op_add_sample(cpu_buf, pc, 0)) - goto fail; - - return; -fail: - cpu_buf->tracing = 0; - cpu_buf->backtrace_aborted++; - return; -} - -/* - * This serves to avoid cpu buffer overflow, and makes sure - * the task mortuary progresses - * - * By using schedule_delayed_work_on and then schedule_delayed_work - * we guarantee this will stay on the correct cpu - */ -static void wq_sync_buffer(struct work_struct *work) -{ - struct oprofile_cpu_buffer *b = - container_of(work, struct oprofile_cpu_buffer, work.work); - if (b->cpu != smp_processor_id() && !cpu_online(b->cpu)) { - cancel_delayed_work(&b->work); - return; - } - sync_buffer(b->cpu); - - /* don't re-add the work if we're shutting down */ - if (work_enabled) - schedule_delayed_work(&b->work, DEFAULT_TIMER_EXPIRE); -} diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h deleted file mode 100644 index 31478c0cff87..000000000000 --- a/drivers/oprofile/cpu_buffer.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file cpu_buffer.h - * - * @remark Copyright 2002-2009 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - * @author Robert Richter <rob...@am...> - */ - -#ifndef OPROFILE_CPU_BUFFER_H -#define OPROFILE_CPU_BUFFER_H - -#include <linux/types.h> -#include <linux/spinlock.h> -#include <linux/workqueue.h> -#include <linux/cache.h> -#include <linux/sched.h> -#include <linux/ring_buffer.h> - -struct task_struct; - -int alloc_cpu_buffers(void); -void free_cpu_buffers(void); - -void start_cpu_work(void); -void end_cpu_work(void); -void flush_cpu_work(void); - -/* CPU buffer is composed of such entries (which are - * also used for context switch notes) - */ -struct op_sample { - unsigned long eip; - unsigned long event; - unsigned long data[]; -}; - -struct op_entry; - -struct oprofile_cpu_buffer { - unsigned long buffer_size; - struct task_struct *last_task; - int last_is_kernel; - int tracing; - unsigned long sample_received; - unsigned long sample_lost_overflow; - unsigned long backtrace_aborted; - unsigned long sample_invalid_eip; - int cpu; - struct delayed_work work; -}; - -DECLARE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer); - -/* - * Resets the cpu buffer to a sane state. - * - * reset these to invalid values; the next sample collected will - * populate the buffer with proper values to initialize the buffer - */ -static inline void op_cpu_buffer_reset(int cpu) -{ - struct oprofile_cpu_buffer *cpu_buf = &per_cpu(op_cpu_buffer, cpu); - - cpu_buf->last_is_kernel = -1; - cpu_buf->last_task = NULL; -} - -/* - * op_cpu_buffer_add_data() and op_cpu_buffer_write_commit() may be - * called only if op_cpu_buffer_write_reserve() did not return NULL or - * entry->event != NULL, otherwise entry->size or entry->event will be - * used uninitialized. - */ - -struct op_sample -*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); -int op_cpu_buffer_write_commit(struct op_entry *entry); -struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu); -unsigned long op_cpu_buffer_entries(int cpu); - -/* returns the remaining free size of data in the entry */ -static inline -int op_cpu_buffer_add_data(struct op_entry *entry, unsigned long val) -{ - if (!entry->size) - return 0; - *entry->data = val; - entry->size--; - entry->data++; - return entry->size; -} - -/* returns the size of data in the entry */ -static inline -int op_cpu_buffer_get_size(struct op_entry *entry) -{ - return entry->size; -} - -/* returns 0 if empty or the size of data including the current value */ -static inline -int op_cpu_buffer_get_data(struct op_entry *entry, unsigned long *val) -{ - int size = entry->size; - if (!size) - return 0; - *val = *entry->data; - entry->size--; - entry->data++; - return size; -} - -/* extra data flags */ -#define KERNEL_CTX_SWITCH (1UL << 0) -#define IS_KERNEL (1UL << 1) -#define TRACE_BEGIN (1UL << 2) -#define USER_CTX_SWITCH (1UL << 3) - -#endif /* OPROFILE_CPU_BUFFER_H */ diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c deleted file mode 100644 index 6c9edc8bbc95..000000000000 --- a/drivers/oprofile/event_buffer.c +++ /dev/null @@ -1,209 +0,0 @@ -/** - * @file event_buffer.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - * - * This is the global event buffer that the user-space - * daemon reads from. The event buffer is an untyped array - * of unsigned longs. Entries are prefixed by the - * escape value ESCAPE_CODE followed by an identifying code. - */ - -#include <linux/vmalloc.h> -#include <linux/oprofile.h> -#include <linux/sched/signal.h> -#include <linux/capability.h> -#include <linux/dcookies.h> -#include <linux/fs.h> -#include <linux/uaccess.h> - -#include "oprof.h" -#include "event_buffer.h" -#include "oprofile_stats.h" - -DEFINE_MUTEX(buffer_mutex); - -static unsigned long buffer_opened; -static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); -static unsigned long *event_buffer; -static unsigned long buffer_size; -static unsigned long buffer_watershed; -static size_t buffer_pos; -/* atomic_t because wait_event checks it outside of buffer_mutex */ -static atomic_t buffer_ready = ATOMIC_INIT(0); - -/* - * Add an entry to the event buffer. When we get near to the end we - * wake up the process sleeping on the read() of the file. To protect - * the event_buffer this function may only be called when buffer_mutex - * is set. - */ -void add_event_entry(unsigned long value) -{ - /* - * This shouldn't happen since all workqueues or handlers are - * canceled or flushed before the event buffer is freed. - */ - if (!event_buffer) { - WARN_ON_ONCE(1); - return; - } - - if (buffer_pos == buffer_size) { - atomic_inc(&oprofile_stats.event_lost_overflow); - return; - } - - event_buffer[buffer_pos] = value; - if (++buffer_pos == buffer_size - buffer_watershed) { - atomic_set(&buffer_ready, 1); - wake_up(&buffer_wait); - } -} - - -/* Wake up the waiting process if any. This happens - * on "echo 0 >/dev/oprofile/enable" so the daemon - * processes the data remaining in the event buffer. - */ -void wake_up_buffer_waiter(void) -{ - mutex_lock(&buffer_mutex); - atomic_set(&buffer_ready, 1); - wake_up(&buffer_wait); - mutex_unlock(&buffer_mutex); -} - - -int alloc_event_buffer(void) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&oprofilefs_lock, flags); - buffer_size = oprofile_buffer_size; - buffer_watershed = oprofile_buffer_watershed; - raw_spin_unlock_irqrestore(&oprofilefs_lock, flags); - - if (buffer_watershed >= buffer_size) - return -EINVAL; - - buffer_pos = 0; - event_buffer = vmalloc(array_size(buffer_size, sizeof(unsigned long))); - if (!event_buffer) - return -ENOMEM; - - return 0; -} - - -void free_event_buffer(void) -{ - mutex_lock(&buffer_mutex); - vfree(event_buffer); - buffer_pos = 0; - event_buffer = NULL; - mutex_unlock(&buffer_mutex); -} - - -static int event_buffer_open(struct inode *inode, struct file *file) -{ - int err = -EPERM; - - if (!perfmon_capable()) - return -EPERM; - - if (test_and_set_bit_lock(0, &buffer_opened)) - return -EBUSY; - - /* Register as a user of dcookies - * to ensure they persist for the lifetime of - * the open event file - */ - err = -EINVAL; - file->private_data = dcookie_register(); - if (!file->private_data) - goto out; - - if ((err = oprofile_setup())) - goto fail; - - /* NB: the actual start happens from userspace - * echo 1 >/dev/oprofile/enable - */ - - return nonseekable_open(inode, file); - -fail: - dcookie_unregister(file->private_data); -out: - __clear_bit_unlock(0, &buffer_opened); - return err; -} - - -static int event_buffer_release(struct inode *inode, struct file *file) -{ - oprofile_stop(); - oprofile_shutdown(); - dcookie_unregister(file->private_data); - buffer_pos = 0; - atomic_set(&buffer_ready, 0); - __clear_bit_unlock(0, &buffer_opened); - return 0; -} - - -static ssize_t event_buffer_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - int retval = -EINVAL; - size_t const max = buffer_size * sizeof(unsigned long); - - /* handling partial reads is more trouble than it's worth */ - if (count != max || *offset) - return -EINVAL; - - wait_event_interruptible(buffer_wait, atomic_read(&buffer_ready)); - - if (signal_pending(current)) - return -EINTR; - - /* can't currently happen */ - if (!atomic_read(&buffer_ready)) - return -EAGAIN; - - mutex_lock(&buffer_mutex); - - /* May happen if the buffer is freed during pending reads. */ - if (!event_buffer) { - retval = -EINTR; - goto out; - } - - atomic_set(&buffer_ready, 0); - - retval = -EFAULT; - - count = buffer_pos * sizeof(unsigned long); - - if (copy_to_user(buf, event_buffer, count)) - goto out; - - retval = count; - buffer_pos = 0; - -out: - mutex_unlock(&buffer_mutex); - return retval; -} - -const struct file_operations event_buffer_fops = { - .open = event_buffer_open, - .release = event_buffer_release, - .read = event_buffer_read, - .llseek = no_llseek, -}; diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h deleted file mode 100644 index a8d5bb3cba89..000000000000 --- a/drivers/oprofile/event_buffer.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - * @file event_buffer.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#ifndef EVENT_BUFFER_H -#define EVENT_BUFFER_H - -#include <linux/types.h> -#include <linux/mutex.h> - -int alloc_event_buffer(void); - -void free_event_buffer(void); - -/** - * Add data to the event buffer. - * The data passed is free-form, but typically consists of - * file offsets, dcookies, context information, and ESCAPE codes. - */ -void add_event_entry(unsigned long data); - -/* wake up the process sleeping on the event file */ -void wake_up_buffer_waiter(void); - -#define INVALID_COOKIE ~0UL -#define NO_COOKIE 0UL - -extern const struct file_operations event_buffer_fops; - -/* mutex between sync_cpu_buffers() and the - * file reading code. - */ -extern struct mutex buffer_mutex; - -#endif /* EVENT_BUFFER_H */ diff --git a/drivers/oprofile/nmi_timer_int.c b/drivers/oprofile/nmi_timer_int.c deleted file mode 100644 index f343bd96609a..000000000000 --- a/drivers/oprofile/nmi_timer_int.c +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/** - * @file nmi_timer_int.c - * - * @remark Copyright 2011 Advanced Micro Devices, Inc. - * - * @author Robert Richter <rob...@am...> - */ - -#include <linux/init.h> -#include <linux/smp.h> -#include <linux/errno.h> -#include <linux/oprofile.h> -#include <linux/perf_event.h> - -#ifdef CONFIG_OPROFILE_NMI_TIMER - -static DEFINE_PER_CPU(struct perf_event *, nmi_timer_events); -static int ctr_running; - -static struct perf_event_attr nmi_timer_attr = { - .type = PERF_TYPE_HARDWARE, - .config = PERF_COUNT_HW_CPU_CYCLES, - .size = sizeof(struct perf_event_attr), - .pinned = 1, - .disabled = 1, -}; - -static void nmi_timer_callback(struct perf_event *event, - struct perf_sample_data *data, - struct pt_regs *regs) -{ - event->hw.interrupts = 0; /* don't throttle interrupts */ - oprofile_add_sample(regs, 0); -} - -static int nmi_timer_start_cpu(int cpu) -{ - struct perf_event *event = per_cpu(nmi_timer_events, cpu); - - if (!event) { - event = perf_event_create_kernel_counter(&nmi_timer_attr, cpu, NULL, - nmi_timer_callback, NULL); - if (IS_ERR(event)) - return PTR_ERR(event); - per_cpu(nmi_timer_events, cpu) = event; - } - - if (event && ctr_running) - perf_event_enable(event); - - return 0; -} - -static void nmi_timer_stop_cpu(int cpu) -{ - struct perf_event *event = per_cpu(nmi_timer_events, cpu); - - if (event && ctr_running) - perf_event_disable(event); -} - -static int nmi_timer_cpu_online(unsigned int cpu) -{ - nmi_timer_start_cpu(cpu); - return 0; -} -static int nmi_timer_cpu_predown(unsigned int cpu) -{ - nmi_timer_stop_cpu(cpu); - return 0; -} - -static int nmi_timer_start(void) -{ - int cpu; - - get_online_cpus(); - ctr_running = 1; - for_each_online_cpu(cpu) - nmi_timer_start_cpu(cpu); - put_online_cpus(); - - return 0; -} - -static void nmi_timer_stop(void) -{ - int cpu; - - get_online_cpus(); - for_each_online_cpu(cpu) - nmi_timer_stop_cpu(cpu); - ctr_running = 0; - put_online_cpus(); -} - -static enum cpuhp_state hp_online; - -static void nmi_timer_shutdown(void) -{ - struct perf_event *event; - int cpu; - - cpuhp_remove_state(hp_online); - for_each_possible_cpu(cpu) { - event = per_cpu(nmi_timer_events, cpu); - if (!event) - continue; - perf_event_disable(event); - per_cpu(nmi_timer_events, cpu) = NULL; - perf_event_release_kernel(event); - } -} - -static int nmi_timer_setup(void) -{ - int err; - u64 period; - - /* clock cycles per tick: */ - period = (u64)cpu_khz * 1000; - do_div(period, HZ); - nmi_timer_attr.sample_period = period; - - err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "oprofile/nmi:online", - nmi_timer_cpu_online, nmi_timer_cpu_predown); - if (err < 0) { - nmi_timer_shutdown(); - return err; - } - hp_online = err; - return 0; -} - -int __init op_nmi_timer_init(struct oprofile_operations *ops) -{ - int err = 0; - - err = nmi_timer_setup(); - if (err) - return err; - nmi_timer_shutdown(); /* only check, don't alloc */ - - ops->create_files = NULL; - ops->setup = nmi_timer_setup; - ops->shutdown = nmi_timer_shutdown; - ops->start = nmi_timer_start; - ops->stop = nmi_timer_stop; - ops->cpu_type = "timer"; - - printk(KERN_INFO "oprofile: using NMI timer interrupt.\n"); - - return 0; -} - -#endif diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c deleted file mode 100644 index ed2c3ec07024..000000000000 --- a/drivers/oprofile/oprof.c +++ /dev/null @@ -1,286 +0,0 @@ -/** - * @file oprof.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/init.h> -#include <linux/oprofile.h> -#include <linux/moduleparam.h> -#include <linux/workqueue.h> -#include <linux/time.h> -#include <linux/mutex.h> - -#include "oprof.h" -#include "event_buffer.h" -#include "cpu_buffer.h" -#include "buffer_sync.h" -#include "oprofile_stats.h" - -struct oprofile_operations oprofile_ops; - -unsigned long oprofile_started; -unsigned long oprofile_backtrace_depth; -static unsigned long is_setup; -static DEFINE_MUTEX(start_mutex); - -/* timer - 0 - use performance monitoring hardware if available - 1 - use the timer int mechanism regardless - */ -static int timer = 0; - -int oprofile_setup(void) -{ - int err; - - mutex_lock(&start_mutex); - - if ((err = alloc_cpu_buffers())) - goto out; - - if ((err = alloc_event_buffer())) - goto out1; - - if (oprofile_ops.setup && (err = oprofile_ops.setup())) - goto out2; - - /* Note even though this starts part of the - * profiling overhead, it's necessary to prevent - * us missing task deaths and eventually oopsing - * when trying to process the event buffer. - */ - if (oprofile_ops.sync_start) { - int sync_ret = oprofile_ops.sync_start(); - switch (sync_ret) { - case 0: - goto post_sync; - case 1: - goto do_generic; - case -1: - goto out3; - default: - goto out3; - } - } -do_generic: - if ((err = sync_start())) - goto out3; - -post_sync: - is_setup = 1; - mutex_unlock(&start_mutex); - return 0; - -out3: - if (oprofile_ops.shutdown) - oprofile_ops.shutdown(); -out2: - free_event_buffer(); -out1: - free_cpu_buffers(); -out: - mutex_unlock(&start_mutex); - return err; -} - -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX - -static void switch_worker(struct work_struct *work); -static DECLARE_DELAYED_WORK(switch_work, switch_worker); - -static void start_switch_worker(void) -{ - if (oprofile_ops.switch_events) - schedule_delayed_work(&switch_work, oprofile_time_slice); -} - -static void stop_switch_worker(void) -{ - cancel_delayed_work_sync(&switch_work); -} - -static void switch_worker(struct work_struct *work) -{ - if (oprofile_ops.switch_events()) - return; - - atomic_inc(&oprofile_stats.multiplex_counter); - start_switch_worker(); -} - -/* User inputs in ms, converts to jiffies */ -int oprofile_set_timeout(unsigned long val_msec) -{ - int err = 0; - unsigned long time_slice; - - mutex_lock(&start_mutex); - - if (oprofile_started) { - err = -EBUSY; - goto out; - } - - if (!oprofile_ops.switch_events) { - err = -EINVAL; - goto out; - } - - time_slice = msecs_to_jiffies(val_msec); - if (time_slice == MAX_JIFFY_OFFSET) { - err = -EINVAL; - goto out; - } - - oprofile_time_slice = time_slice; - -out: - mutex_unlock(&start_mutex); - return err; - -} - -#else - -static inline void start_switch_worker(void) { } -static inline void stop_switch_worker(void) { } - -#endif - -/* Actually start profiling (echo 1>/dev/oprofile/enable) */ -int oprofile_start(void) -{ - int err = -EINVAL; - - mutex_lock(&start_mutex); - - if (!is_setup) - goto out; - - err = 0; - - if (oprofile_started) - goto out; - - oprofile_reset_stats(); - - if ((err = oprofile_ops.start())) - goto out; - - start_switch_worker(); - - oprofile_started = 1; -out: - mutex_unlock(&start_mutex); - return err; -} - - -/* echo 0>/dev/oprofile/enable */ -void oprofile_stop(void) -{ - mutex_lock(&start_mutex); - if (!oprofile_started) - goto out; - oprofile_ops.stop(); - oprofile_started = 0; - - stop_switch_worker(); - - /* wake up the daemon to read what remains */ - wake_up_buffer_waiter(); -out: - mutex_unlock(&start_mutex); -} - - -void oprofile_shutdown(void) -{ - mutex_lock(&start_mutex); - if (oprofile_ops.sync_stop) { - int sync_ret = oprofile_ops.sync_stop(); - switch (sync_ret) { - case 0: - goto post_sync; - case 1: - goto do_generic; - default: - goto post_sync; - } - } -do_generic: - sync_stop(); -post_sync: - if (oprofile_ops.shutdown) - oprofile_ops.shutdown(); - is_setup = 0; - free_event_buffer(); - free_cpu_buffers(); - mutex_unlock(&start_mutex); -} - -int oprofile_set_ulong(unsigned long *addr, unsigned long val) -{ - int err = -EBUSY; - - mutex_lock(&start_mutex); - if (!oprofile_started) { - *addr = val; - err = 0; - } - mutex_unlock(&start_mutex); - - return err; -} - -static int timer_mode; - -static int __init oprofile_init(void) -{ - int err; - - /* always init architecture to setup backtrace support */ - timer_mode = 0; - err = oprofile_arch_init(&oprofile_ops); - if (!err) { - if (!timer && !oprofilefs_register()) - return 0; - oprofile_arch_exit(); - } - - /* setup timer mode: */ - timer_mode = 1; - /* no nmi timer mode if oprofile.timer is set */ - if (timer || op_nmi_timer_init(&oprofile_ops)) { - err = oprofile_timer_init(&oprofile_ops); - if (err) - return err; - } - - return oprofilefs_register(); -} - - -static void __exit oprofile_exit(void) -{ - oprofilefs_unregister(); - if (!timer_mode) - oprofile_arch_exit(); -} - - -module_init(oprofile_init); -module_exit(oprofile_exit); - -module_param_named(timer, timer, int, 0644); -MODULE_PARM_DESC(timer, "force use of timer interrupt"); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("John Levon <le...@mo...>"); -MODULE_DESCRIPTION("OProfile system profiler"); diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h deleted file mode 100644 index d5412060ab0f..000000000000 --- a/drivers/oprofile/oprof.h +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file oprof.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#ifndef OPROF_H -#define OPROF_H - -int oprofile_setup(void); -void oprofile_shutdown(void); - -int oprofilefs_register(void); -void oprofilefs_unregister(void); - -int oprofile_start(void); -void oprofile_stop(void); - -struct oprofile_operations; - -extern unsigned long oprofile_buffer_size; -extern unsigned long oprofile_cpu_buffer_size; -extern unsigned long oprofile_buffer_watershed; -extern unsigned long oprofile_time_slice; - -extern struct oprofile_operations oprofile_ops; -extern unsigned long oprofile_started; -extern unsigned long oprofile_backtrace_depth; - -struct dentry; - -void oprofile_create_files(struct dentry *root); -int oprofile_timer_init(struct oprofile_operations *ops); -#ifdef CONFIG_OPROFILE_NMI_TIMER -int op_nmi_timer_init(struct oprofile_operations *ops); -#else -static inline int op_nmi_timer_init(struct oprofile_operations *ops) -{ - return -ENODEV; -} -#endif - - -int oprofile_set_ulong(unsigned long *addr, unsigned long val); -int oprofile_set_timeout(unsigned long time); - -#endif /* OPROF_H */ diff --git a/drivers/oprofile/oprofile_files.c b/drivers/oprofile/oprofile_files.c deleted file mode 100644 index ee2cfce358b9..000000000000 --- a/drivers/oprofile/oprofile_files.c +++ /dev/null @@ -1,201 +0,0 @@ -/** - * @file oprofile_files.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#include <linux/fs.h> -#include <linux/oprofile.h> -#include <linux/jiffies.h> - -#include "event_buffer.h" -#include "oprofile_stats.h" -#include "oprof.h" - -#define BUFFER_SIZE_DEFAULT 131072 -#define CPU_BUFFER_SIZE_DEFAULT 8192 -#define BUFFER_WATERSHED_DEFAULT 32768 /* FIXME: tune */ -#define TIME_SLICE_DEFAULT 1 - -unsigned long oprofile_buffer_size; -unsigned long oprofile_cpu_buffer_size; -unsigned long oprofile_buffer_watershed; -unsigned long oprofile_time_slice; - -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX - -static ssize_t timeout_read(struct file *file, char __user *buf, - size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(jiffies_to_msecs(oprofile_time_slice), - buf, count, offset); -} - - -static ssize_t timeout_write(struct file *file, char const __user *buf, - size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - retval = oprofile_set_timeout(val); - - if (retval) - return retval; - return count; -} - - -static const struct file_operations timeout_fops = { - .read = timeout_read, - .write = timeout_write, - .llseek = default_llseek, -}; - -#endif - - -static ssize_t depth_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(oprofile_backtrace_depth, buf, count, - offset); -} - - -static ssize_t depth_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - if (!oprofile_ops.backtrace) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - retval = oprofile_set_ulong(&oprofile_backtrace_depth, val); - if (retval) - return retval; - - return count; -} - - -static const struct file_operations depth_fops = { - .read = depth_read, - .write = depth_write, - .llseek = default_llseek, -}; - - -static ssize_t pointer_size_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(sizeof(void *), buf, count, offset); -} - - -static const struct file_operations pointer_size_fops = { - .read = pointer_size_read, - .llseek = default_llseek, -}; - - -static ssize_t cpu_type_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_str_to_user(oprofile_ops.cpu_type, buf, count, offset); -} - - -static const struct file_operations cpu_type_fops = { - .read = cpu_type_read, - .llseek = default_llseek, -}; - - -static ssize_t enable_read(struct file *file, char __user *buf, size_t count, loff_t *offset) -{ - return oprofilefs_ulong_to_user(oprofile_started, buf, count, offset); -} - - -static ssize_t enable_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - unsigned long val; - int retval; - - if (*offset) - return -EINVAL; - - retval = oprofilefs_ulong_from_user(&val, buf, count); - if (retval <= 0) - return retval; - - retval = 0; - if (val) - retval = oprofile_start(); - else - oprofile_stop(); - - if (retval) - return retval; - return count; -} - - -static const struct file_operations enable_fops = { - .read = enable_read, - .write = enable_write, - .llseek = default_llseek, -}; - - -static ssize_t dump_write(struct file *file, char const __user *buf, size_t count, loff_t *offset) -{ - wake_up_buffer_waiter(); - return count; -} - - -static const struct file_operations dump_fops = { - .write = dump_write, - .llseek = noop_llseek, -}; - -void oprofile_create_files(struct dentry *root) -{ - /* reinitialize default values */ - oprofile_buffer_size = BUFFER_SIZE_DEFAULT; - oprofile_cpu_buffer_size = CPU_BUFFER_SIZE_DEFAULT; - oprofile_buffer_watershed = BUFFER_WATERSHED_DEFAULT; - oprofile_time_slice = msecs_to_jiffies(TIME_SLICE_DEFAULT); - - oprofilefs_create_file(root, "enable", &enable_fops); - ... [truncated message content] |
From: Paul E. M. <pa...@ke...> - 2021-01-14 15:24:43
|
On Thu, Jan 14, 2021 at 05:05:30PM +0530, Viresh Kumar wrote: > The "oprofile" user-space tools don't use the kernel OPROFILE support > any more, and haven't in a long time. User-space has been converted to > the perf interfaces. > > Remove kernel's old oprofile support. > > Suggested-by: Christoph Hellwig <hc...@in...> > Suggested-by: Linus Torvalds <tor...@li...> > Signed-off-by: Viresh Kumar <vir...@li...> For the RCU update: Acked-by: Paul E. McKenney <pa...@ke...> > --- > Documentation/RCU/NMI-RCU.rst | 3 +- > .../admin-guide/kernel-parameters.txt | 14 - > Documentation/process/magic-number.rst | 1 - > .../it_IT/process/magic-number.rst | 1 - > .../zh_CN/process/magic-number.rst | 1 - > MAINTAINERS | 11 - > arch/Kconfig | 32 - > drivers/oprofile/buffer_sync.c | 591 ------------------ > drivers/oprofile/buffer_sync.h | 22 - > drivers/oprofile/cpu_buffer.c | 465 -------------- > drivers/oprofile/cpu_buffer.h | 121 ---- > drivers/oprofile/event_buffer.c | 209 ------- > drivers/oprofile/event_buffer.h | 40 -- > drivers/oprofile/nmi_timer_int.c | 157 ----- > drivers/oprofile/oprof.c | 286 --------- > drivers/oprofile/oprof.h | 50 -- > drivers/oprofile/oprofile_files.c | 201 ------ > drivers/oprofile/oprofile_perf.c | 328 ---------- > drivers/oprofile/oprofile_stats.c | 84 --- > drivers/oprofile/oprofile_stats.h | 33 - > drivers/oprofile/oprofilefs.c | 300 --------- > drivers/oprofile/timer_int.c | 122 ---- > include/linux/oprofile.h | 209 ------- > init/Kconfig | 2 +- > 24 files changed, 2 insertions(+), 3281 deletions(-) > delete mode 100644 drivers/oprofile/buffer_sync.c > delete mode 100644 drivers/oprofile/buffer_sync.h > delete mode 100644 drivers/oprofile/cpu_buffer.c > delete mode 100644 drivers/oprofile/cpu_buffer.h > delete mode 100644 drivers/oprofile/event_buffer.c > delete mode 100644 drivers/oprofile/event_buffer.h > delete mode 100644 drivers/oprofile/nmi_timer_int.c > delete mode 100644 drivers/oprofile/oprof.c > delete mode 100644 drivers/oprofile/oprof.h > delete mode 100644 drivers/oprofile/oprofile_files.c > delete mode 100644 drivers/oprofile/oprofile_perf.c > delete mode 100644 drivers/oprofile/oprofile_stats.c > delete mode 100644 drivers/oprofile/oprofile_stats.h > delete mode 100644 drivers/oprofile/oprofilefs.c > delete mode 100644 drivers/oprofile/timer_int.c > delete mode 100644 include/linux/oprofile.h > > diff --git a/Documentation/RCU/NMI-RCU.rst b/Documentation/RCU/NMI-RCU.rst > index 180958388ff9..2a92bc685ef1 100644 > --- a/Documentation/RCU/NMI-RCU.rst > +++ b/Documentation/RCU/NMI-RCU.rst > @@ -8,8 +8,7 @@ Although RCU is usually used to protect read-mostly data structures, > it is possible to use RCU to provide dynamic non-maskable interrupt > handlers, as well as dynamic irq handlers. This document describes > how to do this, drawing loosely from Zwane Mwaikambo's NMI-timer > -work in "arch/x86/oprofile/nmi_timer_int.c" and in > -"arch/x86/kernel/traps.c". > +work in "arch/x86/kernel/traps.c". > > The relevant pieces of code are listed below, each followed by a > brief explanation:: > diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt > index 9e3cdb271d06..e860c681766b 100644 > --- a/Documentation/admin-guide/kernel-parameters.txt > +++ b/Documentation/admin-guide/kernel-parameters.txt > @@ -3458,20 +3458,6 @@ > For example, to override I2C bus2: > omap_mux=i2c2_scl.i2c2_scl=0x100,i2c2_sda.i2c2_sda=0x100 > > - oprofile.timer= [HW] > - Use timer interrupt instead of performance counters > - > - oprofile.cpu_type= Force an oprofile cpu type > - This might be useful if you have an older oprofile > - userland or if you want common events. > - Format: { arch_perfmon } > - arch_perfmon: [X86] Force use of architectural > - perfmon on Intel CPUs instead of the > - CPU specific event set. > - timer: [X86] Force use of architectural NMI > - timer mode (see also oprofile.timer > - for generic hr timer mode) > - > oops=panic Always panic on oopses. Default is to just kill the > process, but there is a small probability of > deadlocking the machine. > diff --git a/Documentation/process/magic-number.rst b/Documentation/process/magic-number.rst > index e02ff5ffb653..c6dfe060ec2f 100644 > --- a/Documentation/process/magic-number.rst > +++ b/Documentation/process/magic-number.rst > @@ -135,7 +135,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo > SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` > SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` > LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` > -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` > M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` > VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` > KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` > diff --git a/Documentation/translations/it_IT/process/magic-number.rst b/Documentation/translations/it_IT/process/magic-number.rst > index 0243d32a0b59..1af30f4228f2 100644 > --- a/Documentation/translations/it_IT/process/magic-number.rst > +++ b/Documentation/translations/it_IT/process/magic-number.rst > @@ -141,7 +141,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo > SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` > SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` > LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` > -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` > M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` > VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` > KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` > diff --git a/Documentation/translations/zh_CN/process/magic-number.rst b/Documentation/translations/zh_CN/process/magic-number.rst > index de182bf4191c..7bb9d4165ed3 100644 > --- a/Documentation/translations/zh_CN/process/magic-number.rst > +++ b/Documentation/translations/zh_CN/process/magic-number.rst > @@ -124,7 +124,6 @@ FW_HEADER_MAGIC 0x65726F66 fw_header ``drivers/atm/fo > SLOT_MAGIC 0x67267321 slot ``drivers/hotplug/cpqphp.h`` > SLOT_MAGIC 0x67267322 slot ``drivers/hotplug/acpiphp.h`` > LO_MAGIC 0x68797548 nbd_device ``include/linux/nbd.h`` > -OPROFILE_MAGIC 0x6f70726f super_block ``drivers/oprofile/oprofilefs.h`` > M3_STATE_MAGIC 0x734d724d m3_state ``sound/oss/maestro3.c`` > VMALLOC_MAGIC 0x87654320 snd_alloc_track ``sound/core/memory.c`` > KMALLOC_MAGIC 0x87654321 snd_alloc_track ``sound/core/memory.c`` > diff --git a/MAINTAINERS b/MAINTAINERS > index cc1e6a5ee6e6..ae2c2cef9d96 100644 > --- a/MAINTAINERS > +++ b/MAINTAINERS > @@ -1414,7 +1414,6 @@ F: arch/arm*/include/asm/hw_breakpoint.h > F: arch/arm*/include/asm/perf_event.h > F: arch/arm*/kernel/hw_breakpoint.c > F: arch/arm*/kernel/perf_* > -F: arch/arm/oprofile/common.c > F: drivers/perf/ > F: include/linux/perf/arm_pmu.h > > @@ -4083,7 +4082,6 @@ W: http://www.ibm.com/developerworks/power/cell/ > F: arch/powerpc/include/asm/cell*.h > F: arch/powerpc/include/asm/spu*.h > F: arch/powerpc/include/uapi/asm/spu*.h > -F: arch/powerpc/oprofile/*cell* > F: arch/powerpc/platforms/cell/ > > CELLWISE CW2015 BATTERY DRIVER > @@ -13311,15 +13309,6 @@ S: Maintained > T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git > F: sound/drivers/opl4/ > > -OPROFILE > -M: Robert Richter <rr...@ke...> > -L: opr...@li... > -S: Maintained > -F: arch/*/include/asm/oprofile*.h > -F: arch/*/oprofile/ > -F: drivers/oprofile/ > -F: include/linux/oprofile.h > - > ORACLE CLUSTER FILESYSTEM 2 (OCFS2) > M: Mark Fasheh <ma...@fa...> > M: Joel Becker <jl...@ev...> > diff --git a/arch/Kconfig b/arch/Kconfig > index 24862d15f3a3..40277027a255 100644 > --- a/arch/Kconfig > +++ b/arch/Kconfig > @@ -33,38 +33,6 @@ config HOTPLUG_SMT > config GENERIC_ENTRY > bool > > -config OPROFILE > - tristate "OProfile system profiling" > - depends on PROFILING > - depends on HAVE_OPROFILE > - select RING_BUFFER > - select RING_BUFFER_ALLOW_SWAP > - help > - OProfile is a profiling system capable of profiling the > - whole system, include the kernel, kernel modules, libraries, > - and applications. > - > - If unsure, say N. > - > -config OPROFILE_EVENT_MULTIPLEX > - bool "OProfile multiplexing support (EXPERIMENTAL)" > - default n > - depends on OPROFILE && X86 > - help > - The number of hardware counters is limited. The multiplexing > - feature enables OProfile to gather more events than counters > - are provided by the hardware. This is realized by switching > - between events at a user specified time interval. > - > - If unsure, say N. > - > -config HAVE_OPROFILE > - bool > - > -config OPROFILE_NMI_TIMER > - def_bool y > - depends on PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !PPC64 > - > config KPROBES > bool "Kprobes" > depends on MODULES > diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c > deleted file mode 100644 > index cc917865f13a..000000000000 > --- a/drivers/oprofile/buffer_sync.c > +++ /dev/null > @@ -1,591 +0,0 @@ > -/** > - * @file buffer_sync.c > - * > - * @remark Copyright 2002-2009 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - * @author Barry Kasindorf > - * @author Robert Richter <rob...@am...> > - * > - * This is the core of the buffer management. Each > - * CPU buffer is processed and entered into the > - * global event buffer. Such processing is necessary > - * in several circumstances, mentioned below. > - * > - * The processing does the job of converting the > - * transitory EIP value into a persistent dentry/offset > - * value that the profiler can record at its leisure. > - * > - * See fs/dcookies.c for a description of the dentry/offset > - * objects. > - */ > - > -#include <linux/file.h> > -#include <linux/mm.h> > -#include <linux/workqueue.h> > -#include <linux/notifier.h> > -#include <linux/dcookies.h> > -#include <linux/profile.h> > -#include <linux/module.h> > -#include <linux/fs.h> > -#include <linux/oprofile.h> > -#include <linux/sched.h> > -#include <linux/sched/mm.h> > -#include <linux/sched/task.h> > -#include <linux/gfp.h> > - > -#include "oprofile_stats.h" > -#include "event_buffer.h" > -#include "cpu_buffer.h" > -#include "buffer_sync.h" > - > -static LIST_HEAD(dying_tasks); > -static LIST_HEAD(dead_tasks); > -static cpumask_var_t marked_cpus; > -static DEFINE_SPINLOCK(task_mortuary); > -static void process_task_mortuary(void); > - > -/* Take ownership of the task struct and place it on the > - * list for processing. Only after two full buffer syncs > - * does the task eventually get freed, because by then > - * we are sure we will not reference it again. > - * Can be invoked from softirq via RCU callback due to > - * call_rcu() of the task struct, hence the _irqsave. > - */ > -static int > -task_free_notify(struct notifier_block *self, unsigned long val, void *data) > -{ > - unsigned long flags; > - struct task_struct *task = data; > - spin_lock_irqsave(&task_mortuary, flags); > - list_add(&task->tasks, &dying_tasks); > - spin_unlock_irqrestore(&task_mortuary, flags); > - return NOTIFY_OK; > -} > - > - > -/* The task is on its way out. A sync of the buffer means we can catch > - * any remaining samples for this task. > - */ > -static int > -task_exit_notify(struct notifier_block *self, unsigned long val, void *data) > -{ > - /* To avoid latency problems, we only process the current CPU, > - * hoping that most samples for the task are on this CPU > - */ > - sync_buffer(raw_smp_processor_id()); > - return 0; > -} > - > - > -/* The task is about to try a do_munmap(). We peek at what it's going to > - * do, and if it's an executable region, process the samples first, so > - * we don't lose any. This does not have to be exact, it's a QoI issue > - * only. > - */ > -static int > -munmap_notify(struct notifier_block *self, unsigned long val, void *data) > -{ > - unsigned long addr = (unsigned long)data; > - struct mm_struct *mm = current->mm; > - struct vm_area_struct *mpnt; > - > - mmap_read_lock(mm); > - > - mpnt = find_vma(mm, addr); > - if (mpnt && mpnt->vm_file && (mpnt->vm_flags & VM_EXEC)) { > - mmap_read_unlock(mm); > - /* To avoid latency problems, we only process the current CPU, > - * hoping that most samples for the task are on this CPU > - */ > - sync_buffer(raw_smp_processor_id()); > - return 0; > - } > - > - mmap_read_unlock(mm); > - return 0; > -} > - > - > -/* We need to be told about new modules so we don't attribute to a previously > - * loaded module, or drop the samples on the floor. > - */ > -static int > -module_load_notify(struct notifier_block *self, unsigned long val, void *data) > -{ > -#ifdef CONFIG_MODULES > - if (val != MODULE_STATE_COMING) > - return NOTIFY_DONE; > - > - /* FIXME: should we process all CPU buffers ? */ > - mutex_lock(&buffer_mutex); > - add_event_entry(ESCAPE_CODE); > - add_event_entry(MODULE_LOADED_CODE); > - mutex_unlock(&buffer_mutex); > -#endif > - return NOTIFY_OK; > -} > - > - > -static struct notifier_block task_free_nb = { > - .notifier_call = task_free_notify, > -}; > - > -static struct notifier_block task_exit_nb = { > - .notifier_call = task_exit_notify, > -}; > - > -static struct notifier_block munmap_nb = { > - .notifier_call = munmap_notify, > -}; > - > -static struct notifier_block module_load_nb = { > - .notifier_call = module_load_notify, > -}; > - > -static void free_all_tasks(void) > -{ > - /* make sure we don't leak task structs */ > - process_task_mortuary(); > - process_task_mortuary(); > -} > - > -int sync_start(void) > -{ > - int err; > - > - if (!zalloc_cpumask_var(&marked_cpus, GFP_KERNEL)) > - return -ENOMEM; > - > - err = task_handoff_register(&task_free_nb); > - if (err) > - goto out1; > - err = profile_event_register(PROFILE_TASK_EXIT, &task_exit_nb); > - if (err) > - goto out2; > - err = profile_event_register(PROFILE_MUNMAP, &munmap_nb); > - if (err) > - goto out3; > - err = register_module_notifier(&module_load_nb); > - if (err) > - goto out4; > - > - start_cpu_work(); > - > -out: > - return err; > -out4: > - profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); > -out3: > - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); > -out2: > - task_handoff_unregister(&task_free_nb); > - free_all_tasks(); > -out1: > - free_cpumask_var(marked_cpus); > - goto out; > -} > - > - > -void sync_stop(void) > -{ > - end_cpu_work(); > - unregister_module_notifier(&module_load_nb); > - profile_event_unregister(PROFILE_MUNMAP, &munmap_nb); > - profile_event_unregister(PROFILE_TASK_EXIT, &task_exit_nb); > - task_handoff_unregister(&task_free_nb); > - barrier(); /* do all of the above first */ > - > - flush_cpu_work(); > - > - free_all_tasks(); > - free_cpumask_var(marked_cpus); > -} > - > - > -/* Optimisation. We can manage without taking the dcookie sem > - * because we cannot reach this code without at least one > - * dcookie user still being registered (namely, the reader > - * of the event buffer). */ > -static inline unsigned long fast_get_dcookie(const struct path *path) > -{ > - unsigned long cookie; > - > - if (path->dentry->d_flags & DCACHE_COOKIE) > - return (unsigned long)path->dentry; > - get_dcookie(path, &cookie); > - return cookie; > -} > - > - > -/* Look up the dcookie for the task's mm->exe_file, > - * which corresponds loosely to "application name". This is > - * not strictly necessary but allows oprofile to associate > - * shared-library samples with particular applications > - */ > -static unsigned long get_exec_dcookie(struct mm_struct *mm) > -{ > - unsigned long cookie = NO_COOKIE; > - struct file *exe_file; > - > - if (!mm) > - goto done; > - > - exe_file = get_mm_exe_file(mm); > - if (!exe_file) > - goto done; > - > - cookie = fast_get_dcookie(&exe_file->f_path); > - fput(exe_file); > -done: > - return cookie; > -} > - > - > -/* Convert the EIP value of a sample into a persistent dentry/offset > - * pair that can then be added to the global event buffer. We make > - * sure to do this lookup before a mm->mmap modification happens so > - * we don't lose track. > - * > - * The caller must ensure the mm is not nil (ie: not a kernel thread). > - */ > -static unsigned long > -lookup_dcookie(struct mm_struct *mm, unsigned long addr, off_t *offset) > -{ > - unsigned long cookie = NO_COOKIE; > - struct vm_area_struct *vma; > - > - mmap_read_lock(mm); > - for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) { > - > - if (addr < vma->vm_start || addr >= vma->vm_end) > - continue; > - > - if (vma->vm_file) { > - cookie = fast_get_dcookie(&vma->vm_file->f_path); > - *offset = (vma->vm_pgoff << PAGE_SHIFT) + addr - > - vma->vm_start; > - } else { > - /* must be an anonymous map */ > - *offset = addr; > - } > - > - break; > - } > - > - if (!vma) > - cookie = INVALID_COOKIE; > - mmap_read_unlock(mm); > - > - return cookie; > -} > - > -static unsigned long last_cookie = INVALID_COOKIE; > - > -static void add_cpu_switch(int i) > -{ > - add_event_entry(ESCAPE_CODE); > - add_event_entry(CPU_SWITCH_CODE); > - add_event_entry(i); > - last_cookie = INVALID_COOKIE; > -} > - > -static void add_kernel_ctx_switch(unsigned int in_kernel) > -{ > - add_event_entry(ESCAPE_CODE); > - if (in_kernel) > - add_event_entry(KERNEL_ENTER_SWITCH_CODE); > - else > - add_event_entry(KERNEL_EXIT_SWITCH_CODE); > -} > - > -static void > -add_user_ctx_switch(struct task_struct const *task, unsigned long cookie) > -{ > - add_event_entry(ESCAPE_CODE); > - add_event_entry(CTX_SWITCH_CODE); > - add_event_entry(task->pid); > - add_event_entry(cookie); > - /* Another code for daemon back-compat */ > - add_event_entry(ESCAPE_CODE); > - add_event_entry(CTX_TGID_CODE); > - add_event_entry(task->tgid); > -} > - > - > -static void add_cookie_switch(unsigned long cookie) > -{ > - add_event_entry(ESCAPE_CODE); > - add_event_entry(COOKIE_SWITCH_CODE); > - add_event_entry(cookie); > -} > - > - > -static void add_trace_begin(void) > -{ > - add_event_entry(ESCAPE_CODE); > - add_event_entry(TRACE_BEGIN_CODE); > -} > - > -static void add_data(struct op_entry *entry, struct mm_struct *mm) > -{ > - unsigned long code, pc, val; > - unsigned long cookie; > - off_t offset; > - > - if (!op_cpu_buffer_get_data(entry, &code)) > - return; > - if (!op_cpu_buffer_get_data(entry, &pc)) > - return; > - if (!op_cpu_buffer_get_size(entry)) > - return; > - > - if (mm) { > - cookie = lookup_dcookie(mm, pc, &offset); > - > - if (cookie == NO_COOKIE) > - offset = pc; > - if (cookie == INVALID_COOKIE) { > - atomic_inc(&oprofile_stats.sample_lost_no_mapping); > - offset = pc; > - } > - if (cookie != last_cookie) { > - add_cookie_switch(cookie); > - last_cookie = cookie; > - } > - } else > - offset = pc; > - > - add_event_entry(ESCAPE_CODE); > - add_event_entry(code); > - add_event_entry(offset); /* Offset from Dcookie */ > - > - while (op_cpu_buffer_get_data(entry, &val)) > - add_event_entry(val); > -} > - > -static inline void add_sample_entry(unsigned long offset, unsigned long event) > -{ > - add_event_entry(offset); > - add_event_entry(event); > -} > - > - > -/* > - * Add a sample to the global event buffer. If possible the > - * sample is converted into a persistent dentry/offset pair > - * for later lookup from userspace. Return 0 on failure. > - */ > -static int > -add_sample(struct mm_struct *mm, struct op_sample *s, int in_kernel) > -{ > - unsigned long cookie; > - off_t offset; > - > - if (in_kernel) { > - add_sample_entry(s->eip, s->event); > - return 1; > - } > - > - /* add userspace sample */ > - > - if (!mm) { > - atomic_inc(&oprofile_stats.sample_lost_no_mm); > - return 0; > - } > - > - cookie = lookup_dcookie(mm, s->eip, &offset); > - > - if (cookie == INVALID_COOKIE) { > - atomic_inc(&oprofile_stats.sample_lost_no_mapping); > - return 0; > - } > - > - if (cookie != last_cookie) { > - add_cookie_switch(cookie); > - last_cookie = cookie; > - } > - > - add_sample_entry(offset, s->event); > - > - return 1; > -} > - > - > -static void release_mm(struct mm_struct *mm) > -{ > - if (!mm) > - return; > - mmput(mm); > -} > - > -static inline int is_code(unsigned long val) > -{ > - return val == ESCAPE_CODE; > -} > - > - > -/* Move tasks along towards death. Any tasks on dead_tasks > - * will definitely have no remaining references in any > - * CPU buffers at this point, because we use two lists, > - * and to have reached the list, it must have gone through > - * one full sync already. > - */ > -static void process_task_mortuary(void) > -{ > - unsigned long flags; > - LIST_HEAD(local_dead_tasks); > - struct task_struct *task; > - struct task_struct *ttask; > - > - spin_lock_irqsave(&task_mortuary, flags); > - > - list_splice_init(&dead_tasks, &local_dead_tasks); > - list_splice_init(&dying_tasks, &dead_tasks); > - > - spin_unlock_irqrestore(&task_mortuary, flags); > - > - list_for_each_entry_safe(task, ttask, &local_dead_tasks, tasks) { > - list_del(&task->tasks); > - free_task(task); > - } > -} > - > - > -static void mark_done(int cpu) > -{ > - int i; > - > - cpumask_set_cpu(cpu, marked_cpus); > - > - for_each_online_cpu(i) { > - if (!cpumask_test_cpu(i, marked_cpus)) > - return; > - } > - > - /* All CPUs have been processed at least once, > - * we can process the mortuary once > - */ > - process_task_mortuary(); > - > - cpumask_clear(marked_cpus); > -} > - > - > -/* FIXME: this is not sufficient if we implement syscall barrier backtrace > - * traversal, the code switch to sb_sample_start at first kernel enter/exit > - * switch so we need a fifth state and some special handling in sync_buffer() > - */ > -typedef enum { > - sb_bt_ignore = -2, > - sb_buffer_start, > - sb_bt_start, > - sb_sample_start, > -} sync_buffer_state; > - > -/* Sync one of the CPU's buffers into the global event buffer. > - * Here we need to go through each batch of samples punctuated > - * by context switch notes, taking the task's mmap_lock and doing > - * lookup in task->mm->mmap to convert EIP into dcookie/offset > - * value. > - */ > -void sync_buffer(int cpu) > -{ > - struct mm_struct *mm = NULL; > - struct mm_struct *oldmm; > - unsigned long val; > - struct task_struct *new; > - unsigned long cookie = 0; > - int in_kernel = 1; > - sync_buffer_state state = sb_buffer_start; > - unsigned int i; > - unsigned long available; > - unsigned long flags; > - struct op_entry entry; > - struct op_sample *sample; > - > - mutex_lock(&buffer_mutex); > - > - add_cpu_switch(cpu); > - > - op_cpu_buffer_reset(cpu); > - available = op_cpu_buffer_entries(cpu); > - > - for (i = 0; i < available; ++i) { > - sample = op_cpu_buffer_read_entry(&entry, cpu); > - if (!sample) > - break; > - > - if (is_code(sample->eip)) { > - flags = sample->event; > - if (flags & TRACE_BEGIN) { > - state = sb_bt_start; > - add_trace_begin(); > - } > - if (flags & KERNEL_CTX_SWITCH) { > - /* kernel/userspace switch */ > - in_kernel = flags & IS_KERNEL; > - if (state == sb_buffer_start) > - state = sb_sample_start; > - add_kernel_ctx_switch(flags & IS_KERNEL); > - } > - if (flags & USER_CTX_SWITCH > - && op_cpu_buffer_get_data(&entry, &val)) { > - /* userspace context switch */ > - new = (struct task_struct *)val; > - oldmm = mm; > - release_mm(oldmm); > - mm = get_task_mm(new); > - if (mm != oldmm) > - cookie = get_exec_dcookie(mm); > - add_user_ctx_switch(new, cookie); > - } > - if (op_cpu_buffer_get_size(&entry)) > - add_data(&entry, mm); > - continue; > - } > - > - if (state < sb_bt_start) > - /* ignore sample */ > - continue; > - > - if (add_sample(mm, sample, in_kernel)) > - continue; > - > - /* ignore backtraces if failed to add a sample */ > - if (state == sb_bt_start) { > - state = sb_bt_ignore; > - atomic_inc(&oprofile_stats.bt_lost_no_mapping); > - } > - } > - release_mm(mm); > - > - mark_done(cpu); > - > - mutex_unlock(&buffer_mutex); > -} > - > -/* The function can be used to add a buffer worth of data directly to > - * the kernel buffer. The buffer is assumed to be a circular buffer. > - * Take the entries from index start and end at index end, wrapping > - * at max_entries. > - */ > -void oprofile_put_buff(unsigned long *buf, unsigned int start, > - unsigned int stop, unsigned int max) > -{ > - int i; > - > - i = start; > - > - mutex_lock(&buffer_mutex); > - while (i != stop) { > - add_event_entry(buf[i++]); > - > - if (i >= max) > - i = 0; > - } > - > - mutex_unlock(&buffer_mutex); > -} > - > diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h > deleted file mode 100644 > index 3110732c1835..000000000000 > --- a/drivers/oprofile/buffer_sync.h > +++ /dev/null > @@ -1,22 +0,0 @@ > -/** > - * @file buffer_sync.h > - * > - * @remark Copyright 2002 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - */ > - > -#ifndef OPROFILE_BUFFER_SYNC_H > -#define OPROFILE_BUFFER_SYNC_H > - > -/* add the necessary profiling hooks */ > -int sync_start(void); > - > -/* remove the hooks */ > -void sync_stop(void); > - > -/* sync the given CPU's buffer */ > -void sync_buffer(int cpu); > - > -#endif /* OPROFILE_BUFFER_SYNC_H */ > diff --git a/drivers/oprofile/cpu_buffer.c b/drivers/oprofile/cpu_buffer.c > deleted file mode 100644 > index 9210a95cb4e6..000000000000 > --- a/drivers/oprofile/cpu_buffer.c > +++ /dev/null > @@ -1,465 +0,0 @@ > -/** > - * @file cpu_buffer.c > - * > - * @remark Copyright 2002-2009 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - * @author Barry Kasindorf <bar...@am...> > - * @author Robert Richter <rob...@am...> > - * > - * Each CPU has a local buffer that stores PC value/event > - * pairs. We also log context switches when we notice them. > - * Eventually each CPU's buffer is processed into the global > - * event buffer by sync_buffer(). > - * > - * We use a local buffer for two reasons: an NMI or similar > - * interrupt cannot synchronise, and high sampling rates > - * would lead to catastrophic global synchronisation if > - * a global buffer was used. > - */ > - > -#include <linux/sched.h> > -#include <linux/oprofile.h> > -#include <linux/errno.h> > - > -#include <asm/ptrace.h> > - > -#include "event_buffer.h" > -#include "cpu_buffer.h" > -#include "buffer_sync.h" > -#include "oprof.h" > - > -#define OP_BUFFER_FLAGS 0 > - > -static struct trace_buffer *op_ring_buffer; > -DEFINE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer); > - > -static void wq_sync_buffer(struct work_struct *work); > - > -#define DEFAULT_TIMER_EXPIRE (HZ / 10) > -static int work_enabled; > - > -unsigned long oprofile_get_cpu_buffer_size(void) > -{ > - return oprofile_cpu_buffer_size; > -} > - > -void oprofile_cpu_buffer_inc_smpl_lost(void) > -{ > - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); > - > - cpu_buf->sample_lost_overflow++; > -} > - > -void free_cpu_buffers(void) > -{ > - if (op_ring_buffer) > - ring_buffer_free(op_ring_buffer); > - op_ring_buffer = NULL; > -} > - > -#define RB_EVENT_HDR_SIZE 4 > - > -int alloc_cpu_buffers(void) > -{ > - int i; > - > - unsigned long buffer_size = oprofile_cpu_buffer_size; > - unsigned long byte_size = buffer_size * (sizeof(struct op_sample) + > - RB_EVENT_HDR_SIZE); > - > - op_ring_buffer = ring_buffer_alloc(byte_size, OP_BUFFER_FLAGS); > - if (!op_ring_buffer) > - goto fail; > - > - for_each_possible_cpu(i) { > - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); > - > - b->last_task = NULL; > - b->last_is_kernel = -1; > - b->tracing = 0; > - b->buffer_size = buffer_size; > - b->sample_received = 0; > - b->sample_lost_overflow = 0; > - b->backtrace_aborted = 0; > - b->sample_invalid_eip = 0; > - b->cpu = i; > - INIT_DELAYED_WORK(&b->work, wq_sync_buffer); > - } > - return 0; > - > -fail: > - free_cpu_buffers(); > - return -ENOMEM; > -} > - > -void start_cpu_work(void) > -{ > - int i; > - > - work_enabled = 1; > - > - for_each_online_cpu(i) { > - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); > - > - /* > - * Spread the work by 1 jiffy per cpu so they dont all > - * fire at once. > - */ > - schedule_delayed_work_on(i, &b->work, DEFAULT_TIMER_EXPIRE + i); > - } > -} > - > -void end_cpu_work(void) > -{ > - work_enabled = 0; > -} > - > -void flush_cpu_work(void) > -{ > - int i; > - > - for_each_online_cpu(i) { > - struct oprofile_cpu_buffer *b = &per_cpu(op_cpu_buffer, i); > - > - /* these works are per-cpu, no need for flush_sync */ > - flush_delayed_work(&b->work); > - } > -} > - > -/* > - * This function prepares the cpu buffer to write a sample. > - * > - * Struct op_entry is used during operations on the ring buffer while > - * struct op_sample contains the data that is stored in the ring > - * buffer. Struct entry can be uninitialized. The function reserves a > - * data array that is specified by size. Use > - * op_cpu_buffer_write_commit() after preparing the sample. In case of > - * errors a null pointer is returned, otherwise the pointer to the > - * sample. > - * > - */ > -struct op_sample > -*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size) > -{ > - entry->event = ring_buffer_lock_reserve > - (op_ring_buffer, sizeof(struct op_sample) + > - size * sizeof(entry->sample->data[0])); > - if (!entry->event) > - return NULL; > - entry->sample = ring_buffer_event_data(entry->event); > - entry->size = size; > - entry->data = entry->sample->data; > - > - return entry->sample; > -} > - > -int op_cpu_buffer_write_commit(struct op_entry *entry) > -{ > - return ring_buffer_unlock_commit(op_ring_buffer, entry->event); > -} > - > -struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu) > -{ > - struct ring_buffer_event *e; > - e = ring_buffer_consume(op_ring_buffer, cpu, NULL, NULL); > - if (!e) > - return NULL; > - > - entry->event = e; > - entry->sample = ring_buffer_event_data(e); > - entry->size = (ring_buffer_event_length(e) - sizeof(struct op_sample)) > - / sizeof(entry->sample->data[0]); > - entry->data = entry->sample->data; > - return entry->sample; > -} > - > -unsigned long op_cpu_buffer_entries(int cpu) > -{ > - return ring_buffer_entries_cpu(op_ring_buffer, cpu); > -} > - > -static int > -op_add_code(struct oprofile_cpu_buffer *cpu_buf, unsigned long backtrace, > - int is_kernel, struct task_struct *task) > -{ > - struct op_entry entry; > - struct op_sample *sample; > - unsigned long flags; > - int size; > - > - flags = 0; > - > - if (backtrace) > - flags |= TRACE_BEGIN; > - > - /* notice a switch from user->kernel or vice versa */ > - is_kernel = !!is_kernel; > - if (cpu_buf->last_is_kernel != is_kernel) { > - cpu_buf->last_is_kernel = is_kernel; > - flags |= KERNEL_CTX_SWITCH; > - if (is_kernel) > - flags |= IS_KERNEL; > - } > - > - /* notice a task switch */ > - if (cpu_buf->last_task != task) { > - cpu_buf->last_task = task; > - flags |= USER_CTX_SWITCH; > - } > - > - if (!flags) > - /* nothing to do */ > - return 0; > - > - if (flags & USER_CTX_SWITCH) > - size = 1; > - else > - size = 0; > - > - sample = op_cpu_buffer_write_reserve(&entry, size); > - if (!sample) > - return -ENOMEM; > - > - sample->eip = ESCAPE_CODE; > - sample->event = flags; > - > - if (size) > - op_cpu_buffer_add_data(&entry, (unsigned long)task); > - > - op_cpu_buffer_write_commit(&entry); > - > - return 0; > -} > - > -static inline int > -op_add_sample(struct oprofile_cpu_buffer *cpu_buf, > - unsigned long pc, unsigned long event) > -{ > - struct op_entry entry; > - struct op_sample *sample; > - > - sample = op_cpu_buffer_write_reserve(&entry, 0); > - if (!sample) > - return -ENOMEM; > - > - sample->eip = pc; > - sample->event = event; > - > - return op_cpu_buffer_write_commit(&entry); > -} > - > -/* > - * This must be safe from any context. > - * > - * is_kernel is needed because on some architectures you cannot > - * tell if you are in kernel or user space simply by looking at > - * pc. We tag this in the buffer by generating kernel enter/exit > - * events whenever is_kernel changes > - */ > -static int > -log_sample(struct oprofile_cpu_buffer *cpu_buf, unsigned long pc, > - unsigned long backtrace, int is_kernel, unsigned long event, > - struct task_struct *task) > -{ > - struct task_struct *tsk = task ? task : current; > - cpu_buf->sample_received++; > - > - if (pc == ESCAPE_CODE) { > - cpu_buf->sample_invalid_eip++; > - return 0; > - } > - > - if (op_add_code(cpu_buf, backtrace, is_kernel, tsk)) > - goto fail; > - > - if (op_add_sample(cpu_buf, pc, event)) > - goto fail; > - > - return 1; > - > -fail: > - cpu_buf->sample_lost_overflow++; > - return 0; > -} > - > -static inline void oprofile_begin_trace(struct oprofile_cpu_buffer *cpu_buf) > -{ > - cpu_buf->tracing = 1; > -} > - > -static inline void oprofile_end_trace(struct oprofile_cpu_buffer *cpu_buf) > -{ > - cpu_buf->tracing = 0; > -} > - > -static inline void > -__oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, > - unsigned long event, int is_kernel, > - struct task_struct *task) > -{ > - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); > - unsigned long backtrace = oprofile_backtrace_depth; > - > - /* > - * if log_sample() fail we can't backtrace since we lost the > - * source of this event > - */ > - if (!log_sample(cpu_buf, pc, backtrace, is_kernel, event, task)) > - /* failed */ > - return; > - > - if (!backtrace) > - return; > - > - oprofile_begin_trace(cpu_buf); > - oprofile_ops.backtrace(regs, backtrace); > - oprofile_end_trace(cpu_buf); > -} > - > -void oprofile_add_ext_hw_sample(unsigned long pc, struct pt_regs * const regs, > - unsigned long event, int is_kernel, > - struct task_struct *task) > -{ > - __oprofile_add_ext_sample(pc, regs, event, is_kernel, task); > -} > - > -void oprofile_add_ext_sample(unsigned long pc, struct pt_regs * const regs, > - unsigned long event, int is_kernel) > -{ > - __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL); > -} > - > -void oprofile_add_sample(struct pt_regs * const regs, unsigned long event) > -{ > - int is_kernel; > - unsigned long pc; > - > - if (likely(regs)) { > - is_kernel = !user_mode(regs); > - pc = profile_pc(regs); > - } else { > - is_kernel = 0; /* This value will not be used */ > - pc = ESCAPE_CODE; /* as this causes an early return. */ > - } > - > - __oprofile_add_ext_sample(pc, regs, event, is_kernel, NULL); > -} > - > -/* > - * Add samples with data to the ring buffer. > - * > - * Use oprofile_add_data(&entry, val) to add data and > - * oprofile_write_commit(&entry) to commit the sample. > - */ > -void > -oprofile_write_reserve(struct op_entry *entry, struct pt_regs * const regs, > - unsigned long pc, int code, int size) > -{ > - struct op_sample *sample; > - int is_kernel = !user_mode(regs); > - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); > - > - cpu_buf->sample_received++; > - > - /* no backtraces for samples with data */ > - if (op_add_code(cpu_buf, 0, is_kernel, current)) > - goto fail; > - > - sample = op_cpu_buffer_write_reserve(entry, size + 2); > - if (!sample) > - goto fail; > - sample->eip = ESCAPE_CODE; > - sample->event = 0; /* no flags */ > - > - op_cpu_buffer_add_data(entry, code); > - op_cpu_buffer_add_data(entry, pc); > - > - return; > - > -fail: > - entry->event = NULL; > - cpu_buf->sample_lost_overflow++; > -} > - > -int oprofile_add_data(struct op_entry *entry, unsigned long val) > -{ > - if (!entry->event) > - return 0; > - return op_cpu_buffer_add_data(entry, val); > -} > - > -int oprofile_add_data64(struct op_entry *entry, u64 val) > -{ > - if (!entry->event) > - return 0; > - if (op_cpu_buffer_get_size(entry) < 2) > - /* > - * the function returns 0 to indicate a too small > - * buffer, even if there is some space left > - */ > - return 0; > - if (!op_cpu_buffer_add_data(entry, (u32)val)) > - return 0; > - return op_cpu_buffer_add_data(entry, (u32)(val >> 32)); > -} > - > -int oprofile_write_commit(struct op_entry *entry) > -{ > - if (!entry->event) > - return -EINVAL; > - return op_cpu_buffer_write_commit(entry); > -} > - > -void oprofile_add_pc(unsigned long pc, int is_kernel, unsigned long event) > -{ > - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); > - log_sample(cpu_buf, pc, 0, is_kernel, event, NULL); > -} > - > -void oprofile_add_trace(unsigned long pc) > -{ > - struct oprofile_cpu_buffer *cpu_buf = this_cpu_ptr(&op_cpu_buffer); > - > - if (!cpu_buf->tracing) > - return; > - > - /* > - * broken frame can give an eip with the same value as an > - * escape code, abort the trace if we get it > - */ > - if (pc == ESCAPE_CODE) > - goto fail; > - > - if (op_add_sample(cpu_buf, pc, 0)) > - goto fail; > - > - return; > -fail: > - cpu_buf->tracing = 0; > - cpu_buf->backtrace_aborted++; > - return; > -} > - > -/* > - * This serves to avoid cpu buffer overflow, and makes sure > - * the task mortuary progresses > - * > - * By using schedule_delayed_work_on and then schedule_delayed_work > - * we guarantee this will stay on the correct cpu > - */ > -static void wq_sync_buffer(struct work_struct *work) > -{ > - struct oprofile_cpu_buffer *b = > - container_of(work, struct oprofile_cpu_buffer, work.work); > - if (b->cpu != smp_processor_id() && !cpu_online(b->cpu)) { > - cancel_delayed_work(&b->work); > - return; > - } > - sync_buffer(b->cpu); > - > - /* don't re-add the work if we're shutting down */ > - if (work_enabled) > - schedule_delayed_work(&b->work, DEFAULT_TIMER_EXPIRE); > -} > diff --git a/drivers/oprofile/cpu_buffer.h b/drivers/oprofile/cpu_buffer.h > deleted file mode 100644 > index 31478c0cff87..000000000000 > --- a/drivers/oprofile/cpu_buffer.h > +++ /dev/null > @@ -1,121 +0,0 @@ > -/** > - * @file cpu_buffer.h > - * > - * @remark Copyright 2002-2009 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - * @author Robert Richter <rob...@am...> > - */ > - > -#ifndef OPROFILE_CPU_BUFFER_H > -#define OPROFILE_CPU_BUFFER_H > - > -#include <linux/types.h> > -#include <linux/spinlock.h> > -#include <linux/workqueue.h> > -#include <linux/cache.h> > -#include <linux/sched.h> > -#include <linux/ring_buffer.h> > - > -struct task_struct; > - > -int alloc_cpu_buffers(void); > -void free_cpu_buffers(void); > - > -void start_cpu_work(void); > -void end_cpu_work(void); > -void flush_cpu_work(void); > - > -/* CPU buffer is composed of such entries (which are > - * also used for context switch notes) > - */ > -struct op_sample { > - unsigned long eip; > - unsigned long event; > - unsigned long data[]; > -}; > - > -struct op_entry; > - > -struct oprofile_cpu_buffer { > - unsigned long buffer_size; > - struct task_struct *last_task; > - int last_is_kernel; > - int tracing; > - unsigned long sample_received; > - unsigned long sample_lost_overflow; > - unsigned long backtrace_aborted; > - unsigned long sample_invalid_eip; > - int cpu; > - struct delayed_work work; > -}; > - > -DECLARE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer); > - > -/* > - * Resets the cpu buffer to a sane state. > - * > - * reset these to invalid values; the next sample collected will > - * populate the buffer with proper values to initialize the buffer > - */ > -static inline void op_cpu_buffer_reset(int cpu) > -{ > - struct oprofile_cpu_buffer *cpu_buf = &per_cpu(op_cpu_buffer, cpu); > - > - cpu_buf->last_is_kernel = -1; > - cpu_buf->last_task = NULL; > -} > - > -/* > - * op_cpu_buffer_add_data() and op_cpu_buffer_write_commit() may be > - * called only if op_cpu_buffer_write_reserve() did not return NULL or > - * entry->event != NULL, otherwise entry->size or entry->event will be > - * used uninitialized. > - */ > - > -struct op_sample > -*op_cpu_buffer_write_reserve(struct op_entry *entry, unsigned long size); > -int op_cpu_buffer_write_commit(struct op_entry *entry); > -struct op_sample *op_cpu_buffer_read_entry(struct op_entry *entry, int cpu); > -unsigned long op_cpu_buffer_entries(int cpu); > - > -/* returns the remaining free size of data in the entry */ > -static inline > -int op_cpu_buffer_add_data(struct op_entry *entry, unsigned long val) > -{ > - if (!entry->size) > - return 0; > - *entry->data = val; > - entry->size--; > - entry->data++; > - return entry->size; > -} > - > -/* returns the size of data in the entry */ > -static inline > -int op_cpu_buffer_get_size(struct op_entry *entry) > -{ > - return entry->size; > -} > - > -/* returns 0 if empty or the size of data including the current value */ > -static inline > -int op_cpu_buffer_get_data(struct op_entry *entry, unsigned long *val) > -{ > - int size = entry->size; > - if (!size) > - return 0; > - *val = *entry->data; > - entry->size--; > - entry->data++; > - return size; > -} > - > -/* extra data flags */ > -#define KERNEL_CTX_SWITCH (1UL << 0) > -#define IS_KERNEL (1UL << 1) > -#define TRACE_BEGIN (1UL << 2) > -#define USER_CTX_SWITCH (1UL << 3) > - > -#endif /* OPROFILE_CPU_BUFFER_H */ > diff --git a/drivers/oprofile/event_buffer.c b/drivers/oprofile/event_buffer.c > deleted file mode 100644 > index 6c9edc8bbc95..000000000000 > --- a/drivers/oprofile/event_buffer.c > +++ /dev/null > @@ -1,209 +0,0 @@ > -/** > - * @file event_buffer.c > - * > - * @remark Copyright 2002 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - * > - * This is the global event buffer that the user-space > - * daemon reads from. The event buffer is an untyped array > - * of unsigned longs. Entries are prefixed by the > - * escape value ESCAPE_CODE followed by an identifying code. > - */ > - > -#include <linux/vmalloc.h> > -#include <linux/oprofile.h> > -#include <linux/sched/signal.h> > -#include <linux/capability.h> > -#include <linux/dcookies.h> > -#include <linux/fs.h> > -#include <linux/uaccess.h> > - > -#include "oprof.h" > -#include "event_buffer.h" > -#include "oprofile_stats.h" > - > -DEFINE_MUTEX(buffer_mutex); > - > -static unsigned long buffer_opened; > -static DECLARE_WAIT_QUEUE_HEAD(buffer_wait); > -static unsigned long *event_buffer; > -static unsigned long buffer_size; > -static unsigned long buffer_watershed; > -static size_t buffer_pos; > -/* atomic_t because wait_event checks it outside of buffer_mutex */ > -static atomic_t buffer_ready = ATOMIC_INIT(0); > - > -/* > - * Add an entry to the event buffer. When we get near to the end we > - * wake up the process sleeping on the read() of the file. To protect > - * the event_buffer this function may only be called when buffer_mutex > - * is set. > - */ > -void add_event_entry(unsigned long value) > -{ > - /* > - * This shouldn't happen since all workqueues or handlers are > - * canceled or flushed before the event buffer is freed. > - */ > - if (!event_buffer) { > - WARN_ON_ONCE(1); > - return; > - } > - > - if (buffer_pos == buffer_size) { > - atomic_inc(&oprofile_stats.event_lost_overflow); > - return; > - } > - > - event_buffer[buffer_pos] = value; > - if (++buffer_pos == buffer_size - buffer_watershed) { > - atomic_set(&buffer_ready, 1); > - wake_up(&buffer_wait); > - } > -} > - > - > -/* Wake up the waiting process if any. This happens > - * on "echo 0 >/dev/oprofile/enable" so the daemon > - * processes the data remaining in the event buffer. > - */ > -void wake_up_buffer_waiter(void) > -{ > - mutex_lock(&buffer_mutex); > - atomic_set(&buffer_ready, 1); > - wake_up(&buffer_wait); > - mutex_unlock(&buffer_mutex); > -} > - > - > -int alloc_event_buffer(void) > -{ > - unsigned long flags; > - > - raw_spin_lock_irqsave(&oprofilefs_lock, flags); > - buffer_size = oprofile_buffer_size; > - buffer_watershed = oprofile_buffer_watershed; > - raw_spin_unlock_irqrestore(&oprofilefs_lock, flags); > - > - if (buffer_watershed >= buffer_size) > - return -EINVAL; > - > - buffer_pos = 0; > - event_buffer = vmalloc(array_size(buffer_size, sizeof(unsigned long))); > - if (!event_buffer) > - return -ENOMEM; > - > - return 0; > -} > - > - > -void free_event_buffer(void) > -{ > - mutex_lock(&buffer_mutex); > - vfree(event_buffer); > - buffer_pos = 0; > - event_buffer = NULL; > - mutex_unlock(&buffer_mutex); > -} > - > - > -static int event_buffer_open(struct inode *inode, struct file *file) > -{ > - int err = -EPERM; > - > - if (!perfmon_capable()) > - return -EPERM; > - > - if (test_and_set_bit_lock(0, &buffer_opened)) > - return -EBUSY; > - > - /* Register as a user of dcookies > - * to ensure they persist for the lifetime of > - * the open event file > - */ > - err = -EINVAL; > - file->private_data = dcookie_register(); > - if (!file->private_data) > - goto out; > - > - if ((err = oprofile_setup())) > - goto fail; > - > - /* NB: the actual start happens from userspace > - * echo 1 >/dev/oprofile/enable > - */ > - > - return nonseekable_open(inode, file); > - > -fail: > - dcookie_unregister(file->private_data); > -out: > - __clear_bit_unlock(0, &buffer_opened); > - return err; > -} > - > - > -static int event_buffer_release(struct inode *inode, struct file *file) > -{ > - oprofile_stop(); > - oprofile_shutdown(); > - dcookie_unregister(file->private_data); > - buffer_pos = 0; > - atomic_set(&buffer_ready, 0); > - __clear_bit_unlock(0, &buffer_opened); > - return 0; > -} > - > - > -static ssize_t event_buffer_read(struct file *file, char __user *buf, > - size_t count, loff_t *offset) > -{ > - int retval = -EINVAL; > - size_t const max = buffer_size * sizeof(unsigned long); > - > - /* handling partial reads is more trouble than it's worth */ > - if (count != max || *offset) > - return -EINVAL; > - > - wait_event_interruptible(buffer_wait, atomic_read(&buffer_ready)); > - > - if (signal_pending(current)) > - return -EINTR; > - > - /* can't currently happen */ > - if (!atomic_read(&buffer_ready)) > - return -EAGAIN; > - > - mutex_lock(&buffer_mutex); > - > - /* May happen if the buffer is freed during pending reads. */ > - if (!event_buffer) { > - retval = -EINTR; > - goto out; > - } > - > - atomic_set(&buffer_ready, 0); > - > - retval = -EFAULT; > - > - count = buffer_pos * sizeof(unsigned long); > - > - if (copy_to_user(buf, event_buffer, count)) > - goto out; > - > - retval = count; > - buffer_pos = 0; > - > -out: > - mutex_unlock(&buffer_mutex); > - return retval; > -} > - > -const struct file_operations event_buffer_fops = { > - .open = event_buffer_open, > - .release = event_buffer_release, > - .read = event_buffer_read, > - .llseek = no_llseek, > -}; > diff --git a/drivers/oprofile/event_buffer.h b/drivers/oprofile/event_buffer.h > deleted file mode 100644 > index a8d5bb3cba89..000000000000 > --- a/drivers/oprofile/event_buffer.h > +++ /dev/null > @@ -1,40 +0,0 @@ > -/** > - * @file event_buffer.h > - * > - * @remark Copyright 2002 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - */ > - > -#ifndef EVENT_BUFFER_H > -#define EVENT_BUFFER_H > - > -#include <linux/types.h> > -#include <linux/mutex.h> > - > -int alloc_event_buffer(void); > - > -void free_event_buffer(void); > - > -/** > - * Add data to the event buffer. > - * The data passed is free-form, but typically consists of > - * file offsets, dcookies, context information, and ESCAPE codes. > - */ > -void add_event_entry(unsigned long data); > - > -/* wake up the process sleeping on the event file */ > -void wake_up_buffer_waiter(void); > - > -#define INVALID_COOKIE ~0UL > -#define NO_COOKIE 0UL > - > -extern const struct file_operations event_buffer_fops; > - > -/* mutex between sync_cpu_buffers() and the > - * file reading code. > - */ > -extern struct mutex buffer_mutex; > - > -#endif /* EVENT_BUFFER_H */ > diff --git a/drivers/oprofile/nmi_timer_int.c b/drivers/oprofile/nmi_timer_int.c > deleted file mode 100644 > index f343bd96609a..000000000000 > --- a/drivers/oprofile/nmi_timer_int.c > +++ /dev/null > @@ -1,157 +0,0 @@ > -// SPDX-License-Identifier: GPL-2.0 > -/** > - * @file nmi_timer_int.c > - * > - * @remark Copyright 2011 Advanced Micro Devices, Inc. > - * > - * @author Robert Richter <rob...@am...> > - */ > - > -#include <linux/init.h> > -#include <linux/smp.h> > -#include <linux/errno.h> > -#include <linux/oprofile.h> > -#include <linux/perf_event.h> > - > -#ifdef CONFIG_OPROFILE_NMI_TIMER > - > -static DEFINE_PER_CPU(struct perf_event *, nmi_timer_events); > -static int ctr_running; > - > -static struct perf_event_attr nmi_timer_attr = { > - .type = PERF_TYPE_HARDWARE, > - .config = PERF_COUNT_HW_CPU_CYCLES, > - .size = sizeof(struct perf_event_attr), > - .pinned = 1, > - .disabled = 1, > -}; > - > -static void nmi_timer_callback(struct perf_event *event, > - struct perf_sample_data *data, > - struct pt_regs *regs) > -{ > - event->hw.interrupts = 0; /* don't throttle interrupts */ > - oprofile_add_sample(regs, 0); > -} > - > -static int nmi_timer_start_cpu(int cpu) > -{ > - struct perf_event *event = per_cpu(nmi_timer_events, cpu); > - > - if (!event) { > - event = perf_event_create_kernel_counter(&nmi_timer_attr, cpu, NULL, > - nmi_timer_callback, NULL); > - if (IS_ERR(event)) > - return PTR_ERR(event); > - per_cpu(nmi_timer_events, cpu) = event; > - } > - > - if (event && ctr_running) > - perf_event_enable(event); > - > - return 0; > -} > - > -static void nmi_timer_stop_cpu(int cpu) > -{ > - struct perf_event *event = per_cpu(nmi_timer_events, cpu); > - > - if (event && ctr_running) > - perf_event_disable(event); > -} > - > -static int nmi_timer_cpu_online(unsigned int cpu) > -{ > - nmi_timer_start_cpu(cpu); > - return 0; > -} > -static int nmi_timer_cpu_predown(unsigned int cpu) > -{ > - nmi_timer_stop_cpu(cpu); > - return 0; > -} > - > -static int nmi_timer_start(void) > -{ > - int cpu; > - > - get_online_cpus(); > - ctr_running = 1; > - for_each_online_cpu(cpu) > - nmi_timer_start_cpu(cpu); > - put_online_cpus(); > - > - return 0; > -} > - > -static void nmi_timer_stop(void) > -{ > - int cpu; > - > - get_online_cpus(); > - for_each_online_cpu(cpu) > - nmi_timer_stop_cpu(cpu); > - ctr_running = 0; > - put_online_cpus(); > -} > - > -static enum cpuhp_state hp_online; > - > -static void nmi_timer_shutdown(void) > -{ > - struct perf_event *event; > - int cpu; > - > - cpuhp_remove_state(hp_online); > - for_each_possible_cpu(cpu) { > - event = per_cpu(nmi_timer_events, cpu); > - if (!event) > - continue; > - perf_event_disable(event); > - per_cpu(nmi_timer_events, cpu) = NULL; > - perf_event_release_kernel(event); > - } > -} > - > -static int nmi_timer_setup(void) > -{ > - int err; > - u64 period; > - > - /* clock cycles per tick: */ > - period = (u64)cpu_khz * 1000; > - do_div(period, HZ); > - nmi_timer_attr.sample_period = period; > - > - err = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "oprofile/nmi:online", > - nmi_timer_cpu_online, nmi_timer_cpu_predown); > - if (err < 0) { > - nmi_timer_shutdown(); > - return err; > - } > - hp_online = err; > - return 0; > -} > - > -int __init op_nmi_timer_init(struct oprofile_operations *ops) > -{ > - int err = 0; > - > - err = nmi_timer_setup(); > - if (err) > - return err; > - nmi_timer_shutdown(); /* only check, don't alloc */ > - > - ops->create_files = NULL; > - ops->setup = nmi_timer_setup; > - ops->shutdown = nmi_timer_shutdown; > - ops->start = nmi_timer_start; > - ops->stop = nmi_timer_stop; > - ops->cpu_type = "timer"; > - > - printk(KERN_INFO "oprofile: using NMI timer interrupt.\n"); > - > - return 0; > -} > - > -#endif > diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c > deleted file mode 100644 > index ed2c3ec07024..000000000000 > --- a/drivers/oprofile/oprof.c > +++ /dev/null > @@ -1,286 +0,0 @@ > -/** > - * @file oprof.c > - * > - * @remark Copyright 2002 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - */ > - > -#include <linux/kernel.h> > -#include <linux/module.h> > -#include <linux/init.h> > -#include <linux/oprofile.h> > -#include <linux/moduleparam.h> > -#include <linux/workqueue.h> > -#include <linux/time.h> > -#include <linux/mutex.h> > - > -#include "oprof.h" > -#include "event_buffer.h" > -#include "cpu_buffer.h" > -#include "buffer_sync.h" > -#include "oprofile_stats.h" > - > -struct oprofile_operations oprofile_ops; > - > -unsigned long oprofile_started; > -unsigned long oprofile_backtrace_depth; > -static unsigned long is_setup; > -static DEFINE_MUTEX(start_mutex); > - > -/* timer > - 0 - use performance monitoring hardware if available > - 1 - use the timer int mechanism regardless > - */ > -static int timer = 0; > - > -int oprofile_setup(void) > -{ > - int err; > - > - mutex_lock(&start_mutex); > - > - if ((err = alloc_cpu_buffers())) > - goto out; > - > - if ((err = alloc_event_buffer())) > - goto out1; > - > - if (oprofile_ops.setup && (err = oprofile_ops.setup())) > - goto out2; > - > - /* Note even though this starts part of the > - * profiling overhead, it's necessary to prevent > - * us missing task deaths and eventually oopsing > - * when trying to process the event buffer. > - */ > - if (oprofile_ops.sync_start) { > - int sync_ret = oprofile_ops.sync_start(); > - switch (sync_ret) { > - case 0: > - goto post_sync; > - case 1: > - goto do_generic; > - case -1: > - goto out3; > - default: > - goto out3; > - } > - } > -do_generic: > - if ((err = sync_start())) > - goto out3; > - > -post_sync: > - is_setup = 1; > - mutex_unlock(&start_mutex); > - return 0; > - > -out3: > - if (oprofile_ops.shutdown) > - oprofile_ops.shutdown(); > -out2: > - free_event_buffer(); > -out1: > - free_cpu_buffers(); > -out: > - mutex_unlock(&start_mutex); > - return err; > -} > - > -#ifdef CONFIG_OPROFILE_EVENT_MULTIPLEX > - > -static void switch_worker(struct work_struct *work); > -static DECLARE_DELAYED_WORK(switch_work, switch_worker); > - > -static void start_switch_worker(void) > -{ > - if (oprofile_ops.switch_events) > - schedule_delayed_work(&switch_work, oprofile_time_slice); > -} > - > -static void stop_switch_worker(void) > -{ > - cancel_delayed_work_sync(&switch_work); > -} > - > -static void switch_worker(struct work_struct *work) > -{ > - if (oprofile_ops.switch_events()) > - return; > - > - atomic_inc(&oprofile_stats.multiplex_counter); > - start_switch_worker(); > -} > - > -/* User inputs in ms, converts to jiffies */ > -int oprofile_set_timeout(unsigned long val_msec) > -{ > - int err = 0; > - unsigned long time_slice; > - > - mutex_lock(&start_mutex); > - > - if (oprofile_started) { > - err = -EBUSY; > - goto out; > - } > - > - if (!oprofile_ops.switch_events) { > - err = -EINVAL; > - goto out; > - } > - > - time_slice = msecs_to_jiffies(val_msec); > - if (time_slice == MAX_JIFFY_OFFSET) { > - err = -EINVAL; > - goto out; > - } > - > - oprofile_time_slice = time_slice; > - > -out: > - mutex_unlock(&start_mutex); > - return err; > - > -} > - > -#else > - > -static inline void start_switch_worker(void) { } > -static inline void stop_switch_worker(void) { } > - > -#endif > - > -/* Actually start profiling (echo 1>/dev/oprofile/enable) */ > -int oprofile_start(void) > -{ > - int err = -EINVAL; > - > - mutex_lock(&start_mutex); > - > - if (!is_setup) > - goto out; > - > - err = 0; > - > - if (oprofile_started) > - goto out; > - > - oprofile_reset_stats(); > - > - if ((err = oprofile_ops.start())) > - goto out; > - > - start_switch_worker(); > - > - oprofile_started = 1; > -out: > - mutex_unlock(&start_mutex); > - return err; > -} > - > - > -/* echo 0>/dev/oprofile/enable */ > -void oprofile_stop(void) > -{ > - mutex_lock(&start_mutex); > - if (!oprofile_started) > - goto out; > - oprofile_ops.stop(); > - oprofile_started = 0; > - > - stop_switch_worker(); > - > - /* wake up the daemon to read what remains */ > - wake_up_buffer_waiter(); > -out: > - mutex_unlock(&start_mutex); > -} > - > - > -void oprofile_shutdown(void) > -{ > - mutex_lock(&start_mutex); > - if (oprofile_ops.sync_stop) { > - int sync_ret = oprofile_ops.sync_stop(); > - switch (sync_ret) { > - case 0: > - goto post_sync; > - case 1: > - goto do_generic; > - default: > - goto post_sync; > - } > - } > -do_generic: > - sync_stop(); > -post_sync: > - if (oprofile_ops.shutdown) > - oprofile_ops.shutdown(); > - is_setup = 0; > - free_event_buffer(); > - free_cpu_buffers(); > - mutex_unlock(&start_mutex); > -} > - > -int oprofile_set_ulong(unsigned long *addr, unsigned long val) > -{ > - int err = -EBUSY; > - > - mutex_lock(&start_mutex); > - if (!oprofile_started) { > - *addr = val; > - err = 0; > - } > - mutex_unlock(&start_mutex); > - > - return err; > -} > - > -static int timer_mode; > - > -static int __init oprofile_init(void) > -{ > - int err; > - > - /* always init architecture to setup backtrace support */ > - timer_mode = 0; > - err = oprofile_arch_init(&oprofile_ops); > - if (!err) { > - if (!timer && !oprofilefs_register()) > - return 0; > - oprofile_arch_exit(); > - } > - > - /* setup timer mode: */ > - timer_mode = 1; > - /* no nmi timer mode if oprofile.timer is set */ > - if (timer || op_nmi_timer_init(&oprofile_ops)) { > - err = oprofile_timer_init(&oprofile_ops); > - if (err) > - return err; > - } > - > - return oprofilefs_register(); > -} > - > - > -static void __exit oprofile_exit(void) > -{ > - oprofilefs_unregister(); > - if (!timer_mode) > - oprofile_arch_exit(); > -} > - > - > -module_init(oprofile_init); > -module_exit(oprofile_exit); > - > -module_param_named(timer, timer, int, 0644); > -MODULE_PARM_DESC(timer, "force use of timer interrupt"); > - > -MODULE_LICENSE("GPL"); > -MODULE_AUTHOR("John Levon <le...@mo...>"); > -MODULE_DESCRIPTION("OProfile system profiler"); > diff --git a/drivers/oprofile/oprof.h b/drivers/oprofile/oprof.h > deleted file mode 100644 > index d5412060ab0f..000000000000 > --- a/drivers/oprofile/oprof.h > +++ /dev/null > @@ -1,50 +0,0 @@ > -/** > - * @file oprof.h > - * > - * @remark Copyright 2002 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - */ > - > -#ifndef OPROF_H > -#define OPROF_H > - > -int oprofile_setup(void); > -void oprofile_shutdown(void); > - > -int oprofilefs_register(void); > -void oprofilefs_unregister(void); > - > -int oprofile_start(void); > -void oprofile_stop(void); > - > -struct oprofile_operations; > - > -extern unsigned long oprofile_buffer_size; > -extern unsigned long oprofile_cpu_buffer_size; > -extern unsigned long oprofile_buffer_watershed; > -extern unsigned long oprofile_time_slice; > - > -extern struct oprofile_operations oprofile_ops; > -extern unsigned long oprofile_started; > -extern unsigned long oprofile_backtrace_depth; > - > -struct dentry; > - > -void oprofile_create_files(struct dentry *root); > -int oprofile_timer_init(struct oprofile_operations *ops); > -#ifdef CONFIG_OPROFILE_NMI_TIMER > -int op_nmi_timer_init(struct oprofile_operations *ops); > -#else > -static inline int op_nmi_timer_init(struct oprofile_operations *ops) > -{ > - return -ENODEV; > -} > -#endif > - > -... [truncated message content] |
From: Viresh K. <vir...@li...> - 2021-01-14 12:01:56
|
The previous commit already disabled building oprofile, lets remove the oprofile directory now. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/powerpc/oprofile/Makefile | 19 - arch/powerpc/oprofile/backtrace.c | 120 -- arch/powerpc/oprofile/cell/pr_util.h | 110 -- arch/powerpc/oprofile/cell/spu_profiler.c | 248 --- arch/powerpc/oprofile/cell/spu_task_sync.c | 657 -------- arch/powerpc/oprofile/cell/vma_map.c | 279 ---- arch/powerpc/oprofile/common.c | 243 --- arch/powerpc/oprofile/op_model_7450.c | 207 --- arch/powerpc/oprofile/op_model_cell.c | 1709 -------------------- arch/powerpc/oprofile/op_model_fsl_emb.c | 380 ----- arch/powerpc/oprofile/op_model_pa6t.c | 227 --- arch/powerpc/oprofile/op_model_power4.c | 438 ----- 12 files changed, 4637 deletions(-) delete mode 100644 arch/powerpc/oprofile/Makefile delete mode 100644 arch/powerpc/oprofile/backtrace.c delete mode 100644 arch/powerpc/oprofile/cell/pr_util.h delete mode 100644 arch/powerpc/oprofile/cell/spu_profiler.c delete mode 100644 arch/powerpc/oprofile/cell/spu_task_sync.c delete mode 100644 arch/powerpc/oprofile/cell/vma_map.c delete mode 100644 arch/powerpc/oprofile/common.c delete mode 100644 arch/powerpc/oprofile/op_model_7450.c delete mode 100644 arch/powerpc/oprofile/op_model_cell.c delete mode 100644 arch/powerpc/oprofile/op_model_fsl_emb.c delete mode 100644 arch/powerpc/oprofile/op_model_pa6t.c delete mode 100644 arch/powerpc/oprofile/op_model_power4.c diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile deleted file mode 100644 index bb2d94c8cbe6..000000000000 --- a/arch/powerpc/oprofile/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC) - -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) common.o backtrace.o -oprofile-$(CONFIG_OPROFILE_CELL) += op_model_cell.o \ - cell/spu_profiler.o cell/vma_map.o \ - cell/spu_task_sync.o -oprofile-$(CONFIG_PPC_BOOK3S_64) += op_model_power4.o op_model_pa6t.o -oprofile-$(CONFIG_FSL_EMB_PERFMON) += op_model_fsl_emb.o -oprofile-$(CONFIG_PPC_BOOK3S_32) += op_model_7450.o diff --git a/arch/powerpc/oprofile/backtrace.c b/arch/powerpc/oprofile/backtrace.c deleted file mode 100644 index 9db7ada79d10..000000000000 --- a/arch/powerpc/oprofile/backtrace.c +++ /dev/null @@ -1,120 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** - * Copyright (C) 2005 Brian Rogan <bc...@co...>, IBM - * -**/ - -#include <linux/time.h> -#include <linux/oprofile.h> -#include <linux/sched.h> -#include <asm/processor.h> -#include <linux/uaccess.h> -#include <linux/compat.h> -#include <asm/oprofile_impl.h> - -#define STACK_SP(STACK) *(STACK) - -#define STACK_LR64(STACK) *((unsigned long *)(STACK) + 2) -#define STACK_LR32(STACK) *((unsigned int *)(STACK) + 1) - -#ifdef CONFIG_PPC64 -#define STACK_LR(STACK) STACK_LR64(STACK) -#else -#define STACK_LR(STACK) STACK_LR32(STACK) -#endif - -static unsigned int user_getsp32(unsigned int sp, int is_first) -{ - unsigned int stack_frame[2]; - void __user *p = compat_ptr(sp); - - /* - * The most likely reason for this is that we returned -EFAULT, - * which means that we've done all that we can do from - * interrupt context. - */ - if (copy_from_user_nofault(stack_frame, (void __user *)p, - sizeof(stack_frame))) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR32(stack_frame)); - - /* - * We do not enforce increasing stack addresses here because - * we may transition to a different stack, eg a signal handler. - */ - return STACK_SP(stack_frame); -} - -#ifdef CONFIG_PPC64 -static unsigned long user_getsp64(unsigned long sp, int is_first) -{ - unsigned long stack_frame[3]; - - if (copy_from_user_nofault(stack_frame, (void __user *)sp, - sizeof(stack_frame))) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR64(stack_frame)); - - return STACK_SP(stack_frame); -} -#endif - -static unsigned long kernel_getsp(unsigned long sp, int is_first) -{ - unsigned long *stack_frame = (unsigned long *)sp; - - if (!validate_sp(sp, current, STACK_FRAME_OVERHEAD)) - return 0; - - if (!is_first) - oprofile_add_trace(STACK_LR(stack_frame)); - - /* - * We do not enforce increasing stack addresses here because - * we might be transitioning from an interrupt stack to a kernel - * stack. validate_sp() is designed to understand this, so just - * use it. - */ - return STACK_SP(stack_frame); -} - -void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - unsigned long sp = regs->gpr[1]; - int first_frame = 1; - - /* We ditch the top stackframe so need to loop through an extra time */ - depth += 1; - - if (!user_mode(regs)) { - while (depth--) { - sp = kernel_getsp(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - } else { -#ifdef CONFIG_PPC64 - if (!is_32bit_task()) { - while (depth--) { - sp = user_getsp64(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - return; - } -#endif - - while (depth--) { - sp = user_getsp32(sp, first_frame); - if (!sp) - break; - first_frame = 0; - } - } -} diff --git a/arch/powerpc/oprofile/cell/pr_util.h b/arch/powerpc/oprofile/cell/pr_util.h deleted file mode 100644 index e198efa9113a..000000000000 --- a/arch/powerpc/oprofile/cell/pr_util.h +++ /dev/null @@ -1,110 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - /* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Author: Maynard Johnson <may...@us...> - */ - -#ifndef PR_UTIL_H -#define PR_UTIL_H - -#include <linux/cpumask.h> -#include <linux/oprofile.h> -#include <asm/cell-pmu.h> -#include <asm/cell-regs.h> -#include <asm/spu.h> - -/* Defines used for sync_start */ -#define SKIP_GENERIC_SYNC 0 -#define SYNC_START_ERROR -1 -#define DO_GENERIC_SYNC 1 -#define SPUS_PER_NODE 8 -#define DEFAULT_TIMER_EXPIRE (HZ / 10) - -extern struct delayed_work spu_work; -extern int spu_prof_running; - -#define TRACE_ARRAY_SIZE 1024 - -extern spinlock_t oprof_spu_smpl_arry_lck; - -struct spu_overlay_info { /* map of sections within an SPU overlay */ - unsigned int vma; /* SPU virtual memory address from elf */ - unsigned int size; /* size of section from elf */ - unsigned int offset; /* offset of section into elf file */ - unsigned int buf; -}; - -struct vma_to_fileoffset_map { /* map of sections within an SPU program */ - struct vma_to_fileoffset_map *next; /* list pointer */ - unsigned int vma; /* SPU virtual memory address from elf */ - unsigned int size; /* size of section from elf */ - unsigned int offset; /* offset of section into elf file */ - unsigned int guard_ptr; - unsigned int guard_val; - /* - * The guard pointer is an entry in the _ovly_buf_table, - * computed using ovly.buf as the index into the table. Since - * ovly.buf values begin at '1' to reference the first (or 0th) - * entry in the _ovly_buf_table, the computation subtracts 1 - * from ovly.buf. - * The guard value is stored in the _ovly_buf_table entry and - * is an index (starting at 1) back to the _ovly_table entry - * that is pointing at this _ovly_buf_table entry. So, for - * example, for an overlay scenario with one overlay segment - * and two overlay sections: - * - Section 1 points to the first entry of the - * _ovly_buf_table, which contains a guard value - * of '1', referencing the first (index=0) entry of - * _ovly_table. - * - Section 2 points to the second entry of the - * _ovly_buf_table, which contains a guard value - * of '2', referencing the second (index=1) entry of - * _ovly_table. - */ - -}; - -struct spu_buffer { - int last_guard_val; - int ctx_sw_seen; - unsigned long *buff; - unsigned int head, tail; -}; - - -/* The three functions below are for maintaining and accessing - * the vma-to-fileoffset map. - */ -struct vma_to_fileoffset_map *create_vma_map(const struct spu *spu, - unsigned long objectid); -unsigned int vma_map_lookup(struct vma_to_fileoffset_map *map, - unsigned int vma, const struct spu *aSpu, - int *grd_val); -void vma_map_free(struct vma_to_fileoffset_map *map); - -/* - * Entry point for SPU profiling. - * cycles_reset is the SPU_CYCLES count value specified by the user. - */ -int start_spu_profiling_cycles(unsigned int cycles_reset); -void start_spu_profiling_events(void); - -void stop_spu_profiling_cycles(void); -void stop_spu_profiling_events(void); - -/* add the necessary profiling hooks */ -int spu_sync_start(void); - -/* remove the hooks */ -int spu_sync_stop(void); - -/* Record SPU program counter samples to the oprofile event buffer. */ -void spu_sync_buffer(int spu_num, unsigned int *samples, - int num_samples); - -void set_spu_profiling_frequency(unsigned int freq_khz, unsigned int cycles_reset); - -#endif /* PR_UTIL_H */ diff --git a/arch/powerpc/oprofile/cell/spu_profiler.c b/arch/powerpc/oprofile/cell/spu_profiler.c deleted file mode 100644 index cdf883445a9f..000000000000 --- a/arch/powerpc/oprofile/cell/spu_profiler.c +++ /dev/null @@ -1,248 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Authors: Maynard Johnson <may...@us...> - * Carl Love <ca...@us...> - */ - -#include <linux/hrtimer.h> -#include <linux/smp.h> -#include <linux/slab.h> -#include <asm/cell-pmu.h> -#include <asm/time.h> -#include "pr_util.h" - -#define SCALE_SHIFT 14 - -static u32 *samples; - -/* spu_prof_running is a flag used to indicate if spu profiling is enabled - * or not. It is set by the routines start_spu_profiling_cycles() and - * start_spu_profiling_events(). The flag is cleared by the routines - * stop_spu_profiling_cycles() and stop_spu_profiling_events(). These - * routines are called via global_start() and global_stop() which are called in - * op_powerpc_start() and op_powerpc_stop(). These routines are called once - * per system as a result of the user starting/stopping oprofile. Hence, only - * one CPU per user at a time will be changing the value of spu_prof_running. - * In general, OProfile does not protect against multiple users trying to run - * OProfile at a time. - */ -int spu_prof_running; -static unsigned int profiling_interval; - -#define NUM_SPU_BITS_TRBUF 16 -#define SPUS_PER_TB_ENTRY 4 - -#define SPU_PC_MASK 0xFFFF - -DEFINE_SPINLOCK(oprof_spu_smpl_arry_lck); -static unsigned long oprof_spu_smpl_arry_lck_flags; - -void set_spu_profiling_frequency(unsigned int freq_khz, unsigned int cycles_reset) -{ - unsigned long ns_per_cyc; - - if (!freq_khz) - freq_khz = ppc_proc_freq/1000; - - /* To calculate a timeout in nanoseconds, the basic - * formula is ns = cycles_reset * (NSEC_PER_SEC / cpu frequency). - * To avoid floating point math, we use the scale math - * technique as described in linux/jiffies.h. We use - * a scale factor of SCALE_SHIFT, which provides 4 decimal places - * of precision. This is close enough for the purpose at hand. - * - * The value of the timeout should be small enough that the hw - * trace buffer will not get more than about 1/3 full for the - * maximum user specified (the LFSR value) hw sampling frequency. - * This is to ensure the trace buffer will never fill even if the - * kernel thread scheduling varies under a heavy system load. - */ - - ns_per_cyc = (USEC_PER_SEC << SCALE_SHIFT)/freq_khz; - profiling_interval = (ns_per_cyc * cycles_reset) >> SCALE_SHIFT; - -} - -/* - * Extract SPU PC from trace buffer entry - */ -static void spu_pc_extract(int cpu, int entry) -{ - /* the trace buffer is 128 bits */ - u64 trace_buffer[2]; - u64 spu_mask; - int spu; - - spu_mask = SPU_PC_MASK; - - /* Each SPU PC is 16 bits; hence, four spus in each of - * the two 64-bit buffer entries that make up the - * 128-bit trace_buffer entry. Process two 64-bit values - * simultaneously. - * trace[0] SPU PC contents are: 0 1 2 3 - * trace[1] SPU PC contents are: 4 5 6 7 - */ - - cbe_read_trace_buffer(cpu, trace_buffer); - - for (spu = SPUS_PER_TB_ENTRY-1; spu >= 0; spu--) { - /* spu PC trace entry is upper 16 bits of the - * 18 bit SPU program counter - */ - samples[spu * TRACE_ARRAY_SIZE + entry] - = (spu_mask & trace_buffer[0]) << 2; - samples[(spu + SPUS_PER_TB_ENTRY) * TRACE_ARRAY_SIZE + entry] - = (spu_mask & trace_buffer[1]) << 2; - - trace_buffer[0] = trace_buffer[0] >> NUM_SPU_BITS_TRBUF; - trace_buffer[1] = trace_buffer[1] >> NUM_SPU_BITS_TRBUF; - } -} - -static int cell_spu_pc_collection(int cpu) -{ - u32 trace_addr; - int entry; - - /* process the collected SPU PC for the node */ - - entry = 0; - - trace_addr = cbe_read_pm(cpu, trace_address); - while (!(trace_addr & CBE_PM_TRACE_BUF_EMPTY)) { - /* there is data in the trace buffer to process */ - spu_pc_extract(cpu, entry); - - entry++; - - if (entry >= TRACE_ARRAY_SIZE) - /* spu_samples is full */ - break; - - trace_addr = cbe_read_pm(cpu, trace_address); - } - - return entry; -} - - -static enum hrtimer_restart profile_spus(struct hrtimer *timer) -{ - ktime_t kt; - int cpu, node, k, num_samples, spu_num; - - if (!spu_prof_running) - goto stop; - - for_each_online_cpu(cpu) { - if (cbe_get_hw_thread_id(cpu)) - continue; - - node = cbe_cpu_to_node(cpu); - - /* There should only be one kernel thread at a time processing - * the samples. In the very unlikely case that the processing - * is taking a very long time and multiple kernel threads are - * started to process the samples. Make sure only one kernel - * thread is working on the samples array at a time. The - * sample array must be loaded and then processed for a given - * cpu. The sample array is not per cpu. - */ - spin_lock_irqsave(&oprof_spu_smpl_arry_lck, - oprof_spu_smpl_arry_lck_flags); - num_samples = cell_spu_pc_collection(cpu); - - if (num_samples == 0) { - spin_unlock_irqrestore(&oprof_spu_smpl_arry_lck, - oprof_spu_smpl_arry_lck_flags); - continue; - } - - for (k = 0; k < SPUS_PER_NODE; k++) { - spu_num = k + (node * SPUS_PER_NODE); - spu_sync_buffer(spu_num, - samples + (k * TRACE_ARRAY_SIZE), - num_samples); - } - - spin_unlock_irqrestore(&oprof_spu_smpl_arry_lck, - oprof_spu_smpl_arry_lck_flags); - - } - smp_wmb(); /* insure spu event buffer updates are written */ - /* don't want events intermingled... */ - - kt = profiling_interval; - if (!spu_prof_running) - goto stop; - hrtimer_forward(timer, timer->base->get_time(), kt); - return HRTIMER_RESTART; - - stop: - printk(KERN_INFO "SPU_PROF: spu-prof timer ending\n"); - return HRTIMER_NORESTART; -} - -static struct hrtimer timer; -/* - * Entry point for SPU cycle profiling. - * NOTE: SPU profiling is done system-wide, not per-CPU. - * - * cycles_reset is the count value specified by the user when - * setting up OProfile to count SPU_CYCLES. - */ -int start_spu_profiling_cycles(unsigned int cycles_reset) -{ - ktime_t kt; - - pr_debug("timer resolution: %lu\n", TICK_NSEC); - kt = profiling_interval; - hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - hrtimer_set_expires(&timer, kt); - timer.function = profile_spus; - - /* Allocate arrays for collecting SPU PC samples */ - samples = kcalloc(SPUS_PER_NODE * TRACE_ARRAY_SIZE, sizeof(u32), - GFP_KERNEL); - - if (!samples) - return -ENOMEM; - - spu_prof_running = 1; - hrtimer_start(&timer, kt, HRTIMER_MODE_REL); - schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); - - return 0; -} - -/* - * Entry point for SPU event profiling. - * NOTE: SPU profiling is done system-wide, not per-CPU. - * - * cycles_reset is the count value specified by the user when - * setting up OProfile to count SPU_CYCLES. - */ -void start_spu_profiling_events(void) -{ - spu_prof_running = 1; - schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); - - return; -} - -void stop_spu_profiling_cycles(void) -{ - spu_prof_running = 0; - hrtimer_cancel(&timer); - kfree(samples); - pr_debug("SPU_PROF: stop_spu_profiling_cycles issued\n"); -} - -void stop_spu_profiling_events(void) -{ - spu_prof_running = 0; -} diff --git a/arch/powerpc/oprofile/cell/spu_task_sync.c b/arch/powerpc/oprofile/cell/spu_task_sync.c deleted file mode 100644 index 489f993100d5..000000000000 --- a/arch/powerpc/oprofile/cell/spu_task_sync.c +++ /dev/null @@ -1,657 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Author: Maynard Johnson <may...@us...> - */ - -/* The purpose of this file is to handle SPU event task switching - * and to record SPU context information into the OProfile - * event buffer. - * - * Additionally, the spu_sync_buffer function is provided as a helper - * for recoding actual SPU program counter samples to the event buffer. - */ -#include <linux/dcookies.h> -#include <linux/kref.h> -#include <linux/mm.h> -#include <linux/fs.h> -#include <linux/file.h> -#include <linux/module.h> -#include <linux/notifier.h> -#include <linux/numa.h> -#include <linux/oprofile.h> -#include <linux/slab.h> -#include <linux/spinlock.h> -#include "pr_util.h" - -#define RELEASE_ALL 9999 - -static DEFINE_SPINLOCK(buffer_lock); -static DEFINE_SPINLOCK(cache_lock); -static int num_spu_nodes; -static int spu_prof_num_nodes; - -struct spu_buffer spu_buff[MAX_NUMNODES * SPUS_PER_NODE]; -struct delayed_work spu_work; -static unsigned max_spu_buff; - -static void spu_buff_add(unsigned long int value, int spu) -{ - /* spu buff is a circular buffer. Add entries to the - * head. Head is the index to store the next value. - * The buffer is full when there is one available entry - * in the queue, i.e. head and tail can't be equal. - * That way we can tell the difference between the - * buffer being full versus empty. - * - * ASSUMPTION: the buffer_lock is held when this function - * is called to lock the buffer, head and tail. - */ - int full = 1; - - if (spu_buff[spu].head >= spu_buff[spu].tail) { - if ((spu_buff[spu].head - spu_buff[spu].tail) - < (max_spu_buff - 1)) - full = 0; - - } else if (spu_buff[spu].tail > spu_buff[spu].head) { - if ((spu_buff[spu].tail - spu_buff[spu].head) - > 1) - full = 0; - } - - if (!full) { - spu_buff[spu].buff[spu_buff[spu].head] = value; - spu_buff[spu].head++; - - if (spu_buff[spu].head >= max_spu_buff) - spu_buff[spu].head = 0; - } else { - /* From the user's perspective make the SPU buffer - * size management/overflow look like we are using - * per cpu buffers. The user uses the same - * per cpu parameter to adjust the SPU buffer size. - * Increment the sample_lost_overflow to inform - * the user the buffer size needs to be increased. - */ - oprofile_cpu_buffer_inc_smpl_lost(); - } -} - -/* This function copies the per SPU buffers to the - * OProfile kernel buffer. - */ -static void sync_spu_buff(void) -{ - int spu; - unsigned long flags; - int curr_head; - - for (spu = 0; spu < num_spu_nodes; spu++) { - /* In case there was an issue and the buffer didn't - * get created skip it. - */ - if (spu_buff[spu].buff == NULL) - continue; - - /* Hold the lock to make sure the head/tail - * doesn't change while spu_buff_add() is - * deciding if the buffer is full or not. - * Being a little paranoid. - */ - spin_lock_irqsave(&buffer_lock, flags); - curr_head = spu_buff[spu].head; - spin_unlock_irqrestore(&buffer_lock, flags); - - /* Transfer the current contents to the kernel buffer. - * data can still be added to the head of the buffer. - */ - oprofile_put_buff(spu_buff[spu].buff, - spu_buff[spu].tail, - curr_head, max_spu_buff); - - spin_lock_irqsave(&buffer_lock, flags); - spu_buff[spu].tail = curr_head; - spin_unlock_irqrestore(&buffer_lock, flags); - } - -} - -static void wq_sync_spu_buff(struct work_struct *work) -{ - /* move data from spu buffers to kernel buffer */ - sync_spu_buff(); - - /* only reschedule if profiling is not done */ - if (spu_prof_running) - schedule_delayed_work(&spu_work, DEFAULT_TIMER_EXPIRE); -} - -/* Container for caching information about an active SPU task. */ -struct cached_info { - struct vma_to_fileoffset_map *map; - struct spu *the_spu; /* needed to access pointer to local_store */ - struct kref cache_ref; -}; - -static struct cached_info *spu_info[MAX_NUMNODES * 8]; - -static void destroy_cached_info(struct kref *kref) -{ - struct cached_info *info; - - info = container_of(kref, struct cached_info, cache_ref); - vma_map_free(info->map); - kfree(info); - module_put(THIS_MODULE); -} - -/* Return the cached_info for the passed SPU number. - * ATTENTION: Callers are responsible for obtaining the - * cache_lock if needed prior to invoking this function. - */ -static struct cached_info *get_cached_info(struct spu *the_spu, int spu_num) -{ - struct kref *ref; - struct cached_info *ret_info; - - if (spu_num >= num_spu_nodes) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Invalid index %d into spu info cache\n", - __func__, __LINE__, spu_num); - ret_info = NULL; - goto out; - } - if (!spu_info[spu_num] && the_spu) { - ref = spu_get_profile_private_kref(the_spu->ctx); - if (ref) { - spu_info[spu_num] = container_of(ref, struct cached_info, cache_ref); - kref_get(&spu_info[spu_num]->cache_ref); - } - } - - ret_info = spu_info[spu_num]; - out: - return ret_info; -} - - -/* Looks for cached info for the passed spu. If not found, the - * cached info is created for the passed spu. - * Returns 0 for success; otherwise, -1 for error. - */ -static int -prepare_cached_spu_info(struct spu *spu, unsigned long objectId) -{ - unsigned long flags; - struct vma_to_fileoffset_map *new_map; - int retval = 0; - struct cached_info *info; - - /* We won't bother getting cache_lock here since - * don't do anything with the cached_info that's returned. - */ - info = get_cached_info(spu, spu->number); - - if (info) { - pr_debug("Found cached SPU info.\n"); - goto out; - } - - /* Create cached_info and set spu_info[spu->number] to point to it. - * spu->number is a system-wide value, not a per-node value. - */ - info = kzalloc(sizeof(*info), GFP_KERNEL); - if (!info) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: create vma_map failed\n", - __func__, __LINE__); - retval = -ENOMEM; - goto err_alloc; - } - new_map = create_vma_map(spu, objectId); - if (!new_map) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: create vma_map failed\n", - __func__, __LINE__); - retval = -ENOMEM; - goto err_alloc; - } - - pr_debug("Created vma_map\n"); - info->map = new_map; - info->the_spu = spu; - kref_init(&info->cache_ref); - spin_lock_irqsave(&cache_lock, flags); - spu_info[spu->number] = info; - /* Increment count before passing off ref to SPUFS. */ - kref_get(&info->cache_ref); - - /* We increment the module refcount here since SPUFS is - * responsible for the final destruction of the cached_info, - * and it must be able to access the destroy_cached_info() - * function defined in the OProfile module. We decrement - * the module refcount in destroy_cached_info. - */ - try_module_get(THIS_MODULE); - spu_set_profile_private_kref(spu->ctx, &info->cache_ref, - destroy_cached_info); - spin_unlock_irqrestore(&cache_lock, flags); - goto out; - -err_alloc: - kfree(info); -out: - return retval; -} - -/* - * NOTE: The caller is responsible for locking the - * cache_lock prior to calling this function. - */ -static int release_cached_info(int spu_index) -{ - int index, end; - - if (spu_index == RELEASE_ALL) { - end = num_spu_nodes; - index = 0; - } else { - if (spu_index >= num_spu_nodes) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: " - "Invalid index %d into spu info cache\n", - __func__, __LINE__, spu_index); - goto out; - } - end = spu_index + 1; - index = spu_index; - } - for (; index < end; index++) { - if (spu_info[index]) { - kref_put(&spu_info[index]->cache_ref, - destroy_cached_info); - spu_info[index] = NULL; - } - } - -out: - return 0; -} - -/* The source code for fast_get_dcookie was "borrowed" - * from drivers/oprofile/buffer_sync.c. - */ - -/* Optimisation. We can manage without taking the dcookie sem - * because we cannot reach this code without at least one - * dcookie user still being registered (namely, the reader - * of the event buffer). - */ -static inline unsigned long fast_get_dcookie(const struct path *path) -{ - unsigned long cookie; - - if (path->dentry->d_flags & DCACHE_COOKIE) - return (unsigned long)path->dentry; - get_dcookie(path, &cookie); - return cookie; -} - -/* Look up the dcookie for the task's mm->exe_file, - * which corresponds loosely to "application name". Also, determine - * the offset for the SPU ELF object. If computed offset is - * non-zero, it implies an embedded SPU object; otherwise, it's a - * separate SPU binary, in which case we retrieve it's dcookie. - * For the embedded case, we must determine if SPU ELF is embedded - * in the executable application or another file (i.e., shared lib). - * If embedded in a shared lib, we must get the dcookie and return - * that to the caller. - */ -static unsigned long -get_exec_dcookie_and_offset(struct spu *spu, unsigned int *offsetp, - unsigned long *spu_bin_dcookie, - unsigned long spu_ref) -{ - unsigned long app_cookie = 0; - unsigned int my_offset = 0; - struct vm_area_struct *vma; - struct file *exe_file; - struct mm_struct *mm = spu->mm; - - if (!mm) - goto out; - - exe_file = get_mm_exe_file(mm); - if (exe_file) { - app_cookie = fast_get_dcookie(&exe_file->f_path); - pr_debug("got dcookie for %pD\n", exe_file); - fput(exe_file); - } - - mmap_read_lock(mm); - for (vma = mm->mmap; vma; vma = vma->vm_next) { - if (vma->vm_start > spu_ref || vma->vm_end <= spu_ref) - continue; - my_offset = spu_ref - vma->vm_start; - if (!vma->vm_file) - goto fail_no_image_cookie; - - pr_debug("Found spu ELF at %X(object-id:%lx) for file %pD\n", - my_offset, spu_ref, vma->vm_file); - *offsetp = my_offset; - break; - } - - *spu_bin_dcookie = fast_get_dcookie(&vma->vm_file->f_path); - pr_debug("got dcookie for %pD\n", vma->vm_file); - - mmap_read_unlock(mm); - -out: - return app_cookie; - -fail_no_image_cookie: - mmap_read_unlock(mm); - - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Cannot find dcookie for SPU binary\n", - __func__, __LINE__); - goto out; -} - - - -/* This function finds or creates cached context information for the - * passed SPU and records SPU context information into the OProfile - * event buffer. - */ -static int process_context_switch(struct spu *spu, unsigned long objectId) -{ - unsigned long flags; - int retval; - unsigned int offset = 0; - unsigned long spu_cookie = 0, app_dcookie; - - retval = prepare_cached_spu_info(spu, objectId); - if (retval) - goto out; - - /* Get dcookie first because a mutex_lock is taken in that - * code path, so interrupts must not be disabled. - */ - app_dcookie = get_exec_dcookie_and_offset(spu, &offset, &spu_cookie, objectId); - if (!app_dcookie || !spu_cookie) { - retval = -ENOENT; - goto out; - } - - /* Record context info in event buffer */ - spin_lock_irqsave(&buffer_lock, flags); - spu_buff_add(ESCAPE_CODE, spu->number); - spu_buff_add(SPU_CTX_SWITCH_CODE, spu->number); - spu_buff_add(spu->number, spu->number); - spu_buff_add(spu->pid, spu->number); - spu_buff_add(spu->tgid, spu->number); - spu_buff_add(app_dcookie, spu->number); - spu_buff_add(spu_cookie, spu->number); - spu_buff_add(offset, spu->number); - - /* Set flag to indicate SPU PC data can now be written out. If - * the SPU program counter data is seen before an SPU context - * record is seen, the postprocessing will fail. - */ - spu_buff[spu->number].ctx_sw_seen = 1; - - spin_unlock_irqrestore(&buffer_lock, flags); - smp_wmb(); /* insure spu event buffer updates are written */ - /* don't want entries intermingled... */ -out: - return retval; -} - -/* - * This function is invoked on either a bind_context or unbind_context. - * If called for an unbind_context, the val arg is 0; otherwise, - * it is the object-id value for the spu context. - * The data arg is of type 'struct spu *'. - */ -static int spu_active_notify(struct notifier_block *self, unsigned long val, - void *data) -{ - int retval; - unsigned long flags; - struct spu *the_spu = data; - - pr_debug("SPU event notification arrived\n"); - if (!val) { - spin_lock_irqsave(&cache_lock, flags); - retval = release_cached_info(the_spu->number); - spin_unlock_irqrestore(&cache_lock, flags); - } else { - retval = process_context_switch(the_spu, val); - } - return retval; -} - -static struct notifier_block spu_active = { - .notifier_call = spu_active_notify, -}; - -static int number_of_online_nodes(void) -{ - u32 cpu; u32 tmp; - int nodes = 0; - for_each_online_cpu(cpu) { - tmp = cbe_cpu_to_node(cpu) + 1; - if (tmp > nodes) - nodes++; - } - return nodes; -} - -static int oprofile_spu_buff_create(void) -{ - int spu; - - max_spu_buff = oprofile_get_cpu_buffer_size(); - - for (spu = 0; spu < num_spu_nodes; spu++) { - /* create circular buffers to store the data in. - * use locks to manage accessing the buffers - */ - spu_buff[spu].head = 0; - spu_buff[spu].tail = 0; - - /* - * Create a buffer for each SPU. Can't reliably - * create a single buffer for all spus due to not - * enough contiguous kernel memory. - */ - - spu_buff[spu].buff = kzalloc((max_spu_buff - * sizeof(unsigned long)), - GFP_KERNEL); - - if (!spu_buff[spu].buff) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: oprofile_spu_buff_create " - "failed to allocate spu buffer %d.\n", - __func__, __LINE__, spu); - - /* release the spu buffers that have been allocated */ - while (spu >= 0) { - kfree(spu_buff[spu].buff); - spu_buff[spu].buff = 0; - spu--; - } - return -ENOMEM; - } - } - return 0; -} - -/* The main purpose of this function is to synchronize - * OProfile with SPUFS by registering to be notified of - * SPU task switches. - * - * NOTE: When profiling SPUs, we must ensure that only - * spu_sync_start is invoked and not the generic sync_start - * in drivers/oprofile/oprof.c. A return value of - * SKIP_GENERIC_SYNC or SYNC_START_ERROR will - * accomplish this. - */ -int spu_sync_start(void) -{ - int spu; - int ret = SKIP_GENERIC_SYNC; - int register_ret; - unsigned long flags = 0; - - spu_prof_num_nodes = number_of_online_nodes(); - num_spu_nodes = spu_prof_num_nodes * 8; - INIT_DELAYED_WORK(&spu_work, wq_sync_spu_buff); - - /* create buffer for storing the SPU data to put in - * the kernel buffer. - */ - ret = oprofile_spu_buff_create(); - if (ret) - goto out; - - spin_lock_irqsave(&buffer_lock, flags); - for (spu = 0; spu < num_spu_nodes; spu++) { - spu_buff_add(ESCAPE_CODE, spu); - spu_buff_add(SPU_PROFILING_CODE, spu); - spu_buff_add(num_spu_nodes, spu); - } - spin_unlock_irqrestore(&buffer_lock, flags); - - for (spu = 0; spu < num_spu_nodes; spu++) { - spu_buff[spu].ctx_sw_seen = 0; - spu_buff[spu].last_guard_val = 0; - } - - /* Register for SPU events */ - register_ret = spu_switch_event_register(&spu_active); - if (register_ret) { - ret = SYNC_START_ERROR; - goto out; - } - - pr_debug("spu_sync_start -- running.\n"); -out: - return ret; -} - -/* Record SPU program counter samples to the oprofile event buffer. */ -void spu_sync_buffer(int spu_num, unsigned int *samples, - int num_samples) -{ - unsigned long long file_offset; - unsigned long flags; - int i; - struct vma_to_fileoffset_map *map; - struct spu *the_spu; - unsigned long long spu_num_ll = spu_num; - unsigned long long spu_num_shifted = spu_num_ll << 32; - struct cached_info *c_info; - - /* We need to obtain the cache_lock here because it's - * possible that after getting the cached_info, the SPU job - * corresponding to this cached_info may end, thus resulting - * in the destruction of the cached_info. - */ - spin_lock_irqsave(&cache_lock, flags); - c_info = get_cached_info(NULL, spu_num); - if (!c_info) { - /* This legitimately happens when the SPU task ends before all - * samples are recorded. - * No big deal -- so we just drop a few samples. - */ - pr_debug("SPU_PROF: No cached SPU context " - "for SPU #%d. Dropping samples.\n", spu_num); - goto out; - } - - map = c_info->map; - the_spu = c_info->the_spu; - spin_lock(&buffer_lock); - for (i = 0; i < num_samples; i++) { - unsigned int sample = *(samples+i); - int grd_val = 0; - file_offset = 0; - if (sample == 0) - continue; - file_offset = vma_map_lookup( map, sample, the_spu, &grd_val); - - /* If overlays are used by this SPU application, the guard - * value is non-zero, indicating which overlay section is in - * use. We need to discard samples taken during the time - * period which an overlay occurs (i.e., guard value changes). - */ - if (grd_val && grd_val != spu_buff[spu_num].last_guard_val) { - spu_buff[spu_num].last_guard_val = grd_val; - /* Drop the rest of the samples. */ - break; - } - - /* We must ensure that the SPU context switch has been written - * out before samples for the SPU. Otherwise, the SPU context - * information is not available and the postprocessing of the - * SPU PC will fail with no available anonymous map information. - */ - if (spu_buff[spu_num].ctx_sw_seen) - spu_buff_add((file_offset | spu_num_shifted), - spu_num); - } - spin_unlock(&buffer_lock); -out: - spin_unlock_irqrestore(&cache_lock, flags); -} - - -int spu_sync_stop(void) -{ - unsigned long flags = 0; - int ret; - int k; - - ret = spu_switch_event_unregister(&spu_active); - - if (ret) - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: spu_switch_event_unregister " \ - "returned %d\n", - __func__, __LINE__, ret); - - /* flush any remaining data in the per SPU buffers */ - sync_spu_buff(); - - spin_lock_irqsave(&cache_lock, flags); - ret = release_cached_info(RELEASE_ALL); - spin_unlock_irqrestore(&cache_lock, flags); - - /* remove scheduled work queue item rather then waiting - * for every queued entry to execute. Then flush pending - * system wide buffer to event buffer. - */ - cancel_delayed_work(&spu_work); - - for (k = 0; k < num_spu_nodes; k++) { - spu_buff[k].ctx_sw_seen = 0; - - /* - * spu_sys_buff will be null if there was a problem - * allocating the buffer. Only delete if it exists. - */ - kfree(spu_buff[k].buff); - spu_buff[k].buff = 0; - } - pr_debug("spu_sync_stop -- done.\n"); - return ret; -} - diff --git a/arch/powerpc/oprofile/cell/vma_map.c b/arch/powerpc/oprofile/cell/vma_map.c deleted file mode 100644 index 7c4b19cfde88..000000000000 --- a/arch/powerpc/oprofile/cell/vma_map.c +++ /dev/null @@ -1,279 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Author: Maynard Johnson <may...@us...> - */ - -/* The code in this source file is responsible for generating - * vma-to-fileOffset maps for both overlay and non-overlay SPU - * applications. - */ - -#include <linux/mm.h> -#include <linux/string.h> -#include <linux/uaccess.h> -#include <linux/elf.h> -#include <linux/slab.h> -#include "pr_util.h" - - -void vma_map_free(struct vma_to_fileoffset_map *map) -{ - while (map) { - struct vma_to_fileoffset_map *next = map->next; - kfree(map); - map = next; - } -} - -unsigned int -vma_map_lookup(struct vma_to_fileoffset_map *map, unsigned int vma, - const struct spu *aSpu, int *grd_val) -{ - /* - * Default the offset to the physical address + a flag value. - * Addresses of dynamically generated code can't be found in the vma - * map. For those addresses the flagged value will be sent on to - * the user space tools so they can be reported rather than just - * thrown away. - */ - u32 offset = 0x10000000 + vma; - u32 ovly_grd; - - for (; map; map = map->next) { - if (vma < map->vma || vma >= map->vma + map->size) - continue; - - if (map->guard_ptr) { - ovly_grd = *(u32 *)(aSpu->local_store + map->guard_ptr); - if (ovly_grd != map->guard_val) - continue; - *grd_val = ovly_grd; - } - offset = vma - map->vma + map->offset; - break; - } - - return offset; -} - -static struct vma_to_fileoffset_map * -vma_map_add(struct vma_to_fileoffset_map *map, unsigned int vma, - unsigned int size, unsigned int offset, unsigned int guard_ptr, - unsigned int guard_val) -{ - struct vma_to_fileoffset_map *new = kzalloc(sizeof(*new), GFP_KERNEL); - - if (!new) { - printk(KERN_ERR "SPU_PROF: %s, line %d: malloc failed\n", - __func__, __LINE__); - vma_map_free(map); - return NULL; - } - - new->next = map; - new->vma = vma; - new->size = size; - new->offset = offset; - new->guard_ptr = guard_ptr; - new->guard_val = guard_val; - - return new; -} - - -/* Parse SPE ELF header and generate a list of vma_maps. - * A pointer to the first vma_map in the generated list - * of vma_maps is returned. */ -struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu, - unsigned long __spu_elf_start) -{ - static const unsigned char expected[EI_PAD] = { - [EI_MAG0] = ELFMAG0, - [EI_MAG1] = ELFMAG1, - [EI_MAG2] = ELFMAG2, - [EI_MAG3] = ELFMAG3, - [EI_CLASS] = ELFCLASS32, - [EI_DATA] = ELFDATA2MSB, - [EI_VERSION] = EV_CURRENT, - [EI_OSABI] = ELFOSABI_NONE - }; - - int grd_val; - struct vma_to_fileoffset_map *map = NULL; - void __user *spu_elf_start = (void __user *)__spu_elf_start; - struct spu_overlay_info ovly; - unsigned int overlay_tbl_offset = -1; - Elf32_Phdr __user *phdr_start; - Elf32_Shdr __user *shdr_start; - Elf32_Ehdr ehdr; - Elf32_Phdr phdr; - Elf32_Shdr shdr, shdr_str; - Elf32_Sym sym; - int i, j; - char name[32]; - - unsigned int ovly_table_sym = 0; - unsigned int ovly_buf_table_sym = 0; - unsigned int ovly_table_end_sym = 0; - unsigned int ovly_buf_table_end_sym = 0; - struct spu_overlay_info __user *ovly_table; - unsigned int n_ovlys; - - /* Get and validate ELF header. */ - - if (copy_from_user(&ehdr, spu_elf_start, sizeof (ehdr))) - goto fail; - - if (memcmp(ehdr.e_ident, expected, EI_PAD) != 0) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Unexpected e_ident parsing SPU ELF\n", - __func__, __LINE__); - goto fail; - } - if (ehdr.e_machine != EM_SPU) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Unexpected e_machine parsing SPU ELF\n", - __func__, __LINE__); - goto fail; - } - if (ehdr.e_type != ET_EXEC) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Unexpected e_type parsing SPU ELF\n", - __func__, __LINE__); - goto fail; - } - phdr_start = spu_elf_start + ehdr.e_phoff; - shdr_start = spu_elf_start + ehdr.e_shoff; - - /* Traverse program headers. */ - for (i = 0; i < ehdr.e_phnum; i++) { - if (copy_from_user(&phdr, phdr_start + i, sizeof(phdr))) - goto fail; - - if (phdr.p_type != PT_LOAD) - continue; - if (phdr.p_flags & (1 << 27)) - continue; - - map = vma_map_add(map, phdr.p_vaddr, phdr.p_memsz, - phdr.p_offset, 0, 0); - if (!map) - goto fail; - } - - pr_debug("SPU_PROF: Created non-overlay maps\n"); - /* Traverse section table and search for overlay-related symbols. */ - for (i = 0; i < ehdr.e_shnum; i++) { - if (copy_from_user(&shdr, shdr_start + i, sizeof(shdr))) - goto fail; - - if (shdr.sh_type != SHT_SYMTAB) - continue; - if (shdr.sh_entsize != sizeof (sym)) - continue; - - if (copy_from_user(&shdr_str, - shdr_start + shdr.sh_link, - sizeof(shdr))) - goto fail; - - if (shdr_str.sh_type != SHT_STRTAB) - goto fail; - - for (j = 0; j < shdr.sh_size / sizeof (sym); j++) { - if (copy_from_user(&sym, spu_elf_start + - shdr.sh_offset + - j * sizeof (sym), - sizeof (sym))) - goto fail; - - if (copy_from_user(name, - spu_elf_start + shdr_str.sh_offset + - sym.st_name, - 20)) - goto fail; - - if (memcmp(name, "_ovly_table", 12) == 0) - ovly_table_sym = sym.st_value; - if (memcmp(name, "_ovly_buf_table", 16) == 0) - ovly_buf_table_sym = sym.st_value; - if (memcmp(name, "_ovly_table_end", 16) == 0) - ovly_table_end_sym = sym.st_value; - if (memcmp(name, "_ovly_buf_table_end", 20) == 0) - ovly_buf_table_end_sym = sym.st_value; - } - } - - /* If we don't have overlays, we're done. */ - if (ovly_table_sym == 0 || ovly_buf_table_sym == 0 - || ovly_table_end_sym == 0 || ovly_buf_table_end_sym == 0) { - pr_debug("SPU_PROF: No overlay table found\n"); - goto out; - } else { - pr_debug("SPU_PROF: Overlay table found\n"); - } - - /* The _ovly_table symbol represents a table with one entry - * per overlay section. The _ovly_buf_table symbol represents - * a table with one entry per overlay region. - * The struct spu_overlay_info gives the structure of the _ovly_table - * entries. The structure of _ovly_table_buf is simply one - * u32 word per entry. - */ - overlay_tbl_offset = vma_map_lookup(map, ovly_table_sym, - aSpu, &grd_val); - if (overlay_tbl_offset > 0x10000000) { - printk(KERN_ERR "SPU_PROF: " - "%s, line %d: Error finding SPU overlay table\n", - __func__, __LINE__); - goto fail; - } - ovly_table = spu_elf_start + overlay_tbl_offset; - - n_ovlys = (ovly_table_end_sym - - ovly_table_sym) / sizeof (ovly); - - /* Traverse overlay table. */ - for (i = 0; i < n_ovlys; i++) { - if (copy_from_user(&ovly, ovly_table + i, sizeof (ovly))) - goto fail; - - /* The ovly.vma/size/offset arguments are analogous to the same - * arguments used above for non-overlay maps. The final two - * args are referred to as the guard pointer and the guard - * value. - * The guard pointer is an entry in the _ovly_buf_table, - * computed using ovly.buf as the index into the table. Since - * ovly.buf values begin at '1' to reference the first (or 0th) - * entry in the _ovly_buf_table, the computation subtracts 1 - * from ovly.buf. - * The guard value is stored in the _ovly_buf_table entry and - * is an index (starting at 1) back to the _ovly_table entry - * that is pointing at this _ovly_buf_table entry. So, for - * example, for an overlay scenario with one overlay segment - * and two overlay sections: - * - Section 1 points to the first entry of the - * _ovly_buf_table, which contains a guard value - * of '1', referencing the first (index=0) entry of - * _ovly_table. - * - Section 2 points to the second entry of the - * _ovly_buf_table, which contains a guard value - * of '2', referencing the second (index=1) entry of - * _ovly_table. - */ - map = vma_map_add(map, ovly.vma, ovly.size, ovly.offset, - ovly_buf_table_sym + (ovly.buf-1) * 4, i+1); - if (!map) - goto fail; - } - goto out; - - fail: - map = NULL; - out: - return map; -} diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c deleted file mode 100644 index 0fb528c2b3a1..000000000000 --- a/arch/powerpc/oprofile/common.c +++ /dev/null @@ -1,243 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * PPC 64 oprofile support: - * Copyright (C) 2004 Anton Blanchard <an...@au...>, IBM - * PPC 32 oprofile support: (based on PPC 64 support) - * Copyright (C) Freescale Semiconductor, Inc 2004 - * Author: Andy Fleming - * - * Based on alpha version. - */ - -#include <linux/oprofile.h> -#include <linux/init.h> -#include <linux/smp.h> -#include <linux/errno.h> -#include <asm/ptrace.h> -#include <asm/pmc.h> -#include <asm/cputable.h> -#include <asm/oprofile_impl.h> -#include <asm/firmware.h> - -static struct op_powerpc_model *model; - -static struct op_counter_config ctr[OP_MAX_COUNTER]; -static struct op_system_config sys; - -static int op_per_cpu_rc; - -static void op_handle_interrupt(struct pt_regs *regs) -{ - model->handle_interrupt(regs, ctr); -} - -static void op_powerpc_cpu_setup(void *dummy) -{ - int ret; - - ret = model->cpu_setup(ctr); - - if (ret != 0) - op_per_cpu_rc = ret; -} - -static int op_powerpc_setup(void) -{ - int err; - - op_per_cpu_rc = 0; - - /* Grab the hardware */ - err = reserve_pmc_hardware(op_handle_interrupt); - if (err) - return err; - - /* Pre-compute the values to stuff in the hardware registers. */ - op_per_cpu_rc = model->reg_setup(ctr, &sys, model->num_counters); - - if (op_per_cpu_rc) - goto out; - - /* Configure the registers on all cpus. If an error occurs on one - * of the cpus, op_per_cpu_rc will be set to the error */ - on_each_cpu(op_powerpc_cpu_setup, NULL, 1); - -out: if (op_per_cpu_rc) { - /* error on setup release the performance counter hardware */ - release_pmc_hardware(); - } - - return op_per_cpu_rc; -} - -static void op_powerpc_shutdown(void) -{ - release_pmc_hardware(); -} - -static void op_powerpc_cpu_start(void *dummy) -{ - /* If any of the cpus have return an error, set the - * global flag to the error so it can be returned - * to the generic OProfile caller. - */ - int ret; - - ret = model->start(ctr); - if (ret != 0) - op_per_cpu_rc = ret; -} - -static int op_powerpc_start(void) -{ - op_per_cpu_rc = 0; - - if (model->global_start) - return model->global_start(ctr); - if (model->start) { - on_each_cpu(op_powerpc_cpu_start, NULL, 1); - return op_per_cpu_rc; - } - return -EIO; /* No start function is defined for this - power architecture */ -} - -static inline void op_powerpc_cpu_stop(void *dummy) -{ - model->stop(); -} - -static void op_powerpc_stop(void) -{ - if (model->stop) - on_each_cpu(op_powerpc_cpu_stop, NULL, 1); - if (model->global_stop) - model->global_stop(); -} - -static int op_powerpc_create_files(struct dentry *root) -{ - int i; - -#ifdef CONFIG_PPC64 - /* - * There is one mmcr0, mmcr1 and mmcra for setting the events for - * all of the counters. - */ - oprofilefs_create_ulong(root, "mmcr0", &sys.mmcr0); - oprofilefs_create_ulong(root, "mmcr1", &sys.mmcr1); - oprofilefs_create_ulong(root, "mmcra", &sys.mmcra); -#ifdef CONFIG_OPROFILE_CELL - /* create a file the user tool can check to see what level of profiling - * support exits with this kernel. Initialize bit mask to indicate - * what support the kernel has: - * bit 0 - Supports SPU event profiling in addition to PPU - * event and cycles; and SPU cycle profiling - * bits 1-31 - Currently unused. - * - * If the file does not exist, then the kernel only supports SPU - * cycle profiling, PPU event and cycle profiling. - */ - oprofilefs_create_ulong(root, "cell_support", &sys.cell_support); - sys.cell_support = 0x1; /* Note, the user OProfile tool must check - * that this bit is set before attempting to - * user SPU event profiling. Older kernels - * will not have this file, hence the user - * tool is not allowed to do SPU event - * profiling on older kernels. Older kernels - * will accept SPU events but collected data - * is garbage. - */ -#endif -#endif - - for (i = 0; i < model->num_counters; ++i) { - struct dentry *dir; - char buf[4]; - - snprintf(buf, sizeof buf, "%d", i); - dir = oprofilefs_mkdir(root, buf); - - oprofilefs_create_ulong(dir, "enabled", &ctr[i].enabled); - oprofilefs_create_ulong(dir, "event", &ctr[i].event); - oprofilefs_create_ulong(dir, "count", &ctr[i].count); - - /* - * Classic PowerPC doesn't support per-counter - * control like this, but the options are - * expected, so they remain. For Freescale - * Book-E style performance monitors, we do - * support them. - */ - oprofilefs_create_ulong(dir, "kernel", &ctr[i].kernel); - oprofilefs_create_ulong(dir, "user", &ctr[i].user); - - oprofilefs_create_ulong(dir, "unit_mask", &ctr[i].unit_mask); - } - - oprofilefs_create_ulong(root, "enable_kernel", &sys.enable_kernel); - oprofilefs_create_ulong(root, "enable_user", &sys.enable_user); - - /* Default to tracing both kernel and user */ - sys.enable_kernel = 1; - sys.enable_user = 1; - - return 0; -} - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - if (!cur_cpu_spec->oprofile_cpu_type) - return -ENODEV; - - switch (cur_cpu_spec->oprofile_type) { -#ifdef CONFIG_PPC_BOOK3S_64 -#ifdef CONFIG_OPROFILE_CELL - case PPC_OPROFILE_CELL: - if (firmware_has_feature(FW_FEATURE_LPAR)) - return -ENODEV; - model = &op_model_cell; - ops->sync_start = model->sync_start; - ops->sync_stop = model->sync_stop; - break; -#endif - case PPC_OPROFILE_POWER4: - model = &op_model_power4; - break; - case PPC_OPROFILE_PA6T: - model = &op_model_pa6t; - break; -#endif -#ifdef CONFIG_PPC_BOOK3S_32 - case PPC_OPROFILE_G4: - model = &op_model_7450; - break; -#endif -#if defined(CONFIG_FSL_EMB_PERFMON) - case PPC_OPROFILE_FSL_EMB: - model = &op_model_fsl_emb; - break; -#endif - default: - return -ENODEV; - } - - model->num_counters = cur_cpu_spec->num_pmcs; - - ops->cpu_type = cur_cpu_spec->oprofile_cpu_type; - ops->create_files = op_powerpc_create_files; - ops->setup = op_powerpc_setup; - ops->shutdown = op_powerpc_shutdown; - ops->start = op_powerpc_start; - ops->stop = op_powerpc_stop; - ops->backtrace = op_powerpc_backtrace; - - printk(KERN_DEBUG "oprofile: using %s performance monitoring.\n", - ops->cpu_type); - - return 0; -} - -void oprofile_arch_exit(void) -{ -} diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c deleted file mode 100644 index 5ebc25188a72..000000000000 --- a/arch/powerpc/oprofile/op_model_7450.c +++ /dev/null @@ -1,207 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * arch/powerpc/oprofile/op_model_7450.c - * - * Freescale 745x/744x oprofile support, based on fsl_booke support - * Copyright (C) 2004 Anton Blanchard <an...@au...>, IBM - * - * Copyright (c) 2004 Freescale Semiconductor, Inc - * - * Author: Andy Fleming - * Maintainer: Kumar Gala <ga...@ke...> - */ - -#include <linux/oprofile.h> -#include <linux/smp.h> -#include <asm/ptrace.h> -#include <asm/processor.h> -#include <asm/cputable.h> -#include <asm/page.h> -#include <asm/pmc.h> -#include <asm/oprofile_impl.h> - -static unsigned long reset_value[OP_MAX_COUNTER]; - -static int oprofile_running; -static u32 mmcr0_val, mmcr1_val, mmcr2_val, num_pmcs; - -#define MMCR0_PMC1_SHIFT 6 -#define MMCR0_PMC2_SHIFT 0 -#define MMCR1_PMC3_SHIFT 27 -#define MMCR1_PMC4_SHIFT 22 -#define MMCR1_PMC5_SHIFT 17 -#define MMCR1_PMC6_SHIFT 11 - -#define mmcr0_event1(event) \ - ((event << MMCR0_PMC1_SHIFT) & MMCR0_PMC1SEL) -#define mmcr0_event2(event) \ - ((event << MMCR0_PMC2_SHIFT) & MMCR0_PMC2SEL) - -#define mmcr1_event3(event) \ - ((event << MMCR1_PMC3_SHIFT) & MMCR1_PMC3SEL) -#define mmcr1_event4(event) \ - ((event << MMCR1_PMC4_SHIFT) & MMCR1_PMC4SEL) -#define mmcr1_event5(event) \ - ((event << MMCR1_PMC5_SHIFT) & MMCR1_PMC5SEL) -#define mmcr1_event6(event) \ - ((event << MMCR1_PMC6_SHIFT) & MMCR1_PMC6SEL) - -#define MMCR0_INIT (MMCR0_FC | MMCR0_FCS | MMCR0_FCP | MMCR0_FCM1 | MMCR0_FCM0) - -/* Unfreezes the counters on this CPU, enables the interrupt, - * enables the counters to trigger the interrupt, and sets the - * counters to only count when the mark bit is not set. - */ -static void pmc_start_ctrs(void) -{ - u32 mmcr0 = mfspr(SPRN_MMCR0); - - mmcr0 &= ~(MMCR0_FC | MMCR0_FCM0); - mmcr0 |= (MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE); - - mtspr(SPRN_MMCR0, mmcr0); -} - -/* Disables the counters on this CPU, and freezes them */ -static void pmc_stop_ctrs(void) -{ - u32 mmcr0 = mfspr(SPRN_MMCR0); - - mmcr0 |= MMCR0_FC; - mmcr0 &= ~(MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE); - - mtspr(SPRN_MMCR0, mmcr0); -} - -/* Configures the counters on this CPU based on the global - * settings */ -static int fsl7450_cpu_setup(struct op_counter_config *ctr) -{ - /* freeze all counters */ - pmc_stop_ctrs(); - - mtspr(SPRN_MMCR0, mmcr0_val); - mtspr(SPRN_MMCR1, mmcr1_val); - if (num_pmcs > 4) - mtspr(SPRN_MMCR2, mmcr2_val); - - return 0; -} - -/* Configures the global settings for the countes on all CPUs. */ -static int fsl7450_reg_setup(struct op_counter_config *ctr, - struct op_system_config *sys, - int num_ctrs) -{ - int i; - - num_pmcs = num_ctrs; - /* Our counters count up, and "count" refers to - * how much before the next interrupt, and we interrupt - * on overflow. So we calculate the starting value - * which will give us "count" until overflow. - * Then we set the events on the enabled counters */ - for (i = 0; i < num_ctrs; ++i) - reset_value[i] = 0x80000000UL - ctr[i].count; - - /* Set events for Counters 1 & 2 */ - mmcr0_val = MMCR0_INIT | mmcr0_event1(ctr[0].event) - | mmcr0_event2(ctr[1].event); - - /* Setup user/kernel bits */ - if (sys->enable_kernel) - mmcr0_val &= ~(MMCR0_FCS); - - if (sys->enable_user) - mmcr0_val &= ~(MMCR0_FCP); - - /* Set events for Counters 3-6 */ - mmcr1_val = mmcr1_event3(ctr[2].event) - | mmcr1_event4(ctr[3].event); - if (num_ctrs > 4) - mmcr1_val |= mmcr1_event5(ctr[4].event) - | mmcr1_event6(ctr[5].event); - - mmcr2_val = 0; - - return 0; -} - -/* Sets the counters on this CPU to the chosen values, and starts them */ -static int fsl7450_start(struct op_counter_config *ctr) -{ - int i; - - mtmsr(mfmsr() | MSR_PMM); - - for (i = 0; i < num_pmcs; ++i) { - if (ctr[i].enabled) - classic_ctr_write(i, reset_value[i]); - else - classic_ctr_write(i, 0); - } - - /* Clear the freeze bit, and enable the interrupt. - * The counters won't actually start until the rfi clears - * the PMM bit */ - pmc_start_ctrs(); - - oprofile_running = 1; - - return 0; -} - -/* Stop the counters on this CPU */ -static void fsl7450_stop(void) -{ - /* freeze counters */ - pmc_stop_ctrs(); - - oprofile_running = 0; - - mb(); -} - - -/* Handle the interrupt on this CPU, and log a sample for each - * event that triggered the interrupt */ -static void fsl7450_handle_interrupt(struct pt_regs *regs, - struct op_counter_config *ctr) -{ - unsigned long pc; - int is_kernel; - int val; - int i; - - /* set the PMM bit (see comment below) */ - mtmsr(mfmsr() | MSR_PMM); - - pc = mfspr(SPRN_SIAR); - is_kernel = is_kernel_addr(pc); - - for (i = 0; i < num_pmcs; ++i) { - val = classic_ctr_read(i); - if (val < 0) { - if (oprofile_running && ctr[i].enabled) { - oprofile_add_ext_sample(pc, regs, i, is_kernel); - classic_ctr_write(i, reset_value[i]); - } else { - classic_ctr_write(i, 0); - } - } - } - - /* The freeze bit was set by the interrupt. */ - /* Clear the freeze bit, and reenable the interrupt. - * The counters won't actually start until the rfi clears - * the PM/M bit */ - pmc_start_ctrs(); -} - -struct op_powerpc_model op_model_7450= { - .reg_setup = fsl7450_reg_setup, - .cpu_setup = fsl7450_cpu_setup, - .start = fsl7450_start, - .stop = fsl7450_stop, - .handle_interrupt = fsl7450_handle_interrupt, -}; diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c deleted file mode 100644 index 7eb73070b7be..000000000000 --- a/arch/powerpc/oprofile/op_model_cell.c +++ /dev/null @@ -1,1709 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Cell Broadband Engine OProfile Support - * - * (C) Copyright IBM Corporation 2006 - * - * Author: David Erb (dj...@us...) - * Modifications: - * Carl Love <ca...@us...> - * Maynard Johnson <may...@us...> - */ - -#include <linux/cpufreq.h> -#include <linux/delay.h> -#include <linux/jiffies.h> -#include <linux/kthread.h> -#include <linux/oprofile.h> -#include <linux/percpu.h> -#include <linux/smp.h> -#include <linux/spinlock.h> -#include <linux/timer.h> -#include <asm/cell-pmu.h> -#include <asm/cputable.h> -#include <asm/firmware.h> -#include <asm/io.h> -#include <asm/oprofile_impl.h> -#include <asm/processor.h> -#include <asm/prom.h> -#include <asm/ptrace.h> -#include <asm/reg.h> -#include <asm/rtas.h> -#include <asm/cell-regs.h> - -#include "../platforms/cell/interrupt.h" -#include "cell/pr_util.h" - -#define PPU_PROFILING 0 -#define SPU_PROFILING_CYCLES 1 -#define SPU_PROFILING_EVENTS 2 - -#define SPU_EVENT_NUM_START 4100 -#define SPU_EVENT_NUM_STOP 4399 -#define SPU_PROFILE_EVENT_ADDR 4363 /* spu, address trace, decimal */ -#define SPU_PROFILE_EVENT_ADDR_MASK_A 0x146 /* sub unit set to zero */ -#define SPU_PROFILE_EVENT_ADDR_MASK_B 0x186 /* sub unit set to zero */ - -#define NUM_SPUS_PER_NODE 8 -#define SPU_CYCLES_EVENT_NUM 2 /* event number for SPU_CYCLES */ - -#define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */ -#define PPU_CYCLES_GRP_NUM 1 /* special group number for identifying - * PPU_CYCLES event - */ -#define CBE_COUNT_ALL_CYCLES 0x42800000 /* PPU cycle event specifier */ - -#define NUM_THREADS 2 /* number of physical threads in - * physical processor - */ -#define NUM_DEBUG_BUS_WORDS 4 -#define NUM_INPUT_BUS_WORDS 2 - -#define MAX_SPU_COUNT 0xFFFFFF /* maximum 24 bit LFSR value */ - -/* Minimum HW interval timer setting to send value to trace buffer is 10 cycle. - * To configure counter to send value every N cycles set counter to - * 2^32 - 1 - N. - */ -#define NUM_INTERVAL_CYC 0xFFFFFFFF - 10 - -/* - * spu_cycle_reset is the number of cycles between samples. - * This variable is used for SPU profiling and should ONLY be set - * at the beginning of cell_reg_setup; otherwise, it's read-only. - */ -static unsigned int spu_cycle_reset; -static unsigned int profiling_mode; -static int spu_evnt_phys_spu_indx; - -struct pmc_cntrl_data { - unsigned long vcntr; - unsigned long evnts; - unsigned long masks; - unsigned long enabled; -}; - -/* - * ibm,cbe-perftools rtas parameters - */ -struct pm_signal { - u16 cpu; /* Processor to modify */ - u16 sub_unit; /* hw subunit this applies to (if applicable)*/ - short int signal_group; /* Signal Group to Enable/Disable */ - u8 bus_word; /* Enable/Disable on this Trace/Trigger/Event - * Bus Word(s) (bitmask) - */ - u8 bit; /* Trigger/Event bit (if applicable) */ -}; - -/* - * rtas call arguments - */ -enum { - SUBFUNC_RESET = 1, - SUBFUNC_ACTIVATE = 2, - SUBFUNC_DEACTIVATE = 3, - - PASSTHRU_IGNORE = 0, - PASSTHRU_ENABLE = 1, - PASSTHRU_DISABLE = 2, -}; - -struct pm_cntrl { - u16 enable; - u16 stop_at_max; - u16 trace_mode; - u16 freeze; - u16 count_mode; - u16 spu_addr_trace; - u8 trace_buf_ovflw; -}; - -static struct { - u32 group_control; - u32 debug_bus_control; - struct pm_cntrl pm_cntrl; - u32 pm07_cntrl[NR_PHYS_CTRS]; -} pm_regs; - -#define GET_SUB_UNIT(x) ((x & 0x0000f000) >> 12) -#define GET_BUS_WORD(x) ((x & 0x000000f0) >> 4) -#define GET_BUS_TYPE(x) ((x & 0x00000300) >> 8) -#define GET_POLARITY(x) ((x & 0x00000002) >> 1) -#define GET_COUNT_CYCLES(x) (x & 0x00000001) -#define GET_INPUT_CONTROL(x) ((x & 0x00000004) >> 2) - -static DEFINE_PER_CPU(unsigned long[NR_PHYS_CTRS], pmc_values); -static unsigned long spu_pm_cnt[MAX_NUMNODES * NUM_SPUS_PER_NODE]; -static struct pmc_cntrl_data pmc_cntrl[NUM_THREADS][NR_PHYS_CTRS]; - -/* - * The CELL profiling code makes rtas calls to setup the debug bus to - * route the performance signals. Additionally, SPU profiling requires - * a second rtas call to setup the hardware to capture the SPU PCs. - * The EIO error value is returned if the token lookups or the rtas - * call fail. The EIO error number is the best choice of the existing - * error numbers. The probability of rtas related error is very low. But - * by returning EIO and printing additional information to dmsg the user - * will know that OProfile did not start and dmesg will tell them why. - * OProfile does not support returning errors on Stop. Not a huge issue - * since failure to reset the debug bus or stop the SPU PC collection is - * not a fatel issue. Chances are if the Stop failed, Start doesn't work - * either. - */ - -/* - * Interpetation of hdw_thread: - * 0 - even virtual cpus 0, 2, 4,... - * 1 - odd virtual cpus 1, 3, 5, ... - * - * FIXME: this is strictly wrong, we need to clean this up in a number - * of places. It works for now. -arnd - */ -static u32 hdw_thread; - -stat... [truncated message content] |
From: Viresh K. <vir...@li...> - 2021-01-14 12:02:02
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/mips/Kconfig | 3 +- arch/mips/Makefile | 1 - arch/mips/configs/fuloong2e_defconfig | 1 - arch/mips/configs/ip32_defconfig | 1 - arch/mips/configs/lemote2f_defconfig | 1 - arch/mips/configs/mtx1_defconfig | 1 - arch/mips/configs/rs90_defconfig | 1 - .../include/asm/mach-loongson2ef/loongson.h | 9 - arch/mips/loongson2ef/fuloong-2e/irq.c | 2 +- arch/mips/loongson2ef/lemote-2f/irq.c | 1 - arch/mips/oprofile/Makefile | 18 - arch/mips/oprofile/backtrace.c | 177 ------- arch/mips/oprofile/common.c | 147 ------ arch/mips/oprofile/op_impl.h | 41 -- arch/mips/oprofile/op_model_loongson2.c | 161 ------ arch/mips/oprofile/op_model_loongson3.c | 213 -------- arch/mips/oprofile/op_model_mipsxx.c | 479 ------------------ 17 files changed, 2 insertions(+), 1255 deletions(-) delete mode 100644 arch/mips/oprofile/Makefile delete mode 100644 arch/mips/oprofile/backtrace.c delete mode 100644 arch/mips/oprofile/common.c delete mode 100644 arch/mips/oprofile/op_impl.h delete mode 100644 arch/mips/oprofile/op_model_loongson2.c delete mode 100644 arch/mips/oprofile/op_model_loongson3.c delete mode 100644 arch/mips/oprofile/op_model_mipsxx.c diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0a17bedf4f0d..54df2fd9988a 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -74,7 +74,6 @@ config MIPS select HAVE_LD_DEAD_CODE_DATA_ELIMINATION select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI - select HAVE_OPROFILE select HAVE_PERF_EVENTS select HAVE_REGS_AND_STACK_ACCESS_API select HAVE_RSEQ @@ -2844,7 +2843,7 @@ config NODES_SHIFT config HW_PERF_EVENTS bool "Enable hardware performance counter support for perf events" - depends on PERF_EVENTS && !OPROFILE && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON64) + depends on PERF_EVENTS && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON64) default y help Enable hardware performance counter support for perf events. If diff --git a/arch/mips/Makefile b/arch/mips/Makefile index cd4343edeb11..f62a6d951d3c 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile @@ -316,7 +316,6 @@ libs-$(CONFIG_MIPS_FP_SUPPORT) += arch/mips/math-emu/ core-y += arch/mips/ drivers-y += arch/mips/crypto/ -drivers-$(CONFIG_OPROFILE) += arch/mips/oprofile/ # suspend and hibernation support drivers-$(CONFIG_PM) += arch/mips/power/ diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig index 023b4e644b1c..5c24ac7fdf56 100644 --- a/arch/mips/configs/fuloong2e_defconfig +++ b/arch/mips/configs/fuloong2e_defconfig @@ -22,7 +22,6 @@ CONFIG_MIPS32_N32=y # CONFIG_SUSPEND is not set CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="/dev/sda3" -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/mips/configs/ip32_defconfig b/arch/mips/configs/ip32_defconfig index 7b1fab518317..1ae48f7d9ddd 100644 --- a/arch/mips/configs/ip32_defconfig +++ b/arch/mips/configs/ip32_defconfig @@ -14,7 +14,6 @@ CONFIG_SGI_IP32=y CONFIG_PCI=y CONFIG_MIPS32_O32=y CONFIG_MIPS32_N32=y -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y diff --git a/arch/mips/configs/lemote2f_defconfig b/arch/mips/configs/lemote2f_defconfig index 688c91918db2..aaf9d5e0aa2c 100644 --- a/arch/mips/configs/lemote2f_defconfig +++ b/arch/mips/configs/lemote2f_defconfig @@ -21,7 +21,6 @@ CONFIG_MIPS32_O32=y CONFIG_MIPS32_N32=y CONFIG_HIBERNATION=y CONFIG_PM_STD_PARTITION="/dev/hda3" -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y diff --git a/arch/mips/configs/mtx1_defconfig b/arch/mips/configs/mtx1_defconfig index bbe0f39f8088..205d3b34528c 100644 --- a/arch/mips/configs/mtx1_defconfig +++ b/arch/mips/configs/mtx1_defconfig @@ -17,7 +17,6 @@ CONFIG_PCCARD=m CONFIG_YENTA=m CONFIG_PD6729=m CONFIG_I82092=m -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODVERSIONS=y diff --git a/arch/mips/configs/rs90_defconfig b/arch/mips/configs/rs90_defconfig index 4f540bb94628..7ce3b814fdc8 100644 --- a/arch/mips/configs/rs90_defconfig +++ b/arch/mips/configs/rs90_defconfig @@ -30,7 +30,6 @@ CONFIG_PM=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y CONFIG_CPUFREQ_DT=y -CONFIG_OPROFILE=y CONFIG_JUMP_LABEL=y # CONFIG_STACKPROTECTOR is not set # CONFIG_BLK_DEV_BSG is not set diff --git a/arch/mips/include/asm/mach-loongson2ef/loongson.h b/arch/mips/include/asm/mach-loongson2ef/loongson.h index 57e571128489..ca039b8dcde3 100644 --- a/arch/mips/include/asm/mach-loongson2ef/loongson.h +++ b/arch/mips/include/asm/mach-loongson2ef/loongson.h @@ -56,15 +56,6 @@ extern int mach_i8259_irq(void); (*(volatile u32 *)((char *)CKSEG1ADDR(LOONGSON_REG_BASE) + (x))) #define LOONGSON_IRQ_BASE 32 -#define LOONGSON2_PERFCNT_IRQ (MIPS_CPU_IRQ_BASE + 6) /* cpu perf counter */ - -#include <linux/interrupt.h> -static inline void do_perfcnt_IRQ(void) -{ -#if IS_ENABLED(CONFIG_OPROFILE) - do_IRQ(LOONGSON2_PERFCNT_IRQ); -#endif -} #define LOONGSON_FLASH_BASE 0x1c000000 #define LOONGSON_FLASH_SIZE 0x02000000 /* 32M */ diff --git a/arch/mips/loongson2ef/fuloong-2e/irq.c b/arch/mips/loongson2ef/fuloong-2e/irq.c index 305aa2eb74ad..b1c9d4ee0335 100644 --- a/arch/mips/loongson2ef/fuloong-2e/irq.c +++ b/arch/mips/loongson2ef/fuloong-2e/irq.c @@ -26,7 +26,7 @@ asmlinkage void mach_irq_dispatch(unsigned int pending) if (pending & CAUSEF_IP7) do_IRQ(MIPS_CPU_IRQ_BASE + 7); else if (pending & CAUSEF_IP6) /* perf counter loverflow */ - do_perfcnt_IRQ(); + return; else if (pending & CAUSEF_IP5) i8259_irqdispatch(); else if (pending & CAUSEF_IP2) diff --git a/arch/mips/loongson2ef/lemote-2f/irq.c b/arch/mips/loongson2ef/lemote-2f/irq.c index 6f00579971a3..f5a731a2a35f 100644 --- a/arch/mips/loongson2ef/lemote-2f/irq.c +++ b/arch/mips/loongson2ef/lemote-2f/irq.c @@ -75,7 +75,6 @@ void mach_irq_dispatch(unsigned int pending) if (pending & CAUSEF_IP7) do_IRQ(LOONGSON_TIMER_IRQ); else if (pending & CAUSEF_IP6) { /* North Bridge, Perf counter */ - do_perfcnt_IRQ(); bonito_irqdispatch(); } else if (pending & CAUSEF_IP3) /* CPU UART */ do_IRQ(LOONGSON_UART_IRQ); diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile deleted file mode 100644 index e10f216d0422..000000000000 --- a/arch/mips/oprofile/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) common.o backtrace.o - -oprofile-$(CONFIG_CPU_MIPS32) += op_model_mipsxx.o -oprofile-$(CONFIG_CPU_MIPS64) += op_model_mipsxx.o -oprofile-$(CONFIG_CPU_R10000) += op_model_mipsxx.o -oprofile-$(CONFIG_CPU_SB1) += op_model_mipsxx.o -oprofile-$(CONFIG_CPU_XLR) += op_model_mipsxx.o -oprofile-$(CONFIG_CPU_LOONGSON2EF) += op_model_loongson2.o -oprofile-$(CONFIG_CPU_LOONGSON64) += op_model_loongson3.o diff --git a/arch/mips/oprofile/backtrace.c b/arch/mips/oprofile/backtrace.c deleted file mode 100644 index 07d98ba7f49e..000000000000 --- a/arch/mips/oprofile/backtrace.c +++ /dev/null @@ -1,177 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include <linux/oprofile.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/uaccess.h> -#include <asm/ptrace.h> -#include <asm/stacktrace.h> -#include <linux/stacktrace.h> -#include <linux/kernel.h> -#include <asm/sections.h> -#include <asm/inst.h> - -struct stackframe { - unsigned long sp; - unsigned long pc; - unsigned long ra; -}; - -static inline int get_mem(unsigned long addr, unsigned long *result) -{ - unsigned long *address = (unsigned long *) addr; - if (!access_ok(address, sizeof(unsigned long))) - return -1; - if (__copy_from_user_inatomic(result, address, sizeof(unsigned long))) - return -3; - return 0; -} - -/* - * These two instruction helpers were taken from process.c - */ -static inline int is_ra_save_ins(union mips_instruction *ip) -{ - /* sw / sd $ra, offset($sp) */ - return (ip->i_format.opcode == sw_op || ip->i_format.opcode == sd_op) - && ip->i_format.rs == 29 && ip->i_format.rt == 31; -} - -static inline int is_sp_move_ins(union mips_instruction *ip) -{ - /* addiu/daddiu sp,sp,-imm */ - if (ip->i_format.rs != 29 || ip->i_format.rt != 29) - return 0; - if (ip->i_format.opcode == addiu_op || ip->i_format.opcode == daddiu_op) - return 1; - return 0; -} - -/* - * Looks for specific instructions that mark the end of a function. - * This usually means we ran into the code area of the previous function. - */ -static inline int is_end_of_function_marker(union mips_instruction *ip) -{ - /* jr ra */ - if (ip->r_format.func == jr_op && ip->r_format.rs == 31) - return 1; - /* lui gp */ - if (ip->i_format.opcode == lui_op && ip->i_format.rt == 28) - return 1; - return 0; -} - -/* - * TODO for userspace stack unwinding: - * - handle cases where the stack is adjusted inside a function - * (generally doesn't happen) - * - find optimal value for max_instr_check - * - try to find a better way to handle leaf functions - */ - -static inline int unwind_user_frame(struct stackframe *old_frame, - const unsigned int max_instr_check) -{ - struct stackframe new_frame = *old_frame; - off_t ra_offset = 0; - size_t stack_size = 0; - unsigned long addr; - - if (old_frame->pc == 0 || old_frame->sp == 0 || old_frame->ra == 0) - return -9; - - for (addr = new_frame.pc; (addr + max_instr_check > new_frame.pc) - && (!ra_offset || !stack_size); --addr) { - union mips_instruction ip; - - if (get_mem(addr, (unsigned long *) &ip)) - return -11; - - if (is_sp_move_ins(&ip)) { - int stack_adjustment = ip.i_format.simmediate; - if (stack_adjustment > 0) - /* This marks the end of the previous function, - which means we overran. */ - break; - stack_size = (unsigned long) stack_adjustment; - } else if (is_ra_save_ins(&ip)) { - int ra_slot = ip.i_format.simmediate; - if (ra_slot < 0) - /* This shouldn't happen. */ - break; - ra_offset = ra_slot; - } else if (is_end_of_function_marker(&ip)) - break; - } - - if (!ra_offset || !stack_size) - goto done; - - if (ra_offset) { - new_frame.ra = old_frame->sp + ra_offset; - if (get_mem(new_frame.ra, &(new_frame.ra))) - return -13; - } - - if (stack_size) { - new_frame.sp = old_frame->sp + stack_size; - if (get_mem(new_frame.sp, &(new_frame.sp))) - return -14; - } - - if (new_frame.sp > old_frame->sp) - return -2; - -done: - new_frame.pc = old_frame->ra; - *old_frame = new_frame; - - return 0; -} - -static inline void do_user_backtrace(unsigned long low_addr, - struct stackframe *frame, - unsigned int depth) -{ - const unsigned int max_instr_check = 512; - const unsigned long high_addr = low_addr + THREAD_SIZE; - - while (depth-- && !unwind_user_frame(frame, max_instr_check)) { - oprofile_add_trace(frame->ra); - if (frame->sp < low_addr || frame->sp > high_addr) - break; - } -} - -#ifndef CONFIG_KALLSYMS -static inline void do_kernel_backtrace(unsigned long low_addr, - struct stackframe *frame, - unsigned int depth) { } -#else -static inline void do_kernel_backtrace(unsigned long low_addr, - struct stackframe *frame, - unsigned int depth) -{ - while (depth-- && frame->pc) { - frame->pc = unwind_stack_by_address(low_addr, - &(frame->sp), - frame->pc, - &(frame->ra)); - oprofile_add_trace(frame->ra); - } -} -#endif - -void notrace op_mips_backtrace(struct pt_regs *const regs, unsigned int depth) -{ - struct stackframe frame = { .sp = regs->regs[29], - .pc = regs->cp0_epc, - .ra = regs->regs[31] }; - const int userspace = user_mode(regs); - const unsigned long low_addr = ALIGN(frame.sp, THREAD_SIZE); - - if (userspace) - do_user_backtrace(low_addr, &frame, depth); - else - do_kernel_backtrace(low_addr, &frame, depth); -} diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c deleted file mode 100644 index d3996c4c6440..000000000000 --- a/arch/mips/oprofile/common.c +++ /dev/null @@ -1,147 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2004, 2005 Ralf Baechle - * Copyright (C) 2005 MIPS Technologies, Inc. - */ -#include <linux/compiler.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/oprofile.h> -#include <linux/smp.h> -#include <asm/cpu-info.h> -#include <asm/cpu-type.h> - -#include "op_impl.h" - -extern struct op_mips_model op_model_mipsxx_ops __weak; -extern struct op_mips_model op_model_loongson2_ops __weak; -extern struct op_mips_model op_model_loongson3_ops __weak; - -static struct op_mips_model *model; - -static struct op_counter_config ctr[20]; - -static int op_mips_setup(void) -{ - /* Pre-compute the values to stuff in the hardware registers. */ - model->reg_setup(ctr); - - /* Configure the registers on all cpus. */ - on_each_cpu(model->cpu_setup, NULL, 1); - - return 0; -} - -static int op_mips_create_files(struct dentry *root) -{ - int i; - - for (i = 0; i < model->num_counters; ++i) { - struct dentry *dir; - char buf[4]; - - snprintf(buf, sizeof buf, "%d", i); - dir = oprofilefs_mkdir(root, buf); - - oprofilefs_create_ulong(dir, "enabled", &ctr[i].enabled); - oprofilefs_create_ulong(dir, "event", &ctr[i].event); - oprofilefs_create_ulong(dir, "count", &ctr[i].count); - oprofilefs_create_ulong(dir, "kernel", &ctr[i].kernel); - oprofilefs_create_ulong(dir, "user", &ctr[i].user); - oprofilefs_create_ulong(dir, "exl", &ctr[i].exl); - /* Dummy. */ - oprofilefs_create_ulong(dir, "unit_mask", &ctr[i].unit_mask); - } - - return 0; -} - -static int op_mips_start(void) -{ - on_each_cpu(model->cpu_start, NULL, 1); - - return 0; -} - -static void op_mips_stop(void) -{ - /* Disable performance monitoring for all counters. */ - on_each_cpu(model->cpu_stop, NULL, 1); -} - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - struct op_mips_model *lmodel = NULL; - int res; - - switch (boot_cpu_type()) { - case CPU_5KC: - case CPU_M14KC: - case CPU_M14KEC: - case CPU_20KC: - case CPU_24K: - case CPU_25KF: - case CPU_34K: - case CPU_1004K: - case CPU_74K: - case CPU_1074K: - case CPU_INTERAPTIV: - case CPU_PROAPTIV: - case CPU_P5600: - case CPU_I6400: - case CPU_M5150: - case CPU_LOONGSON32: - case CPU_SB1: - case CPU_SB1A: - case CPU_R10000: - case CPU_R12000: - case CPU_R14000: - case CPU_R16000: - case CPU_XLR: - lmodel = &op_model_mipsxx_ops; - break; - - case CPU_LOONGSON2EF: - lmodel = &op_model_loongson2_ops; - break; - case CPU_LOONGSON64: - lmodel = &op_model_loongson3_ops; - break; - } - - /* - * Always set the backtrace. This allows unsupported CPU types to still - * use timer-based oprofile. - */ - ops->backtrace = op_mips_backtrace; - - if (!lmodel) - return -ENODEV; - - res = lmodel->init(); - if (res) - return res; - - model = lmodel; - - ops->create_files = op_mips_create_files; - ops->setup = op_mips_setup; - //ops->shutdown = op_mips_shutdown; - ops->start = op_mips_start; - ops->stop = op_mips_stop; - ops->cpu_type = lmodel->cpu_type; - - printk(KERN_INFO "oprofile: using %s performance monitoring.\n", - lmodel->cpu_type); - - return 0; -} - -void oprofile_arch_exit(void) -{ - if (model) - model->exit(); -} diff --git a/arch/mips/oprofile/op_impl.h b/arch/mips/oprofile/op_impl.h deleted file mode 100644 index a4e758a39af4..000000000000 --- a/arch/mips/oprofile/op_impl.h +++ /dev/null @@ -1,41 +0,0 @@ -/** - * @file arch/alpha/oprofile/op_impl.h - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author Richard Henderson <rt...@tw...> - */ - -#ifndef OP_IMPL_H -#define OP_IMPL_H 1 - -extern int (*perf_irq)(void); - -/* Per-counter configuration as set via oprofilefs. */ -struct op_counter_config { - unsigned long enabled; - unsigned long event; - unsigned long count; - /* Dummies because I am too lazy to hack the userspace tools. */ - unsigned long kernel; - unsigned long user; - unsigned long exl; - unsigned long unit_mask; -}; - -/* Per-architecture configure and hooks. */ -struct op_mips_model { - void (*reg_setup) (struct op_counter_config *); - void (*cpu_setup) (void *dummy); - int (*init)(void); - void (*exit)(void); - void (*cpu_start)(void *args); - void (*cpu_stop)(void *args); - char *cpu_type; - unsigned char num_counters; -}; - -void op_mips_backtrace(struct pt_regs * const regs, unsigned int depth); - -#endif diff --git a/arch/mips/oprofile/op_model_loongson2.c b/arch/mips/oprofile/op_model_loongson2.c deleted file mode 100644 index b249ec0bebb2..000000000000 --- a/arch/mips/oprofile/op_model_loongson2.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Loongson2 performance counter driver for oprofile - * - * Copyright (C) 2009 Lemote Inc. - * Author: Yanhua <ya...@le...> - * Author: Wu Zhangjin <wuz...@gm...> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/init.h> -#include <linux/oprofile.h> -#include <linux/interrupt.h> - -#include <loongson.h> /* LOONGSON2_PERFCNT_IRQ */ -#include "op_impl.h" - -#define LOONGSON2_CPU_TYPE "mips/loongson2" - -#define LOONGSON2_PERFCNT_OVERFLOW (1ULL << 31) - -#define LOONGSON2_PERFCTRL_EXL (1UL << 0) -#define LOONGSON2_PERFCTRL_KERNEL (1UL << 1) -#define LOONGSON2_PERFCTRL_SUPERVISOR (1UL << 2) -#define LOONGSON2_PERFCTRL_USER (1UL << 3) -#define LOONGSON2_PERFCTRL_ENABLE (1UL << 4) -#define LOONGSON2_PERFCTRL_EVENT(idx, event) \ - (((event) & 0x0f) << ((idx) ? 9 : 5)) - -#define read_c0_perfctrl() __read_64bit_c0_register($24, 0) -#define write_c0_perfctrl(val) __write_64bit_c0_register($24, 0, val) -#define read_c0_perfcnt() __read_64bit_c0_register($25, 0) -#define write_c0_perfcnt(val) __write_64bit_c0_register($25, 0, val) - -static struct loongson2_register_config { - unsigned int ctrl; - unsigned long long reset_counter1; - unsigned long long reset_counter2; - int cnt1_enabled, cnt2_enabled; -} reg; - -static char *oprofid = "LoongsonPerf"; -static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id); - -static void reset_counters(void *arg) -{ - write_c0_perfctrl(0); - write_c0_perfcnt(0); -} - -static void loongson2_reg_setup(struct op_counter_config *cfg) -{ - unsigned int ctrl = 0; - - reg.reset_counter1 = 0; - reg.reset_counter2 = 0; - - /* - * Compute the performance counter ctrl word. - * For now, count kernel and user mode. - */ - if (cfg[0].enabled) { - ctrl |= LOONGSON2_PERFCTRL_EVENT(0, cfg[0].event); - reg.reset_counter1 = 0x80000000ULL - cfg[0].count; - } - - if (cfg[1].enabled) { - ctrl |= LOONGSON2_PERFCTRL_EVENT(1, cfg[1].event); - reg.reset_counter2 = 0x80000000ULL - cfg[1].count; - } - - if (cfg[0].enabled || cfg[1].enabled) { - ctrl |= LOONGSON2_PERFCTRL_EXL | LOONGSON2_PERFCTRL_ENABLE; - if (cfg[0].kernel || cfg[1].kernel) - ctrl |= LOONGSON2_PERFCTRL_KERNEL; - if (cfg[0].user || cfg[1].user) - ctrl |= LOONGSON2_PERFCTRL_USER; - } - - reg.ctrl = ctrl; - - reg.cnt1_enabled = cfg[0].enabled; - reg.cnt2_enabled = cfg[1].enabled; -} - -static void loongson2_cpu_setup(void *args) -{ - write_c0_perfcnt((reg.reset_counter2 << 32) | reg.reset_counter1); -} - -static void loongson2_cpu_start(void *args) -{ - /* Start all counters on current CPU */ - if (reg.cnt1_enabled || reg.cnt2_enabled) - write_c0_perfctrl(reg.ctrl); -} - -static void loongson2_cpu_stop(void *args) -{ - /* Stop all counters on current CPU */ - write_c0_perfctrl(0); - memset(®, 0, sizeof(reg)); -} - -static irqreturn_t loongson2_perfcount_handler(int irq, void *dev_id) -{ - uint64_t counter, counter1, counter2; - struct pt_regs *regs = get_irq_regs(); - int enabled; - - /* Check whether the irq belongs to me */ - enabled = read_c0_perfctrl() & LOONGSON2_PERFCTRL_ENABLE; - if (!enabled) - return IRQ_NONE; - enabled = reg.cnt1_enabled | reg.cnt2_enabled; - if (!enabled) - return IRQ_NONE; - - counter = read_c0_perfcnt(); - counter1 = counter & 0xffffffff; - counter2 = counter >> 32; - - if (counter1 & LOONGSON2_PERFCNT_OVERFLOW) { - if (reg.cnt1_enabled) - oprofile_add_sample(regs, 0); - counter1 = reg.reset_counter1; - } - if (counter2 & LOONGSON2_PERFCNT_OVERFLOW) { - if (reg.cnt2_enabled) - oprofile_add_sample(regs, 1); - counter2 = reg.reset_counter2; - } - - write_c0_perfcnt((counter2 << 32) | counter1); - - return IRQ_HANDLED; -} - -static int __init loongson2_init(void) -{ - return request_irq(LOONGSON2_PERFCNT_IRQ, loongson2_perfcount_handler, - IRQF_SHARED, "Perfcounter", oprofid); -} - -static void loongson2_exit(void) -{ - reset_counters(NULL); - free_irq(LOONGSON2_PERFCNT_IRQ, oprofid); -} - -struct op_mips_model op_model_loongson2_ops = { - .reg_setup = loongson2_reg_setup, - .cpu_setup = loongson2_cpu_setup, - .init = loongson2_init, - .exit = loongson2_exit, - .cpu_start = loongson2_cpu_start, - .cpu_stop = loongson2_cpu_stop, - .cpu_type = LOONGSON2_CPU_TYPE, - .num_counters = 2 -}; diff --git a/arch/mips/oprofile/op_model_loongson3.c b/arch/mips/oprofile/op_model_loongson3.c deleted file mode 100644 index 436b1fc99f2c..000000000000 --- a/arch/mips/oprofile/op_model_loongson3.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - */ -#include <linux/init.h> -#include <linux/cpu.h> -#include <linux/smp.h> -#include <linux/proc_fs.h> -#include <linux/oprofile.h> -#include <linux/spinlock.h> -#include <linux/interrupt.h> -#include <linux/uaccess.h> -#include <irq.h> -#include <loongson.h> -#include "op_impl.h" - -#define LOONGSON3_PERFCNT_OVERFLOW (1ULL << 63) - -#define LOONGSON3_PERFCTRL_EXL (1UL << 0) -#define LOONGSON3_PERFCTRL_KERNEL (1UL << 1) -#define LOONGSON3_PERFCTRL_SUPERVISOR (1UL << 2) -#define LOONGSON3_PERFCTRL_USER (1UL << 3) -#define LOONGSON3_PERFCTRL_ENABLE (1UL << 4) -#define LOONGSON3_PERFCTRL_W (1UL << 30) -#define LOONGSON3_PERFCTRL_M (1UL << 31) -#define LOONGSON3_PERFCTRL_EVENT(idx, event) \ - (((event) & (idx ? 0x0f : 0x3f)) << 5) - -/* Loongson-3 PerfCount performance counter1 register */ -#define read_c0_perflo1() __read_64bit_c0_register($25, 0) -#define write_c0_perflo1(val) __write_64bit_c0_register($25, 0, val) -#define read_c0_perfhi1() __read_64bit_c0_register($25, 1) -#define write_c0_perfhi1(val) __write_64bit_c0_register($25, 1, val) - -/* Loongson-3 PerfCount performance counter2 register */ -#define read_c0_perflo2() __read_64bit_c0_register($25, 2) -#define write_c0_perflo2(val) __write_64bit_c0_register($25, 2, val) -#define read_c0_perfhi2() __read_64bit_c0_register($25, 3) -#define write_c0_perfhi2(val) __write_64bit_c0_register($25, 3, val) - -static int (*save_perf_irq)(void); - -static struct loongson3_register_config { - unsigned int control1; - unsigned int control2; - unsigned long long reset_counter1; - unsigned long long reset_counter2; - int ctr1_enable, ctr2_enable; -} reg; - -static void reset_counters(void *arg) -{ - write_c0_perfhi1(0); - write_c0_perfhi2(0); - write_c0_perflo1(0xc0000000); - write_c0_perflo2(0x40000000); -} - -/* Compute all of the registers in preparation for enabling profiling. */ -static void loongson3_reg_setup(struct op_counter_config *ctr) -{ - unsigned int control1 = 0; - unsigned int control2 = 0; - - reg.reset_counter1 = 0; - reg.reset_counter2 = 0; - /* Compute the performance counter control word. */ - /* For now count kernel and user mode */ - if (ctr[0].enabled) { - control1 |= LOONGSON3_PERFCTRL_EVENT(0, ctr[0].event) | - LOONGSON3_PERFCTRL_ENABLE; - if (ctr[0].kernel) - control1 |= LOONGSON3_PERFCTRL_KERNEL; - if (ctr[0].user) - control1 |= LOONGSON3_PERFCTRL_USER; - reg.reset_counter1 = 0x8000000000000000ULL - ctr[0].count; - } - - if (ctr[1].enabled) { - control2 |= LOONGSON3_PERFCTRL_EVENT(1, ctr[1].event) | - LOONGSON3_PERFCTRL_ENABLE; - if (ctr[1].kernel) - control2 |= LOONGSON3_PERFCTRL_KERNEL; - if (ctr[1].user) - control2 |= LOONGSON3_PERFCTRL_USER; - reg.reset_counter2 = 0x8000000000000000ULL - ctr[1].count; - } - - if (ctr[0].enabled) - control1 |= LOONGSON3_PERFCTRL_EXL; - if (ctr[1].enabled) - control2 |= LOONGSON3_PERFCTRL_EXL; - - reg.control1 = control1; - reg.control2 = control2; - reg.ctr1_enable = ctr[0].enabled; - reg.ctr2_enable = ctr[1].enabled; -} - -/* Program all of the registers in preparation for enabling profiling. */ -static void loongson3_cpu_setup(void *args) -{ - uint64_t perfcount1, perfcount2; - - perfcount1 = reg.reset_counter1; - perfcount2 = reg.reset_counter2; - write_c0_perfhi1(perfcount1); - write_c0_perfhi2(perfcount2); -} - -static void loongson3_cpu_start(void *args) -{ - /* Start all counters on current CPU */ - reg.control1 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); - reg.control2 |= (LOONGSON3_PERFCTRL_W|LOONGSON3_PERFCTRL_M); - - if (reg.ctr1_enable) - write_c0_perflo1(reg.control1); - if (reg.ctr2_enable) - write_c0_perflo2(reg.control2); -} - -static void loongson3_cpu_stop(void *args) -{ - /* Stop all counters on current CPU */ - write_c0_perflo1(0xc0000000); - write_c0_perflo2(0x40000000); - memset(®, 0, sizeof(reg)); -} - -static int loongson3_perfcount_handler(void) -{ - unsigned long flags; - uint64_t counter1, counter2; - uint32_t cause, handled = IRQ_NONE; - struct pt_regs *regs = get_irq_regs(); - - cause = read_c0_cause(); - if (!(cause & CAUSEF_PCI)) - return handled; - - counter1 = read_c0_perfhi1(); - counter2 = read_c0_perfhi2(); - - local_irq_save(flags); - - if (counter1 & LOONGSON3_PERFCNT_OVERFLOW) { - if (reg.ctr1_enable) - oprofile_add_sample(regs, 0); - counter1 = reg.reset_counter1; - } - if (counter2 & LOONGSON3_PERFCNT_OVERFLOW) { - if (reg.ctr2_enable) - oprofile_add_sample(regs, 1); - counter2 = reg.reset_counter2; - } - - local_irq_restore(flags); - - write_c0_perfhi1(counter1); - write_c0_perfhi2(counter2); - - if (!(cause & CAUSEF_TI)) - handled = IRQ_HANDLED; - - return handled; -} - -static int loongson3_starting_cpu(unsigned int cpu) -{ - write_c0_perflo1(reg.control1); - write_c0_perflo2(reg.control2); - return 0; -} - -static int loongson3_dying_cpu(unsigned int cpu) -{ - write_c0_perflo1(0xc0000000); - write_c0_perflo2(0x40000000); - return 0; -} - -static int __init loongson3_init(void) -{ - on_each_cpu(reset_counters, NULL, 1); - cpuhp_setup_state_nocalls(CPUHP_AP_MIPS_OP_LOONGSON3_STARTING, - "mips/oprofile/loongson3:starting", - loongson3_starting_cpu, loongson3_dying_cpu); - save_perf_irq = perf_irq; - perf_irq = loongson3_perfcount_handler; - - return 0; -} - -static void loongson3_exit(void) -{ - on_each_cpu(reset_counters, NULL, 1); - cpuhp_remove_state_nocalls(CPUHP_AP_MIPS_OP_LOONGSON3_STARTING); - perf_irq = save_perf_irq; -} - -struct op_mips_model op_model_loongson3_ops = { - .reg_setup = loongson3_reg_setup, - .cpu_setup = loongson3_cpu_setup, - .init = loongson3_init, - .exit = loongson3_exit, - .cpu_start = loongson3_cpu_start, - .cpu_stop = loongson3_cpu_stop, - .cpu_type = "mips/loongson3", - .num_counters = 2 -}; diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c deleted file mode 100644 index 55d7b7fd18b6..000000000000 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ /dev/null @@ -1,479 +0,0 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 2004, 05, 06 by Ralf Baechle - * Copyright (C) 2005 by MIPS Technologies, Inc. - */ -#include <linux/cpumask.h> -#include <linux/oprofile.h> -#include <linux/interrupt.h> -#include <linux/smp.h> -#include <asm/irq_regs.h> -#include <asm/time.h> - -#include "op_impl.h" - -#define M_PERFCTL_EVENT(event) (((event) << MIPS_PERFCTRL_EVENT_S) & \ - MIPS_PERFCTRL_EVENT) -#define M_PERFCTL_VPEID(vpe) ((vpe) << MIPS_PERFCTRL_VPEID_S) - -#define M_COUNTER_OVERFLOW (1UL << 31) - -static int (*save_perf_irq)(void); -static int perfcount_irq; - -/* - * XLR has only one set of counters per core. Designate the - * first hardware thread in the core for setup and init. - * Skip CPUs with non-zero hardware thread id (4 hwt per core) - */ -#if defined(CONFIG_CPU_XLR) && defined(CONFIG_SMP) -#define oprofile_skip_cpu(c) ((cpu_logical_map(c) & 0x3) != 0) -#else -#define oprofile_skip_cpu(c) 0 -#endif - -#ifdef CONFIG_MIPS_MT_SMP -#define WHAT (MIPS_PERFCTRL_MT_EN_VPE | \ - M_PERFCTL_VPEID(cpu_vpe_id(¤t_cpu_data))) -#define vpe_id() (cpu_has_mipsmt_pertccounters ? \ - 0 : cpu_vpe_id(¤t_cpu_data)) - -/* - * The number of bits to shift to convert between counters per core and - * counters per VPE. There is no reasonable interface atm to obtain the - * number of VPEs used by Linux and in the 34K this number is fixed to two - * anyways so we hardcore a few things here for the moment. The way it's - * done here will ensure that oprofile VSMP kernel will run right on a lesser - * core like a 24K also or with maxcpus=1. - */ -static inline unsigned int vpe_shift(void) -{ - if (num_possible_cpus() > 1) - return 1; - - return 0; -} - -#else - -#define WHAT 0 -#define vpe_id() 0 - -static inline unsigned int vpe_shift(void) -{ - return 0; -} - -#endif - -static inline unsigned int counters_total_to_per_cpu(unsigned int counters) -{ - return counters >> vpe_shift(); -} - -static inline unsigned int counters_per_cpu_to_total(unsigned int counters) -{ - return counters << vpe_shift(); -} - -#define __define_perf_accessors(r, n, np) \ - \ -static inline unsigned int r_c0_ ## r ## n(void) \ -{ \ - unsigned int cpu = vpe_id(); \ - \ - switch (cpu) { \ - case 0: \ - return read_c0_ ## r ## n(); \ - case 1: \ - return read_c0_ ## r ## np(); \ - default: \ - BUG(); \ - } \ - return 0; \ -} \ - \ -static inline void w_c0_ ## r ## n(unsigned int value) \ -{ \ - unsigned int cpu = vpe_id(); \ - \ - switch (cpu) { \ - case 0: \ - write_c0_ ## r ## n(value); \ - return; \ - case 1: \ - write_c0_ ## r ## np(value); \ - return; \ - default: \ - BUG(); \ - } \ - return; \ -} \ - -__define_perf_accessors(perfcntr, 0, 2) -__define_perf_accessors(perfcntr, 1, 3) -__define_perf_accessors(perfcntr, 2, 0) -__define_perf_accessors(perfcntr, 3, 1) - -__define_perf_accessors(perfctrl, 0, 2) -__define_perf_accessors(perfctrl, 1, 3) -__define_perf_accessors(perfctrl, 2, 0) -__define_perf_accessors(perfctrl, 3, 1) - -struct op_mips_model op_model_mipsxx_ops; - -static struct mipsxx_register_config { - unsigned int control[4]; - unsigned int counter[4]; -} reg; - -/* Compute all of the registers in preparation for enabling profiling. */ - -static void mipsxx_reg_setup(struct op_counter_config *ctr) -{ - unsigned int counters = op_model_mipsxx_ops.num_counters; - int i; - - /* Compute the performance counter control word. */ - for (i = 0; i < counters; i++) { - reg.control[i] = 0; - reg.counter[i] = 0; - - if (!ctr[i].enabled) - continue; - - reg.control[i] = M_PERFCTL_EVENT(ctr[i].event) | - MIPS_PERFCTRL_IE; - if (ctr[i].kernel) - reg.control[i] |= MIPS_PERFCTRL_K; - if (ctr[i].user) - reg.control[i] |= MIPS_PERFCTRL_U; - if (ctr[i].exl) - reg.control[i] |= MIPS_PERFCTRL_EXL; - if (boot_cpu_type() == CPU_XLR) - reg.control[i] |= XLR_PERFCTRL_ALLTHREADS; - reg.counter[i] = 0x80000000 - ctr[i].count; - } -} - -/* Program all of the registers in preparation for enabling profiling. */ - -static void mipsxx_cpu_setup(void *args) -{ - unsigned int counters = op_model_mipsxx_ops.num_counters; - - if (oprofile_skip_cpu(smp_processor_id())) - return; - - switch (counters) { - case 4: - w_c0_perfctrl3(0); - w_c0_perfcntr3(reg.counter[3]); - fallthrough; - case 3: - w_c0_perfctrl2(0); - w_c0_perfcntr2(reg.counter[2]); - fallthrough; - case 2: - w_c0_perfctrl1(0); - w_c0_perfcntr1(reg.counter[1]); - fallthrough; - case 1: - w_c0_perfctrl0(0); - w_c0_perfcntr0(reg.counter[0]); - } -} - -/* Start all counters on current CPU */ -static void mipsxx_cpu_start(void *args) -{ - unsigned int counters = op_model_mipsxx_ops.num_counters; - - if (oprofile_skip_cpu(smp_processor_id())) - return; - - switch (counters) { - case 4: - w_c0_perfctrl3(WHAT | reg.control[3]); - fallthrough; - case 3: - w_c0_perfctrl2(WHAT | reg.control[2]); - fallthrough; - case 2: - w_c0_perfctrl1(WHAT | reg.control[1]); - fallthrough; - case 1: - w_c0_perfctrl0(WHAT | reg.control[0]); - } -} - -/* Stop all counters on current CPU */ -static void mipsxx_cpu_stop(void *args) -{ - unsigned int counters = op_model_mipsxx_ops.num_counters; - - if (oprofile_skip_cpu(smp_processor_id())) - return; - - switch (counters) { - case 4: - w_c0_perfctrl3(0); - fallthrough; - case 3: - w_c0_perfctrl2(0); - fallthrough; - case 2: - w_c0_perfctrl1(0); - fallthrough; - case 1: - w_c0_perfctrl0(0); - } -} - -static int mipsxx_perfcount_handler(void) -{ - unsigned int counters = op_model_mipsxx_ops.num_counters; - unsigned int control; - unsigned int counter; - int handled = IRQ_NONE; - - if (cpu_has_mips_r2 && !(read_c0_cause() & CAUSEF_PCI)) - return handled; - - switch (counters) { -#define HANDLE_COUNTER(n) \ - case n + 1: \ - control = r_c0_perfctrl ## n(); \ - counter = r_c0_perfcntr ## n(); \ - if ((control & MIPS_PERFCTRL_IE) && \ - (counter & M_COUNTER_OVERFLOW)) { \ - oprofile_add_sample(get_irq_regs(), n); \ - w_c0_perfcntr ## n(reg.counter[n]); \ - handled = IRQ_HANDLED; \ - } - HANDLE_COUNTER(3) - fallthrough; - HANDLE_COUNTER(2) - fallthrough; - HANDLE_COUNTER(1) - fallthrough; - HANDLE_COUNTER(0) - } - - return handled; -} - -static inline int __n_counters(void) -{ - if (!cpu_has_perf) - return 0; - if (!(read_c0_perfctrl0() & MIPS_PERFCTRL_M)) - return 1; - if (!(read_c0_perfctrl1() & MIPS_PERFCTRL_M)) - return 2; - if (!(read_c0_perfctrl2() & MIPS_PERFCTRL_M)) - return 3; - - return 4; -} - -static inline int n_counters(void) -{ - int counters; - - switch (current_cpu_type()) { - case CPU_R10000: - counters = 2; - break; - - case CPU_R12000: - case CPU_R14000: - case CPU_R16000: - counters = 4; - break; - - default: - counters = __n_counters(); - } - - return counters; -} - -static void reset_counters(void *arg) -{ - int counters = (int)(long)arg; - switch (counters) { - case 4: - w_c0_perfctrl3(0); - w_c0_perfcntr3(0); - fallthrough; - case 3: - w_c0_perfctrl2(0); - w_c0_perfcntr2(0); - fallthrough; - case 2: - w_c0_perfctrl1(0); - w_c0_perfcntr1(0); - fallthrough; - case 1: - w_c0_perfctrl0(0); - w_c0_perfcntr0(0); - } -} - -static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id) -{ - return mipsxx_perfcount_handler(); -} - -static int __init mipsxx_init(void) -{ - int counters; - - counters = n_counters(); - if (counters == 0) { - printk(KERN_ERR "Oprofile: CPU has no performance counters\n"); - return -ENODEV; - } - -#ifdef CONFIG_MIPS_MT_SMP - if (!cpu_has_mipsmt_pertccounters) - counters = counters_total_to_per_cpu(counters); -#endif - on_each_cpu(reset_counters, (void *)(long)counters, 1); - - op_model_mipsxx_ops.num_counters = counters; - switch (current_cpu_type()) { - case CPU_M14KC: - op_model_mipsxx_ops.cpu_type = "mips/M14Kc"; - break; - - case CPU_M14KEC: - op_model_mipsxx_ops.cpu_type = "mips/M14KEc"; - break; - - case CPU_20KC: - op_model_mipsxx_ops.cpu_type = "mips/20K"; - break; - - case CPU_24K: - op_model_mipsxx_ops.cpu_type = "mips/24K"; - break; - - case CPU_25KF: - op_model_mipsxx_ops.cpu_type = "mips/25K"; - break; - - case CPU_1004K: - case CPU_34K: - op_model_mipsxx_ops.cpu_type = "mips/34K"; - break; - - case CPU_1074K: - case CPU_74K: - op_model_mipsxx_ops.cpu_type = "mips/74K"; - break; - - case CPU_INTERAPTIV: - op_model_mipsxx_ops.cpu_type = "mips/interAptiv"; - break; - - case CPU_PROAPTIV: - op_model_mipsxx_ops.cpu_type = "mips/proAptiv"; - break; - - case CPU_P5600: - op_model_mipsxx_ops.cpu_type = "mips/P5600"; - break; - - case CPU_I6400: - op_model_mipsxx_ops.cpu_type = "mips/I6400"; - break; - - case CPU_M5150: - op_model_mipsxx_ops.cpu_type = "mips/M5150"; - break; - - case CPU_5KC: - op_model_mipsxx_ops.cpu_type = "mips/5K"; - break; - - case CPU_R10000: - if ((current_cpu_data.processor_id & 0xff) == 0x20) - op_model_mipsxx_ops.cpu_type = "mips/r10000-v2.x"; - else - op_model_mipsxx_ops.cpu_type = "mips/r10000"; - break; - - case CPU_R12000: - case CPU_R14000: - op_model_mipsxx_ops.cpu_type = "mips/r12000"; - break; - - case CPU_R16000: - op_model_mipsxx_ops.cpu_type = "mips/r16000"; - break; - - case CPU_SB1: - case CPU_SB1A: - op_model_mipsxx_ops.cpu_type = "mips/sb1"; - break; - - case CPU_LOONGSON32: - op_model_mipsxx_ops.cpu_type = "mips/loongson1"; - break; - - case CPU_XLR: - op_model_mipsxx_ops.cpu_type = "mips/xlr"; - break; - - default: - printk(KERN_ERR "Profiling unsupported for this CPU\n"); - - return -ENODEV; - } - - save_perf_irq = perf_irq; - perf_irq = mipsxx_perfcount_handler; - - if (get_c0_perfcount_int) - perfcount_irq = get_c0_perfcount_int(); - else if (cp0_perfcount_irq >= 0) - perfcount_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; - else - perfcount_irq = -1; - - if (perfcount_irq >= 0) - return request_irq(perfcount_irq, mipsxx_perfcount_int, - IRQF_PERCPU | IRQF_NOBALANCING | - IRQF_NO_THREAD | IRQF_NO_SUSPEND | - IRQF_SHARED, - "Perfcounter", save_perf_irq); - - return 0; -} - -static void mipsxx_exit(void) -{ - int counters = op_model_mipsxx_ops.num_counters; - - if (perfcount_irq >= 0) - free_irq(perfcount_irq, save_perf_irq); - - counters = counters_per_cpu_to_total(counters); - on_each_cpu(reset_counters, (void *)(long)counters, 1); - - perf_irq = save_perf_irq; -} - -struct op_mips_model op_model_mipsxx_ops = { - .reg_setup = mipsxx_reg_setup, - .cpu_setup = mipsxx_cpu_setup, - .init = mipsxx_init, - .exit = mipsxx_exit, - .cpu_start = mipsxx_cpu_start, - .cpu_stop = mipsxx_cpu_stop, -}; -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:02:42
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/parisc/Kconfig | 1 - arch/parisc/Makefile | 2 -- arch/parisc/oprofile/Makefile | 10 ---------- arch/parisc/oprofile/init.c | 23 ----------------------- 4 files changed, 36 deletions(-) delete mode 100644 arch/parisc/oprofile/Makefile delete mode 100644 arch/parisc/oprofile/init.c diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 78b17621ee4a..c2216e53fa81 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig @@ -4,7 +4,6 @@ config PARISC select ARCH_32BIT_OFF_T if !64BIT select ARCH_MIGHT_HAVE_PC_PARPORT select HAVE_IDE - select HAVE_OPROFILE select HAVE_FUNCTION_TRACER select HAVE_FUNCTION_GRAPH_TRACER select HAVE_SYSCALL_TRACEPOINTS diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile index 5140c602207f..7d9f71aa829a 100644 --- a/arch/parisc/Makefile +++ b/arch/parisc/Makefile @@ -116,8 +116,6 @@ kernel-y := mm/ kernel/ math-emu/ core-y += $(addprefix arch/parisc/, $(kernel-y)) libs-y += arch/parisc/lib/ $(LIBGCC) -drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ - boot := arch/parisc/boot PALO := $(shell if (which palo 2>&1); then : ; \ diff --git a/arch/parisc/oprofile/Makefile b/arch/parisc/oprofile/Makefile deleted file mode 100644 index 86a1ccc328eb..000000000000 --- a/arch/parisc/oprofile/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) init.o diff --git a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c deleted file mode 100644 index 026cba2af07a..000000000000 --- a/arch/parisc/oprofile/init.c +++ /dev/null @@ -1,23 +0,0 @@ -/** - * @file init.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/oprofile.h> - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - return -ENODEV; -} - - -void oprofile_arch_exit(void) -{ -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Helge D. <de...@gm...> - 2021-01-28 19:24:41
|
On 1/14/21 12:35 PM, Viresh Kumar wrote: > The "oprofile" user-space tools don't use the kernel OPROFILE support > any more, and haven't in a long time. User-space has been converted to > the perf interfaces. > > Remove the old oprofile's architecture specific support. > > Suggested-by: Christoph Hellwig <hc...@in...> > Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> For parisc parts: Acked-by: Helge Deller <de...@gm...> # parisc Thanks! Helge > --- > arch/parisc/Kconfig | 1 - > arch/parisc/Makefile | 2 -- > arch/parisc/oprofile/Makefile | 10 ---------- > arch/parisc/oprofile/init.c | 23 ----------------------- > 4 files changed, 36 deletions(-) > delete mode 100644 arch/parisc/oprofile/Makefile > delete mode 100644 arch/parisc/oprofile/init.c > > diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig > index 78b17621ee4a..c2216e53fa81 100644 > --- a/arch/parisc/Kconfig > +++ b/arch/parisc/Kconfig > @@ -4,7 +4,6 @@ config PARISC > select ARCH_32BIT_OFF_T if !64BIT > select ARCH_MIGHT_HAVE_PC_PARPORT > select HAVE_IDE > - select HAVE_OPROFILE > select HAVE_FUNCTION_TRACER > select HAVE_FUNCTION_GRAPH_TRACER > select HAVE_SYSCALL_TRACEPOINTS > diff --git a/arch/parisc/Makefile b/arch/parisc/Makefile > index 5140c602207f..7d9f71aa829a 100644 > --- a/arch/parisc/Makefile > +++ b/arch/parisc/Makefile > @@ -116,8 +116,6 @@ kernel-y := mm/ kernel/ math-emu/ > core-y += $(addprefix arch/parisc/, $(kernel-y)) > libs-y += arch/parisc/lib/ $(LIBGCC) > > -drivers-$(CONFIG_OPROFILE) += arch/parisc/oprofile/ > - > boot := arch/parisc/boot > > PALO := $(shell if (which palo 2>&1); then : ; \ > diff --git a/arch/parisc/oprofile/Makefile b/arch/parisc/oprofile/Makefile > deleted file mode 100644 > index 86a1ccc328eb..000000000000 > --- a/arch/parisc/oprofile/Makefile > +++ /dev/null > @@ -1,10 +0,0 @@ > -# SPDX-License-Identifier: GPL-2.0 > -obj-$(CONFIG_OPROFILE) += oprofile.o > - > -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ > - oprof.o cpu_buffer.o buffer_sync.o \ > - event_buffer.o oprofile_files.o \ > - oprofilefs.o oprofile_stats.o \ > - timer_int.o ) > - > -oprofile-y := $(DRIVER_OBJS) init.o > diff --git a/arch/parisc/oprofile/init.c b/arch/parisc/oprofile/init.c > deleted file mode 100644 > index 026cba2af07a..000000000000 > --- a/arch/parisc/oprofile/init.c > +++ /dev/null > @@ -1,23 +0,0 @@ > -/** > - * @file init.c > - * > - * @remark Copyright 2002 OProfile authors > - * @remark Read the file COPYING > - * > - * @author John Levon <le...@mo...> > - */ > - > -#include <linux/errno.h> > -#include <linux/init.h> > -#include <linux/kernel.h> > -#include <linux/oprofile.h> > - > -int __init oprofile_arch_init(struct oprofile_operations *ops) > -{ > - return -ENODEV; > -} > - > - > -void oprofile_arch_exit(void) > -{ > -} > |
From: Viresh K. <vir...@li...> - 2021-01-14 12:03:34
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/arm/Kconfig | 1 - arch/arm/Makefile | 2 - arch/arm/configs/bcm2835_defconfig | 1 - arch/arm/configs/cns3420vb_defconfig | 1 - arch/arm/configs/corgi_defconfig | 1 - arch/arm/configs/imx_v4_v5_defconfig | 1 - arch/arm/configs/keystone_defconfig | 1 - arch/arm/configs/multi_v5_defconfig | 1 - arch/arm/configs/mv78xx0_defconfig | 1 - arch/arm/configs/mvebu_v5_defconfig | 1 - arch/arm/configs/omap1_defconfig | 1 - arch/arm/configs/omap2plus_defconfig | 1 - arch/arm/configs/orion5x_defconfig | 1 - arch/arm/configs/pxa_defconfig | 1 - arch/arm/configs/qcom_defconfig | 1 - arch/arm/configs/socfpga_defconfig | 1 - arch/arm/configs/spitz_defconfig | 1 - arch/arm/configs/vexpress_defconfig | 1 - arch/arm/oprofile/Makefile | 14 --- arch/arm/oprofile/common.c | 132 --------------------------- 20 files changed, 165 deletions(-) delete mode 100644 arch/arm/oprofile/Makefile delete mode 100644 arch/arm/oprofile/common.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 138248999df7..c9d43d415d54 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -102,7 +102,6 @@ config ARM select HAVE_KRETPROBES if HAVE_KPROBES select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI - select HAVE_OPROFILE if HAVE_PERF_EVENTS select HAVE_OPTPROBES if !THUMB2_KERNEL select HAVE_PERF_EVENTS select HAVE_PERF_REGS diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 4aaec9599e8a..e06fee171ab1 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -266,8 +266,6 @@ core-y += $(machdirs) $(platdirs) core- += $(patsubst %,arch/arm/mach-%/, $(machine-)) core- += $(patsubst %,arch/arm/plat-%/, $(plat-)) -drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ - libs-y := arch/arm/lib/ $(libs-y) # Default target when executing plain make diff --git a/arch/arm/configs/bcm2835_defconfig b/arch/arm/configs/bcm2835_defconfig index 44ff9cd88d81..1ef2bc4c7f69 100644 --- a/arch/arm/configs/bcm2835_defconfig +++ b/arch/arm/configs/bcm2835_defconfig @@ -21,7 +21,6 @@ CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_JUMP_LABEL=y CONFIG_CC_STACKPROTECTOR_REGULAR=y CONFIG_MODULES=y diff --git a/arch/arm/configs/cns3420vb_defconfig b/arch/arm/configs/cns3420vb_defconfig index 66a80b46038d..63fa2eb21b75 100644 --- a/arch/arm/configs/cns3420vb_defconfig +++ b/arch/arm/configs/cns3420vb_defconfig @@ -11,7 +11,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_PERF_EVENTS is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/arm/configs/corgi_defconfig b/arch/arm/configs/corgi_defconfig index 911e880f06ed..15b749f6996d 100644 --- a/arch/arm/configs/corgi_defconfig +++ b/arch/arm/configs/corgi_defconfig @@ -5,7 +5,6 @@ CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EXPERT=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/arm/configs/imx_v4_v5_defconfig b/arch/arm/configs/imx_v4_v5_defconfig index bb70acc6b526..1d9fa77bbafc 100644 --- a/arch/arm/configs/imx_v4_v5_defconfig +++ b/arch/arm/configs/imx_v4_v5_defconfig @@ -27,7 +27,6 @@ CONFIG_AEABI=y CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_PM_DEBUG=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/arm/configs/keystone_defconfig b/arch/arm/configs/keystone_defconfig index 84a3b055f253..33c917df7b32 100644 --- a/arch/arm/configs/keystone_defconfig +++ b/arch/arm/configs/keystone_defconfig @@ -16,7 +16,6 @@ CONFIG_KALLSYMS_ALL=y # CONFIG_BASE_FULL is not set CONFIG_EMBEDDED=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y diff --git a/arch/arm/configs/multi_v5_defconfig b/arch/arm/configs/multi_v5_defconfig index e00be9faa23b..5170a1059a11 100644 --- a/arch/arm/configs/multi_v5_defconfig +++ b/arch/arm/configs/multi_v5_defconfig @@ -67,7 +67,6 @@ CONFIG_CPU_FREQ_STAT=y CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y CONFIG_CPU_IDLE=y CONFIG_ARM_KIRKWOOD_CPUIDLE=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig index b39b1300a459..cd703c15798f 100644 --- a/arch/arm/configs/mv78xx0_defconfig +++ b/arch/arm/configs/mv78xx0_defconfig @@ -5,7 +5,6 @@ CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y # CONFIG_SLUB_DEBUG is not set CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/arm/configs/mvebu_v5_defconfig b/arch/arm/configs/mvebu_v5_defconfig index 226f2e97c6e2..4f16716bfc32 100644 --- a/arch/arm/configs/mvebu_v5_defconfig +++ b/arch/arm/configs/mvebu_v5_defconfig @@ -4,7 +4,6 @@ CONFIG_NO_HZ=y CONFIG_HIGH_RES_TIMERS=y CONFIG_LOG_BUF_SHIFT=19 CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/arm/configs/omap1_defconfig b/arch/arm/configs/omap1_defconfig index 3b6e7452609b..3148567b66b6 100644 --- a/arch/arm/configs/omap1_defconfig +++ b/arch/arm/configs/omap1_defconfig @@ -13,7 +13,6 @@ CONFIG_EXPERT=y # CONFIG_VM_EVENT_COUNTERS is not set CONFIG_SLOB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index b515c31f0ab7..eb353ece7bac 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig @@ -68,7 +68,6 @@ CONFIG_CRYPTO_AES_ARM=m CONFIG_CRYPTO_AES_ARM_BS=m CONFIG_CRYPTO_GHASH_ARM_CE=m CONFIG_CRYPTO_CHACHA20_NEON=m -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig index 4bdbb036ac26..b9e3b647e732 100644 --- a/arch/arm/configs/orion5x_defconfig +++ b/arch/arm/configs/orion5x_defconfig @@ -5,7 +5,6 @@ CONFIG_LOG_BUF_SHIFT=14 CONFIG_EXPERT=y # CONFIG_SLUB_DEBUG is not set CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig index 8654ece13004..bd7dd81c9c54 100644 --- a/arch/arm/configs/pxa_defconfig +++ b/arch/arm/configs/pxa_defconfig @@ -13,7 +13,6 @@ CONFIG_KALLSYMS_ALL=y CONFIG_EMBEDDED=y CONFIG_SLOB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_FORCE_LOAD=y diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index d6733e745b80..43e3668f4bf0 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig @@ -10,7 +10,6 @@ CONFIG_EMBEDDED=y # CONFIG_SLUB_DEBUG is not set # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/arm/configs/socfpga_defconfig b/arch/arm/configs/socfpga_defconfig index e73c97b0f5b0..0c60eb382c80 100644 --- a/arch/arm/configs/socfpga_defconfig +++ b/arch/arm/configs/socfpga_defconfig @@ -18,7 +18,6 @@ CONFIG_ZBOOT_ROM_TEXT=0x0 CONFIG_ZBOOT_ROM_BSS=0x0 CONFIG_VFP=y CONFIG_NEON=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set diff --git a/arch/arm/configs/spitz_defconfig b/arch/arm/configs/spitz_defconfig index 8b2c14424927..f42c7a502b6e 100644 --- a/arch/arm/configs/spitz_defconfig +++ b/arch/arm/configs/spitz_defconfig @@ -5,7 +5,6 @@ CONFIG_SYSFS_DEPRECATED_V2=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_EXPERT=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/arm/configs/vexpress_defconfig b/arch/arm/configs/vexpress_defconfig index c01baf7d6e37..4479369540f2 100644 --- a/arch/arm/configs/vexpress_defconfig +++ b/arch/arm/configs/vexpress_defconfig @@ -11,7 +11,6 @@ CONFIG_CPUSETS=y # CONFIG_NET_NS is not set CONFIG_BLK_DEV_INITRD=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile deleted file mode 100644 index 39688dc9f181..000000000000 --- a/arch/arm/oprofile/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -ifeq ($(CONFIG_HW_PERF_EVENTS),y) -DRIVER_OBJS += $(addprefix ../../../drivers/oprofile/, oprofile_perf.o) -endif - -oprofile-y := $(DRIVER_OBJS) common.o diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c deleted file mode 100644 index 7cb3e0453fcd..000000000000 --- a/arch/arm/oprofile/common.c +++ /dev/null @@ -1,132 +0,0 @@ -/** - * @file common.c - * - * @remark Copyright 2004 Oprofile Authors - * @remark Copyright 2010 ARM Ltd. - * @remark Read the file COPYING - * - * @author Zwane Mwaikambo - * @author Will Deacon [move to perf] - */ - -#include <linux/cpumask.h> -#include <linux/init.h> -#include <linux/mutex.h> -#include <linux/oprofile.h> -#include <linux/perf_event.h> -#include <linux/platform_device.h> -#include <linux/slab.h> -#include <asm/stacktrace.h> -#include <linux/uaccess.h> - -#include <asm/perf_event.h> -#include <asm/ptrace.h> - -#ifdef CONFIG_HW_PERF_EVENTS - -/* - * OProfile has a curious naming scheme for the ARM PMUs, but they are - * part of the user ABI so we need to map from the perf PMU name for - * supported PMUs. - */ -static struct op_perf_name { - char *perf_name; - char *op_name; -} op_perf_name_map[] = { - { "armv5_xscale1", "arm/xscale1" }, - { "armv5_xscale2", "arm/xscale2" }, - { "armv6_1136", "arm/armv6" }, - { "armv6_1156", "arm/armv6" }, - { "armv6_1176", "arm/armv6" }, - { "armv6_11mpcore", "arm/mpcore" }, - { "armv7_cortex_a8", "arm/armv7" }, - { "armv7_cortex_a9", "arm/armv7-ca9" }, -}; - -char *op_name_from_perf_id(void) -{ - int i; - struct op_perf_name names; - const char *perf_name = perf_pmu_name(); - - for (i = 0; i < ARRAY_SIZE(op_perf_name_map); ++i) { - names = op_perf_name_map[i]; - if (!strcmp(names.perf_name, perf_name)) - return names.op_name; - } - - return NULL; -} -#endif - -static int report_trace(struct stackframe *frame, void *d) -{ - unsigned int *depth = d; - - if (*depth) { - oprofile_add_trace(frame->pc); - (*depth)--; - } - - return *depth == 0; -} - -/* - * The registers we're interested in are at the end of the variable - * length saved register structure. The fp points at the end of this - * structure so the address of this struct is: - * (struct frame_tail *)(xxx->fp)-1 - */ -struct frame_tail { - struct frame_tail *fp; - unsigned long sp; - unsigned long lr; -} __attribute__((packed)); - -static struct frame_tail* user_backtrace(struct frame_tail *tail) -{ - struct frame_tail buftail[2]; - - /* Also check accessibility of one struct frame_tail beyond */ - if (!access_ok(tail, sizeof(buftail))) - return NULL; - if (__copy_from_user_inatomic(buftail, tail, sizeof(buftail))) - return NULL; - - oprofile_add_trace(buftail[0].lr); - - /* frame pointers should strictly progress back up the stack - * (towards higher addresses) */ - if (tail + 1 >= buftail[0].fp) - return NULL; - - return buftail[0].fp-1; -} - -static void arm_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - struct frame_tail *tail = ((struct frame_tail *) regs->ARM_fp) - 1; - - if (!user_mode(regs)) { - struct stackframe frame; - arm_get_current_stackframe(regs, &frame); - walk_stackframe(&frame, report_trace, &depth); - return; - } - - while (depth-- && tail && !((unsigned long) tail & 3)) - tail = user_backtrace(tail); -} - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - /* provide backtrace support also in timer mode: */ - ops->backtrace = arm_backtrace; - - return oprofile_perf_init(ops); -} - -void oprofile_arch_exit(void) -{ - oprofile_perf_exit(); -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:03:43
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Also note that ia64 supports oprofile but not perf and profiling shouldn't be working anyway currently. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/ia64/Kconfig | 1 - arch/ia64/Makefile | 1 - arch/ia64/configs/bigsur_defconfig | 1 - arch/ia64/oprofile/Makefile | 10 --- arch/ia64/oprofile/backtrace.c | 131 ----------------------------- arch/ia64/oprofile/init.c | 28 ------ 6 files changed, 172 deletions(-) delete mode 100644 arch/ia64/oprofile/Makefile delete mode 100644 arch/ia64/oprofile/backtrace.c delete mode 100644 arch/ia64/oprofile/init.c diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index eed59ec32657..2ad7a8d29fcc 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -24,7 +24,6 @@ config IA64 select HAVE_UNSTABLE_SCHED_CLOCK select HAVE_EXIT_THREAD select HAVE_IDE - select HAVE_OPROFILE select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_FTRACE_MCOUNT_RECORD diff --git a/arch/ia64/Makefile b/arch/ia64/Makefile index 703b1c4f6d12..33c11fa31192 100644 --- a/arch/ia64/Makefile +++ b/arch/ia64/Makefile @@ -52,7 +52,6 @@ core-y += arch/ia64/kernel/ arch/ia64/mm/ core-$(CONFIG_IA64_SGI_UV) += arch/ia64/uv/ drivers-y += arch/ia64/pci/ arch/ia64/hp/common/ -drivers-$(CONFIG_OPROFILE) += arch/ia64/oprofile/ PHONY += compressed check diff --git a/arch/ia64/configs/bigsur_defconfig b/arch/ia64/configs/bigsur_defconfig index cfed5ed89301..c409756b5396 100644 --- a/arch/ia64/configs/bigsur_defconfig +++ b/arch/ia64/configs/bigsur_defconfig @@ -2,7 +2,6 @@ CONFIG_SYSVIPC=y CONFIG_POSIX_MQUEUE=y CONFIG_LOG_BUF_SHIFT=16 CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_PARTITION_ADVANCED=y diff --git a/arch/ia64/oprofile/Makefile b/arch/ia64/oprofile/Makefile deleted file mode 100644 index fc7944d462f4..000000000000 --- a/arch/ia64/oprofile/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) init.o backtrace.o diff --git a/arch/ia64/oprofile/backtrace.c b/arch/ia64/oprofile/backtrace.c deleted file mode 100644 index 6a219a946050..000000000000 --- a/arch/ia64/oprofile/backtrace.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file backtrace.c - * - * @remark Copyright 2004 Silicon Graphics Inc. All Rights Reserved. - * @remark Read the file COPYING - * - * @author Greg Banks <gn...@me...> - * @author Keith Owens <ka...@me...> - * Based on work done for the ia64 port of the SGI kernprof patch, which is - * Copyright (c) 2003-2004 Silicon Graphics Inc. All Rights Reserved. - */ - -#include <linux/oprofile.h> -#include <linux/sched.h> -#include <linux/mm.h> -#include <asm/ptrace.h> - -/* - * For IA64 we need to perform a complex little dance to get both - * the struct pt_regs and a synthetic struct switch_stack in place - * to allow the unwind code to work. This dance requires our unwind - * using code to be called from a function called from unw_init_running(). - * There we only get a single void* data pointer, so use this struct - * to hold all the data we need during the unwind. - */ -typedef struct -{ - unsigned int depth; - struct pt_regs *regs; - struct unw_frame_info frame; - unsigned long *prev_pfs_loc; /* state for WAR for old spinlock ool code */ -} ia64_backtrace_t; - -/* Returns non-zero if the PC is in the Interrupt Vector Table */ -static __inline__ int in_ivt_code(unsigned long pc) -{ - extern char ia64_ivt[]; - return (pc >= (u_long)ia64_ivt && pc < (u_long)ia64_ivt+32768); -} - -/* - * Unwind to next stack frame. - */ -static __inline__ int next_frame(ia64_backtrace_t *bt) -{ - /* - * Avoid unsightly console message from unw_unwind() when attempting - * to unwind through the Interrupt Vector Table which has no unwind - * information. - */ - if (in_ivt_code(bt->frame.ip)) - return 0; - - /* - * WAR for spinlock contention from leaf functions. ia64_spinlock_contention_pre3_4 - * has ar.pfs == r0. Leaf functions do not modify ar.pfs so ar.pfs remains - * as 0, stopping the backtrace. Record the previous ar.pfs when the current - * IP is in ia64_spinlock_contention_pre3_4 then unwind, if pfs_loc has not changed - * after unwind then use pt_regs.ar_pfs which is where the real ar.pfs is for - * leaf functions. - */ - if (bt->prev_pfs_loc && bt->regs && bt->frame.pfs_loc == bt->prev_pfs_loc) - bt->frame.pfs_loc = &bt->regs->ar_pfs; - bt->prev_pfs_loc = NULL; - - return unw_unwind(&bt->frame) == 0; -} - - -static void do_ia64_backtrace(struct unw_frame_info *info, void *vdata) -{ - ia64_backtrace_t *bt = vdata; - struct switch_stack *sw; - int count = 0; - u_long pc, sp; - - sw = (struct switch_stack *)(info+1); - /* padding from unw_init_running */ - sw = (struct switch_stack *)(((unsigned long)sw + 15) & ~15); - - unw_init_frame_info(&bt->frame, current, sw); - - /* skip over interrupt frame and oprofile calls */ - do { - unw_get_sp(&bt->frame, &sp); - if (sp >= (u_long)bt->regs) - break; - if (!next_frame(bt)) - return; - } while (count++ < 200); - - /* finally, grab the actual sample */ - while (bt->depth-- && next_frame(bt)) { - unw_get_ip(&bt->frame, &pc); - oprofile_add_trace(pc); - if (unw_is_intr_frame(&bt->frame)) { - /* - * Interrupt received on kernel stack; this can - * happen when timer interrupt fires while processing - * a softirq from the tail end of a hardware interrupt - * which interrupted a system call. Don't laugh, it - * happens! Splice the backtrace into two parts to - * avoid spurious cycles in the gprof output. - */ - /* TODO: split rather than drop the 2nd half */ - break; - } - } -} - -void -ia64_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - ia64_backtrace_t bt; - unsigned long flags; - - /* - * On IA64 there is little hope of getting backtraces from - * user space programs -- the problems of getting the unwind - * information from arbitrary user programs are extreme. - */ - if (user_mode(regs)) - return; - - bt.depth = depth; - bt.regs = regs; - bt.prev_pfs_loc = NULL; - local_irq_save(flags); - unw_init_running(do_ia64_backtrace, &bt); - local_irq_restore(flags); -} diff --git a/arch/ia64/oprofile/init.c b/arch/ia64/oprofile/init.c deleted file mode 100644 index a692ba16a07b..000000000000 --- a/arch/ia64/oprofile/init.c +++ /dev/null @@ -1,28 +0,0 @@ -/** - * @file init.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#include <linux/kernel.h> -#include <linux/oprofile.h> -#include <linux/init.h> -#include <linux/errno.h> - -extern int perfmon_init(struct oprofile_operations *ops); -extern void perfmon_exit(void); -extern void ia64_backtrace(struct pt_regs * const regs, unsigned int depth); - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - ops->backtrace = ia64_backtrace; - return -ENODEV; -} - - -void oprofile_arch_exit(void) -{ -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:05:29
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- Documentation/kbuild/makefiles.rst | 1 - arch/sparc/Kconfig | 1 - arch/sparc/Makefile | 1 - arch/sparc/configs/sparc64_defconfig | 1 - arch/sparc/oprofile/Makefile | 10 ---- arch/sparc/oprofile/init.c | 87 ---------------------------- 6 files changed, 101 deletions(-) delete mode 100644 arch/sparc/oprofile/Makefile delete mode 100644 arch/sparc/oprofile/init.c diff --git a/Documentation/kbuild/makefiles.rst b/Documentation/kbuild/makefiles.rst index 9f6a11881951..d7b2e027c1f8 100644 --- a/Documentation/kbuild/makefiles.rst +++ b/Documentation/kbuild/makefiles.rst @@ -1317,7 +1317,6 @@ a few targets. libs-y += arch/sparc/lib/ drivers-$(CONFIG_PM) += arch/sparc/power/ - drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ 7.5 Architecture-specific boot images ------------------------------------- diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig index c9c34dc52b7d..caf95e61162b 100644 --- a/arch/sparc/Kconfig +++ b/arch/sparc/Kconfig @@ -20,7 +20,6 @@ config SPARC select OF_PROMTREE select HAVE_ASM_MODVERSIONS select HAVE_IDE - select HAVE_OPROFILE select HAVE_ARCH_KGDB if !SMP || SPARC64 select HAVE_ARCH_TRACEHOOK select HAVE_ARCH_SECCOMP if SPARC64 diff --git a/arch/sparc/Makefile b/arch/sparc/Makefile index 4a0919581697..bee99e65fe23 100644 --- a/arch/sparc/Makefile +++ b/arch/sparc/Makefile @@ -65,7 +65,6 @@ libs-y += arch/sparc/prom/ libs-y += arch/sparc/lib/ drivers-$(CONFIG_PM) += arch/sparc/power/ -drivers-$(CONFIG_OPROFILE) += arch/sparc/oprofile/ boot := arch/sparc/boot diff --git a/arch/sparc/configs/sparc64_defconfig b/arch/sparc/configs/sparc64_defconfig index bde4d21a8ac8..d91eb6a76dd1 100644 --- a/arch/sparc/configs/sparc64_defconfig +++ b/arch/sparc/configs/sparc64_defconfig @@ -8,7 +8,6 @@ CONFIG_PERF_EVENTS=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/sparc/oprofile/Makefile b/arch/sparc/oprofile/Makefile deleted file mode 100644 index fe906e403d3a..000000000000 --- a/arch/sparc/oprofile/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) init.o diff --git a/arch/sparc/oprofile/init.c b/arch/sparc/oprofile/init.c deleted file mode 100644 index 43730c9b1c86..000000000000 --- a/arch/sparc/oprofile/init.c +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file init.c - * - * @remark Copyright 2002 OProfile authors - * @remark Read the file COPYING - * - * @author John Levon <le...@mo...> - */ - -#include <linux/kernel.h> -#include <linux/oprofile.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/param.h> /* for HZ */ - -#ifdef CONFIG_SPARC64 -#include <linux/notifier.h> -#include <linux/rcupdate.h> -#include <linux/kdebug.h> -#include <asm/nmi.h> - -static int profile_timer_exceptions_notify(struct notifier_block *self, - unsigned long val, void *data) -{ - struct die_args *args = data; - int ret = NOTIFY_DONE; - - switch (val) { - case DIE_NMI: - oprofile_add_sample(args->regs, 0); - ret = NOTIFY_STOP; - break; - default: - break; - } - return ret; -} - -static struct notifier_block profile_timer_exceptions_nb = { - .notifier_call = profile_timer_exceptions_notify, -}; - -static int timer_start(void) -{ - if (register_die_notifier(&profile_timer_exceptions_nb)) - return 1; - nmi_adjust_hz(HZ); - return 0; -} - - -static void timer_stop(void) -{ - nmi_adjust_hz(1); - unregister_die_notifier(&profile_timer_exceptions_nb); - synchronize_rcu(); /* Allow already-started NMIs to complete. */ -} - -static int op_nmi_timer_init(struct oprofile_operations *ops) -{ - if (atomic_read(&nmi_active) <= 0) - return -ENODEV; - - ops->start = timer_start; - ops->stop = timer_stop; - ops->cpu_type = "timer"; - printk(KERN_INFO "oprofile: Using perfctr NMI timer interrupt.\n"); - return 0; -} -#endif - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - int ret = -ENODEV; - -#ifdef CONFIG_SPARC64 - ret = op_nmi_timer_init(ops); - if (!ret) - return ret; -#endif - - return ret; -} - -void oprofile_arch_exit(void) -{ -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:05:55
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/sh/Kconfig | 1 - arch/sh/Makefile | 1 - arch/sh/configs/espt_defconfig | 1 - arch/sh/configs/migor_defconfig | 1 - arch/sh/configs/r7780mp_defconfig | 1 - arch/sh/configs/r7785rp_defconfig | 1 - arch/sh/configs/rsk7201_defconfig | 1 - arch/sh/configs/rsk7203_defconfig | 1 - arch/sh/configs/rts7751r2d1_defconfig | 1 - arch/sh/configs/rts7751r2dplus_defconfig | 1 - arch/sh/configs/sdk7786_defconfig | 1 - arch/sh/configs/se7206_defconfig | 1 - arch/sh/configs/sh03_defconfig | 1 - arch/sh/configs/sh7724_generic_defconfig | 1 - arch/sh/configs/sh7763rdp_defconfig | 1 - arch/sh/configs/sh7770_generic_defconfig | 1 - arch/sh/configs/shx3_defconfig | 1 - arch/sh/oprofile/Makefile | 16 ----- arch/sh/oprofile/backtrace.c | 80 ------------------------ arch/sh/oprofile/common.c | 64 ------------------- 20 files changed, 177 deletions(-) delete mode 100644 arch/sh/oprofile/Makefile delete mode 100644 arch/sh/oprofile/backtrace.c delete mode 100644 arch/sh/oprofile/common.c diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 5fa580219a86..1e64da1d1de6 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig @@ -51,7 +51,6 @@ config SUPERH select HAVE_MIXED_BREAKPOINTS_REGS select HAVE_MOD_ARCH_SPECIFIC if DWARF_UNWINDER select HAVE_NMI - select HAVE_OPROFILE select HAVE_PATA_PLATFORM select HAVE_PERF_EVENTS select HAVE_REGS_AND_STACK_ACCESS_API diff --git a/arch/sh/Makefile b/arch/sh/Makefile index 2faebfd72eca..3bcbf52fb30e 100644 --- a/arch/sh/Makefile +++ b/arch/sh/Makefile @@ -170,7 +170,6 @@ cpuincdir-$(CONFIG_CPU_SH4) += cpu-sh4 cpuincdir-y += cpu-common # Must be last drivers-y += arch/sh/drivers/ -drivers-$(CONFIG_OPROFILE) += arch/sh/oprofile/ cflags-y += $(foreach d, $(cpuincdir-y), -I $(srctree)/arch/sh/include/$(d)) \ $(foreach d, $(machdir-y), -I $(srctree)/arch/sh/include/$(d)) diff --git a/arch/sh/configs/espt_defconfig b/arch/sh/configs/espt_defconfig index 9a988c347e9d..2804cb760a76 100644 --- a/arch/sh/configs/espt_defconfig +++ b/arch/sh/configs/espt_defconfig @@ -7,7 +7,6 @@ CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7763=y diff --git a/arch/sh/configs/migor_defconfig b/arch/sh/configs/migor_defconfig index a24cf8cd2cea..4859cd30cfc4 100644 --- a/arch/sh/configs/migor_defconfig +++ b/arch/sh/configs/migor_defconfig @@ -6,7 +6,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7722=y diff --git a/arch/sh/configs/r7780mp_defconfig b/arch/sh/configs/r7780mp_defconfig index e922659fdadb..f823cc6b18f9 100644 --- a/arch/sh/configs/r7780mp_defconfig +++ b/arch/sh/configs/r7780mp_defconfig @@ -7,7 +7,6 @@ CONFIG_LOG_BUF_SHIFT=14 # CONFIG_EPOLL is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set diff --git a/arch/sh/configs/r7785rp_defconfig b/arch/sh/configs/r7785rp_defconfig index 5978866358ec..f96bc20d4b1a 100644 --- a/arch/sh/configs/r7785rp_defconfig +++ b/arch/sh/configs/r7785rp_defconfig @@ -9,7 +9,6 @@ CONFIG_IKCONFIG_PROC=y CONFIG_LOG_BUF_SHIFT=14 CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/sh/configs/rsk7201_defconfig b/arch/sh/configs/rsk7201_defconfig index 841809b5c2dc..e41526120be1 100644 --- a/arch/sh/configs/rsk7201_defconfig +++ b/arch/sh/configs/rsk7201_defconfig @@ -12,7 +12,6 @@ CONFIG_BLK_DEV_INITRD=y # CONFIG_AIO is not set CONFIG_SLOB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7201=y diff --git a/arch/sh/configs/rsk7203_defconfig b/arch/sh/configs/rsk7203_defconfig index 0055031664ad..6af08fa1ddf8 100644 --- a/arch/sh/configs/rsk7203_defconfig +++ b/arch/sh/configs/rsk7203_defconfig @@ -13,7 +13,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_KALLSYMS_ALL=y CONFIG_SLOB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7203=y diff --git a/arch/sh/configs/rts7751r2d1_defconfig b/arch/sh/configs/rts7751r2d1_defconfig index fc9c22152b08..96263a4912b7 100644 --- a/arch/sh/configs/rts7751r2d1_defconfig +++ b/arch/sh/configs/rts7751r2d1_defconfig @@ -3,7 +3,6 @@ CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7751R=y diff --git a/arch/sh/configs/rts7751r2dplus_defconfig b/arch/sh/configs/rts7751r2dplus_defconfig index ff3fd6787fd6..92e586e6c974 100644 --- a/arch/sh/configs/rts7751r2dplus_defconfig +++ b/arch/sh/configs/rts7751r2dplus_defconfig @@ -3,7 +3,6 @@ CONFIG_LOG_BUF_SHIFT=14 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7751R=y diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig index 61bec46ebd66..e804347cf68c 100644 --- a/arch/sh/configs/sdk7786_defconfig +++ b/arch/sh/configs/sdk7786_defconfig @@ -35,7 +35,6 @@ CONFIG_RD_LZO=y # CONFIG_COMPAT_BRK is not set CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig index ff5bb4489922..315b04a8dd2f 100644 --- a/arch/sh/configs/se7206_defconfig +++ b/arch/sh/configs/se7206_defconfig @@ -23,7 +23,6 @@ CONFIG_KALLSYMS_ALL=y # CONFIG_COMPAT_BRK is not set CONFIG_SLOB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set diff --git a/arch/sh/configs/sh03_defconfig b/arch/sh/configs/sh03_defconfig index f0073ed39947..f0ce5b0057ed 100644 --- a/arch/sh/configs/sh03_defconfig +++ b/arch/sh/configs/sh03_defconfig @@ -5,7 +5,6 @@ CONFIG_LOG_BUF_SHIFT=14 CONFIG_BLK_DEV_INITRD=y CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y diff --git a/arch/sh/configs/sh7724_generic_defconfig b/arch/sh/configs/sh7724_generic_defconfig index 9adee9010319..2c46c0004780 100644 --- a/arch/sh/configs/sh7724_generic_defconfig +++ b/arch/sh/configs/sh7724_generic_defconfig @@ -4,7 +4,6 @@ CONFIG_CGROUPS=y # CONFIG_UID16 is not set # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y -CONFIG_OPROFILE=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7724=y CONFIG_NO_HZ=y diff --git a/arch/sh/configs/sh7763rdp_defconfig b/arch/sh/configs/sh7763rdp_defconfig index 26c5fd02c87a..8a6a446f9eb8 100644 --- a/arch/sh/configs/sh7763rdp_defconfig +++ b/arch/sh/configs/sh7763rdp_defconfig @@ -7,7 +7,6 @@ CONFIG_UTS_NS=y CONFIG_IPC_NS=y CONFIG_SLAB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7763=y diff --git a/arch/sh/configs/sh7770_generic_defconfig b/arch/sh/configs/sh7770_generic_defconfig index c17590f0df67..88193153e51b 100644 --- a/arch/sh/configs/sh7770_generic_defconfig +++ b/arch/sh/configs/sh7770_generic_defconfig @@ -4,7 +4,6 @@ CONFIG_CGROUPS=y # CONFIG_UID16 is not set # CONFIG_COMPAT_BRK is not set CONFIG_PROFILING=y -CONFIG_OPROFILE=y # CONFIG_BLK_DEV_BSG is not set CONFIG_CPU_SUBTYPE_SH7770=y CONFIG_SH_PCLK_FREQ=41666666 diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig index dc2be2514b62..32ec6eb1eabc 100644 --- a/arch/sh/configs/shx3_defconfig +++ b/arch/sh/configs/shx3_defconfig @@ -22,7 +22,6 @@ CONFIG_PID_NS=y CONFIG_KALLSYMS_ALL=y CONFIG_SLOB=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_KPROBES=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y diff --git a/arch/sh/oprofile/Makefile b/arch/sh/oprofile/Makefile deleted file mode 100644 index d478dd8dac0b..000000000000 --- a/arch/sh/oprofile/Makefile +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -CFLAGS_common.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -ifeq ($(CONFIG_HW_PERF_EVENTS),y) -DRIVER_OBJS += $(addprefix ../../../drivers/oprofile/, oprofile_perf.o) -endif - -oprofile-y := $(DRIVER_OBJS) common.o backtrace.o diff --git a/arch/sh/oprofile/backtrace.c b/arch/sh/oprofile/backtrace.c deleted file mode 100644 index cc16cf86cd92..000000000000 --- a/arch/sh/oprofile/backtrace.c +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * SH specific backtracing code for oprofile - * - * Copyright 2007 STMicroelectronics Ltd. - * - * Author: Dave Peverley <dpe...@mp...> - * - * Based on ARM oprofile backtrace code by Richard Purdie and in turn, i386 - * oprofile backtrace code by John Levon, David Smith - */ -#include <linux/oprofile.h> -#include <linux/sched.h> -#include <linux/kallsyms.h> -#include <linux/mm.h> -#include <asm/unwinder.h> -#include <asm/ptrace.h> -#include <linux/uaccess.h> -#include <asm/sections.h> -#include <asm/stacktrace.h> - -static void backtrace_address(void *data, unsigned long addr, int reliable) -{ - unsigned int *depth = data; - - if ((*depth)--) - oprofile_add_trace(addr); -} - -static struct stacktrace_ops backtrace_ops = { - .address = backtrace_address, -}; - -/* Limit to stop backtracing too far. */ -static int backtrace_limit = 20; - -static unsigned long * -user_backtrace(unsigned long *stackaddr, struct pt_regs *regs) -{ - unsigned long buf_stack; - - /* Also check accessibility of address */ - if (!access_ok(stackaddr, sizeof(unsigned long))) - return NULL; - - if (__copy_from_user_inatomic(&buf_stack, stackaddr, sizeof(unsigned long))) - return NULL; - - /* Quick paranoia check */ - if (buf_stack & 3) - return NULL; - - oprofile_add_trace(buf_stack); - - stackaddr++; - - return stackaddr; -} - -void sh_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - unsigned long *stackaddr; - - /* - * Paranoia - clip max depth as we could get lost in the weeds. - */ - if (depth > backtrace_limit) - depth = backtrace_limit; - - stackaddr = (unsigned long *)kernel_stack_pointer(regs); - if (!user_mode(regs)) { - if (depth) - unwind_stack(NULL, regs, stackaddr, - &backtrace_ops, &depth); - return; - } - - while (depth-- && (stackaddr != NULL)) - stackaddr = user_backtrace(stackaddr, regs); -} diff --git a/arch/sh/oprofile/common.c b/arch/sh/oprofile/common.c deleted file mode 100644 index e4dd5d5a1115..000000000000 --- a/arch/sh/oprofile/common.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * arch/sh/oprofile/init.c - * - * Copyright (C) 2003 - 2010 Paul Mundt - * - * Based on arch/mips/oprofile/common.c: - * - * Copyright (C) 2004, 2005 Ralf Baechle - * Copyright (C) 2005 MIPS Technologies, Inc. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include <linux/kernel.h> -#include <linux/oprofile.h> -#include <linux/init.h> -#include <linux/errno.h> -#include <linux/smp.h> -#include <linux/perf_event.h> -#include <linux/slab.h> -#include <asm/processor.h> - -extern void sh_backtrace(struct pt_regs * const regs, unsigned int depth); - -#ifdef CONFIG_HW_PERF_EVENTS -/* - * This will need to be reworked when multiple PMUs are supported. - */ -static char *sh_pmu_op_name; - -char *op_name_from_perf_id(void) -{ - return sh_pmu_op_name; -} - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - ops->backtrace = sh_backtrace; - - if (perf_num_counters() == 0) - return -ENODEV; - - sh_pmu_op_name = kasprintf(GFP_KERNEL, "%s/%s", - UTS_MACHINE, perf_pmu_name()); - if (unlikely(!sh_pmu_op_name)) - return -ENOMEM; - - return oprofile_perf_init(ops); -} - -void oprofile_arch_exit(void) -{ - oprofile_perf_exit(); - kfree(sh_pmu_op_name); -} -#else -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - ops->backtrace = sh_backtrace; - return -ENODEV; -} -void oprofile_arch_exit(void) {} -#endif /* CONFIG_HW_PERF_EVENTS */ -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:05:56
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/arc/Kconfig | 1 - arch/arc/Makefile | 2 -- arch/arc/oprofile/Makefile | 10 ---------- arch/arc/oprofile/common.c | 23 ----------------------- 4 files changed, 36 deletions(-) delete mode 100644 arch/arc/oprofile/Makefile delete mode 100644 arch/arc/oprofile/common.c diff --git a/arch/arc/Kconfig b/arch/arc/Kconfig index b55ca77f619b..bc8d6aecfbbd 100644 --- a/arch/arc/Kconfig +++ b/arch/arc/Kconfig @@ -37,7 +37,6 @@ config ARC select HAVE_KPROBES select HAVE_KRETPROBES select HAVE_MOD_ARCH_SPECIFIC - select HAVE_OPROFILE select HAVE_PERF_EVENTS select HANDLE_DOMAIN_IRQ select IRQ_DOMAIN diff --git a/arch/arc/Makefile b/arch/arc/Makefile index 578bdbbb0fa7..4392c9c189c4 100644 --- a/arch/arc/Makefile +++ b/arch/arc/Makefile @@ -96,8 +96,6 @@ core-$(CONFIG_ARC_PLAT_TB10X) += arch/arc/plat-tb10x/ core-$(CONFIG_ARC_PLAT_AXS10X) += arch/arc/plat-axs10x/ core-$(CONFIG_ARC_SOC_HSDK) += arch/arc/plat-hsdk/ -drivers-$(CONFIG_OPROFILE) += arch/arc/oprofile/ - libs-y += arch/arc/lib/ $(LIBGCC) boot := arch/arc/boot diff --git a/arch/arc/oprofile/Makefile b/arch/arc/oprofile/Makefile deleted file mode 100644 index 698367bb41d0..000000000000 --- a/arch/arc/oprofile/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) common.o diff --git a/arch/arc/oprofile/common.c b/arch/arc/oprofile/common.c deleted file mode 100644 index 86bf5899533b..000000000000 --- a/arch/arc/oprofile/common.c +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com) - * - * Based on orig code from @author John Levon <le...@mo...> - */ - -#include <linux/oprofile.h> -#include <linux/perf_event.h> - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - /* - * A failure here, forces oprofile core to switch to Timer based PC - * sampling, which will happen if say perf is not enabled/available - */ - return oprofile_perf_init(ops); -} - -void oprofile_arch_exit(void) -{ - oprofile_perf_exit(); -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:06:02
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Don't select HAVE_OPROFILE for hexagon anymore. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/hexagon/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index 6e00c16a36b5..44a409967af1 100644 --- a/arch/hexagon/Kconfig +++ b/arch/hexagon/Kconfig @@ -7,7 +7,6 @@ config HEXAGON select ARCH_32BIT_OFF_T select ARCH_HAS_SYNC_DMA_FOR_DEVICE select ARCH_NO_PREEMPT - select HAVE_OPROFILE # Other pending projects/to-do items. # select HAVE_REGS_AND_STACK_ACCESS_API # select HAVE_HW_BREAKPOINT if PERF_EVENTS -- 2.25.0.rc1.19.g042ed3e048af |
From: Brian C. <bc...@co...> - 2021-01-15 15:57:28
|
> -----Original Message----- > From: Viresh Kumar <vir...@li...> > Sent: Thursday, January 14, 2021 5:35 AM ... > The "oprofile" user-space tools don't use the kernel OPROFILE support any > more, and haven't in a long time. User-space has been converted to the perf > interfaces. > > Don't select HAVE_OPROFILE for hexagon anymore. Acked-by: Brian Cain <bc...@co...> > Suggested-by: Christoph Hellwig <hc...@in...> > Suggested-by: Linus Torvalds <tor...@li...> > Signed-off-by: Viresh Kumar <vir...@li...> > --- > arch/hexagon/Kconfig | 1 - > 1 file changed, 1 deletion(-) > > diff --git a/arch/hexagon/Kconfig b/arch/hexagon/Kconfig index > 6e00c16a36b5..44a409967af1 100644 > --- a/arch/hexagon/Kconfig > +++ b/arch/hexagon/Kconfig > @@ -7,7 +7,6 @@ config HEXAGON > select ARCH_32BIT_OFF_T > select ARCH_HAS_SYNC_DMA_FOR_DEVICE > select ARCH_NO_PREEMPT > - select HAVE_OPROFILE > # Other pending projects/to-do items. > # select HAVE_REGS_AND_STACK_ACCESS_API > # select HAVE_HW_BREAKPOINT if PERF_EVENTS > -- > 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:06:56
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/xtensa/Kconfig | 1 - arch/xtensa/Makefile | 1 - arch/xtensa/configs/audio_kc705_defconfig | 1 - arch/xtensa/configs/generic_kc705_defconfig | 1 - arch/xtensa/configs/smp_lx200_defconfig | 1 - arch/xtensa/configs/xip_kc705_defconfig | 1 - arch/xtensa/kernel/stacktrace.c | 2 +- arch/xtensa/oprofile/Makefile | 10 -------- arch/xtensa/oprofile/backtrace.c | 27 --------------------- arch/xtensa/oprofile/init.c | 26 -------------------- 10 files changed, 1 insertion(+), 70 deletions(-) delete mode 100644 arch/xtensa/oprofile/Makefile delete mode 100644 arch/xtensa/oprofile/backtrace.c delete mode 100644 arch/xtensa/oprofile/init.c diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 37ce1489364e..9ad6b7b82707 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig @@ -32,7 +32,6 @@ config XTENSA select HAVE_FUTEX_CMPXCHG if !MMU select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IRQ_TIME_ACCOUNTING - select HAVE_OPROFILE select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_STACKPROTECTOR diff --git a/arch/xtensa/Makefile b/arch/xtensa/Makefile index 67a7d151d1e7..cf0940708702 100644 --- a/arch/xtensa/Makefile +++ b/arch/xtensa/Makefile @@ -83,7 +83,6 @@ core-y += $(buildvar) $(buildplf) core-y += arch/xtensa/boot/dts/ libs-y += arch/xtensa/lib/ $(LIBGCC) -drivers-$(CONFIG_OPROFILE) += arch/xtensa/oprofile/ boot := arch/xtensa/boot diff --git a/arch/xtensa/configs/audio_kc705_defconfig b/arch/xtensa/configs/audio_kc705_defconfig index eeb4c5383c83..3be62da8089b 100644 --- a/arch/xtensa/configs/audio_kc705_defconfig +++ b/arch/xtensa/configs/audio_kc705_defconfig @@ -18,7 +18,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_XTENSA_VARIANT_CUSTOM=y diff --git a/arch/xtensa/configs/generic_kc705_defconfig b/arch/xtensa/configs/generic_kc705_defconfig index 412f611033cc..e9d6b6f6eca1 100644 --- a/arch/xtensa/configs/generic_kc705_defconfig +++ b/arch/xtensa/configs/generic_kc705_defconfig @@ -18,7 +18,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_XTENSA_VARIANT_DC233C=y diff --git a/arch/xtensa/configs/smp_lx200_defconfig b/arch/xtensa/configs/smp_lx200_defconfig index 4f1c7998b030..a47c85638ec1 100644 --- a/arch/xtensa/configs/smp_lx200_defconfig +++ b/arch/xtensa/configs/smp_lx200_defconfig @@ -18,7 +18,6 @@ CONFIG_BLK_DEV_INITRD=y CONFIG_EXPERT=y CONFIG_KALLSYMS_ALL=y CONFIG_PROFILING=y -CONFIG_OPROFILE=y CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_XTENSA_VARIANT_CUSTOM=y diff --git a/arch/xtensa/configs/xip_kc705_defconfig b/arch/xtensa/configs/xip_kc705_defconfig index f9e85c082afc..4f1ff9531f6a 100644 --- a/arch/xtensa/configs/xip_kc705_defconfig +++ b/arch/xtensa/configs/xip_kc705_defconfig @@ -31,7 +31,6 @@ CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0 CONFIG_USE_OF=y CONFIG_BUILTIN_DTB_SOURCE="kc705" # CONFIG_PARSE_BOOTPARAM is not set -CONFIG_OPROFILE=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set # CONFIG_COMPACTION is not set CONFIG_NET=y diff --git a/arch/xtensa/kernel/stacktrace.c b/arch/xtensa/kernel/stacktrace.c index c822abb93d20..7f7755cd28f0 100644 --- a/arch/xtensa/kernel/stacktrace.c +++ b/arch/xtensa/kernel/stacktrace.c @@ -16,7 +16,7 @@ #include <asm/traps.h> #include <linux/uaccess.h> -#if IS_ENABLED(CONFIG_OPROFILE) || IS_ENABLED(CONFIG_PERF_EVENTS) +#if IS_ENABLED(CONFIG_PERF_EVENTS) /* Address of common_exception_return, used to check the * transition from kernel to user space. diff --git a/arch/xtensa/oprofile/Makefile b/arch/xtensa/oprofile/Makefile deleted file mode 100644 index f559b9ffbb3f..000000000000 --- a/arch/xtensa/oprofile/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) init.o backtrace.o diff --git a/arch/xtensa/oprofile/backtrace.c b/arch/xtensa/oprofile/backtrace.c deleted file mode 100644 index 8f952034e161..000000000000 --- a/arch/xtensa/oprofile/backtrace.c +++ /dev/null @@ -1,27 +0,0 @@ -/** - * @file backtrace.c - * - * @remark Copyright 2008 Tensilica Inc. - * Copyright (C) 2015 Cadence Design Systems Inc. - * @remark Read the file COPYING - * - */ - -#include <linux/oprofile.h> -#include <asm/ptrace.h> -#include <asm/stacktrace.h> - -static int xtensa_backtrace_cb(struct stackframe *frame, void *data) -{ - oprofile_add_trace(frame->pc); - return 0; -} - -void xtensa_backtrace(struct pt_regs * const regs, unsigned int depth) -{ - if (user_mode(regs)) - xtensa_backtrace_user(regs, depth, xtensa_backtrace_cb, NULL); - else - xtensa_backtrace_kernel(regs, depth, xtensa_backtrace_cb, - xtensa_backtrace_cb, NULL); -} diff --git a/arch/xtensa/oprofile/init.c b/arch/xtensa/oprofile/init.c deleted file mode 100644 index a67eea379766..000000000000 --- a/arch/xtensa/oprofile/init.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * @file init.c - * - * @remark Copyright 2008 Tensilica Inc. - * @remark Read the file COPYING - * - */ - -#include <linux/kernel.h> -#include <linux/oprofile.h> -#include <linux/errno.h> -#include <linux/init.h> - - -extern void xtensa_backtrace(struct pt_regs *const regs, unsigned int depth); - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - ops->backtrace = xtensa_backtrace; - return -ENODEV; -} - - -void oprofile_arch_exit(void) -{ -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Max F. <jcm...@gm...> - 2021-01-14 20:38:19
|
On Thu, Jan 14, 2021 at 3:36 AM Viresh Kumar <vir...@li...> wrote: > > The "oprofile" user-space tools don't use the kernel OPROFILE support > any more, and haven't in a long time. User-space has been converted to > the perf interfaces. > > Remove the old oprofile's architecture specific support. > > Suggested-by: Christoph Hellwig <hc...@in...> > Suggested-by: Linus Torvalds <tor...@li...> > Signed-off-by: Viresh Kumar <vir...@li...> > --- > arch/xtensa/Kconfig | 1 - > arch/xtensa/Makefile | 1 - > arch/xtensa/configs/audio_kc705_defconfig | 1 - > arch/xtensa/configs/generic_kc705_defconfig | 1 - > arch/xtensa/configs/smp_lx200_defconfig | 1 - > arch/xtensa/configs/xip_kc705_defconfig | 1 - > arch/xtensa/kernel/stacktrace.c | 2 +- > arch/xtensa/oprofile/Makefile | 10 -------- > arch/xtensa/oprofile/backtrace.c | 27 --------------------- > arch/xtensa/oprofile/init.c | 26 -------------------- > 10 files changed, 1 insertion(+), 70 deletions(-) > delete mode 100644 arch/xtensa/oprofile/Makefile > delete mode 100644 arch/xtensa/oprofile/backtrace.c > delete mode 100644 arch/xtensa/oprofile/init.c Although I still keep userspace oprofile tools that use this interface, I haven't run them for ages. Acked-by: Max Filippov <jcm...@gm...> -- Thanks. -- Max |
From: Viresh K. <vir...@li...> - 2021-01-14 12:07:30
|
Perfmon support (used by oprofile earlier) was removed by commit ecf5b72d5f66 ("ia64: Remove perfmon") earlier, but it missed few files to remove/update. Clean it up. Suggested-by: Arnd Bergmann <ar...@ke...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/ia64/include/asm/hw_irq.h | 1 - arch/ia64/include/asm/perfmon.h | 111 ------- arch/ia64/include/uapi/asm/perfmon.h | 178 ----------- .../include/uapi/asm/perfmon_default_smpl.h | 84 ----- arch/ia64/kernel/palinfo.c | 41 --- arch/ia64/kernel/perfmon_default_smpl.c | 297 ------------------ arch/ia64/kernel/perfmon_generic.h | 46 --- arch/ia64/kernel/perfmon_itanium.h | 2 +- arch/ia64/kernel/perfmon_mckinley.h | 188 ----------- arch/ia64/kernel/perfmon_montecito.h | 270 ---------------- usr/include/Makefile | 2 - 11 files changed, 1 insertion(+), 1219 deletions(-) delete mode 100644 arch/ia64/include/asm/perfmon.h delete mode 100644 arch/ia64/include/uapi/asm/perfmon.h delete mode 100644 arch/ia64/include/uapi/asm/perfmon_default_smpl.h delete mode 100644 arch/ia64/kernel/perfmon_default_smpl.c delete mode 100644 arch/ia64/kernel/perfmon_generic.h delete mode 100644 arch/ia64/kernel/perfmon_mckinley.h delete mode 100644 arch/ia64/kernel/perfmon_montecito.h diff --git a/arch/ia64/include/asm/hw_irq.h b/arch/ia64/include/asm/hw_irq.h index f6ff95b4ecb1..5d267132f8cb 100644 --- a/arch/ia64/include/asm/hw_irq.h +++ b/arch/ia64/include/asm/hw_irq.h @@ -69,7 +69,6 @@ extern int ia64_last_device_vector; #define IA64_NUM_DEVICE_VECTORS (IA64_LAST_DEVICE_VECTOR - IA64_FIRST_DEVICE_VECTOR + 1) #define IA64_MCA_RENDEZ_VECTOR 0xe8 /* MCA rendez interrupt */ -#define IA64_PERFMON_VECTOR 0xee /* performance monitor interrupt vector */ #define IA64_TIMER_VECTOR 0xef /* use highest-prio group 15 interrupt for timer */ #define IA64_MCA_WAKEUP_VECTOR 0xf0 /* MCA wakeup (must be >MCA_RENDEZ_VECTOR) */ #define IA64_IPI_LOCAL_TLB_FLUSH 0xfc /* SMP flush local TLB */ diff --git a/arch/ia64/include/asm/perfmon.h b/arch/ia64/include/asm/perfmon.h deleted file mode 100644 index e0545869cc8c..000000000000 --- a/arch/ia64/include/asm/perfmon.h +++ /dev/null @@ -1,111 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * Copyright (C) 2001-2003 Hewlett-Packard Co - * Stephane Eranian <er...@hp...> - */ -#ifndef _ASM_IA64_PERFMON_H -#define _ASM_IA64_PERFMON_H - -#include <uapi/asm/perfmon.h> - - -extern long perfmonctl(int fd, int cmd, void *arg, int narg); - -typedef struct { - void (*handler)(int irq, void *arg, struct pt_regs *regs); -} pfm_intr_handler_desc_t; - -extern void pfm_save_regs (struct task_struct *); -extern void pfm_load_regs (struct task_struct *); - -extern void pfm_exit_thread(struct task_struct *); -extern int pfm_use_debug_registers(struct task_struct *); -extern int pfm_release_debug_registers(struct task_struct *); -extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, int is_ctxswin); -extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs); -extern void pfm_init_percpu(void); -extern void pfm_handle_work(void); -extern int pfm_install_alt_pmu_interrupt(pfm_intr_handler_desc_t *h); -extern int pfm_remove_alt_pmu_interrupt(pfm_intr_handler_desc_t *h); - - - -/* - * Reset PMD register flags - */ -#define PFM_PMD_SHORT_RESET 0 -#define PFM_PMD_LONG_RESET 1 - -typedef union { - unsigned int val; - struct { - unsigned int notify_user:1; /* notify user program of overflow */ - unsigned int reset_ovfl_pmds:1; /* reset overflowed PMDs */ - unsigned int block_task:1; /* block monitored task on kernel exit */ - unsigned int mask_monitoring:1; /* mask monitors via PMCx.plm */ - unsigned int reserved:28; /* for future use */ - } bits; -} pfm_ovfl_ctrl_t; - -typedef struct { - unsigned char ovfl_pmd; /* index of overflowed PMD */ - unsigned char ovfl_notify; /* =1 if monitor requested overflow notification */ - unsigned short active_set; /* event set active at the time of the overflow */ - pfm_ovfl_ctrl_t ovfl_ctrl; /* return: perfmon controls to set by handler */ - - unsigned long pmd_last_reset; /* last reset value of of the PMD */ - unsigned long smpl_pmds[4]; /* bitmask of other PMD of interest on overflow */ - unsigned long smpl_pmds_values[PMU_MAX_PMDS]; /* values for the other PMDs of interest */ - unsigned long pmd_value; /* current 64-bit value of the PMD */ - unsigned long pmd_eventid; /* eventid associated with PMD */ -} pfm_ovfl_arg_t; - - -typedef struct { - char *fmt_name; - pfm_uuid_t fmt_uuid; - size_t fmt_arg_size; - unsigned long fmt_flags; - - int (*fmt_validate)(struct task_struct *task, unsigned int flags, int cpu, void *arg); - int (*fmt_getsize)(struct task_struct *task, unsigned int flags, int cpu, void *arg, unsigned long *size); - int (*fmt_init)(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *arg); - int (*fmt_handler)(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs, unsigned long stamp); - int (*fmt_restart)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs); - int (*fmt_restart_active)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs); - int (*fmt_exit)(struct task_struct *task, void *buf, struct pt_regs *regs); - - struct list_head fmt_list; -} pfm_buffer_fmt_t; - -extern int pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt); -extern int pfm_unregister_buffer_fmt(pfm_uuid_t uuid); - -/* - * perfmon interface exported to modules - */ -extern int pfm_mod_read_pmds(struct task_struct *, void *req, unsigned int nreq, struct pt_regs *regs); -extern int pfm_mod_write_pmcs(struct task_struct *, void *req, unsigned int nreq, struct pt_regs *regs); -extern int pfm_mod_write_ibrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs); -extern int pfm_mod_write_dbrs(struct task_struct *task, void *req, unsigned int nreq, struct pt_regs *regs); - -/* - * describe the content of the local_cpu_date->pfm_syst_info field - */ -#define PFM_CPUINFO_SYST_WIDE 0x1 /* if set a system wide session exists */ -#define PFM_CPUINFO_DCR_PP 0x2 /* if set the system wide session has started */ -#define PFM_CPUINFO_EXCL_IDLE 0x4 /* the system wide session excludes the idle task */ - -/* - * sysctl control structure. visible to sampling formats - */ -typedef struct { - int debug; /* turn on/off debugging via syslog */ - int debug_ovfl; /* turn on/off debug printk in overflow handler */ - int fastctxsw; /* turn on/off fast (unsecure) ctxsw */ - int expert_mode; /* turn on/off value checking */ -} pfm_sysctl_t; -extern pfm_sysctl_t pfm_sysctl; - - -#endif /* _ASM_IA64_PERFMON_H */ diff --git a/arch/ia64/include/uapi/asm/perfmon.h b/arch/ia64/include/uapi/asm/perfmon.h deleted file mode 100644 index 017548365e5c..000000000000 --- a/arch/ia64/include/uapi/asm/perfmon.h +++ /dev/null @@ -1,178 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * Copyright (C) 2001-2003 Hewlett-Packard Co - * Stephane Eranian <er...@hp...> - */ - -#ifndef _UAPI_ASM_IA64_PERFMON_H -#define _UAPI_ASM_IA64_PERFMON_H - -/* - * perfmon commands supported on all CPU models - */ -#define PFM_WRITE_PMCS 0x01 -#define PFM_WRITE_PMDS 0x02 -#define PFM_READ_PMDS 0x03 -#define PFM_STOP 0x04 -#define PFM_START 0x05 -#define PFM_ENABLE 0x06 /* obsolete */ -#define PFM_DISABLE 0x07 /* obsolete */ -#define PFM_CREATE_CONTEXT 0x08 -#define PFM_DESTROY_CONTEXT 0x09 /* obsolete use close() */ -#define PFM_RESTART 0x0a -#define PFM_PROTECT_CONTEXT 0x0b /* obsolete */ -#define PFM_GET_FEATURES 0x0c -#define PFM_DEBUG 0x0d -#define PFM_UNPROTECT_CONTEXT 0x0e /* obsolete */ -#define PFM_GET_PMC_RESET_VAL 0x0f -#define PFM_LOAD_CONTEXT 0x10 -#define PFM_UNLOAD_CONTEXT 0x11 - -/* - * PMU model specific commands (may not be supported on all PMU models) - */ -#define PFM_WRITE_IBRS 0x20 -#define PFM_WRITE_DBRS 0x21 - -/* - * context flags - */ -#define PFM_FL_NOTIFY_BLOCK 0x01 /* block task on user level notifications */ -#define PFM_FL_SYSTEM_WIDE 0x02 /* create a system wide context */ -#define PFM_FL_OVFL_NO_MSG 0x80 /* do not post overflow/end messages for notification */ - -/* - * event set flags - */ -#define PFM_SETFL_EXCL_IDLE 0x01 /* exclude idle task (syswide only) XXX: DO NOT USE YET */ - -/* - * PMC flags - */ -#define PFM_REGFL_OVFL_NOTIFY 0x1 /* send notification on overflow */ -#define PFM_REGFL_RANDOM 0x2 /* randomize sampling interval */ - -/* - * PMD/PMC/IBR/DBR return flags (ignored on input) - * - * Those flags are used on output and must be checked in case EAGAIN is returned - * by any of the calls using a pfarg_reg_t or pfarg_dbreg_t structure. - */ -#define PFM_REG_RETFL_NOTAVAIL (1UL<<31) /* set if register is implemented but not available */ -#define PFM_REG_RETFL_EINVAL (1UL<<30) /* set if register entry is invalid */ -#define PFM_REG_RETFL_MASK (PFM_REG_RETFL_NOTAVAIL|PFM_REG_RETFL_EINVAL) - -#define PFM_REG_HAS_ERROR(flag) (((flag) & PFM_REG_RETFL_MASK) != 0) - -typedef unsigned char pfm_uuid_t[16]; /* custom sampling buffer identifier type */ - -/* - * Request structure used to define a context - */ -typedef struct { - pfm_uuid_t ctx_smpl_buf_id; /* which buffer format to use (if needed) */ - unsigned long ctx_flags; /* noblock/block */ - unsigned short ctx_nextra_sets; /* number of extra event sets (you always get 1) */ - unsigned short ctx_reserved1; /* for future use */ - int ctx_fd; /* return arg: unique identification for context */ - void *ctx_smpl_vaddr; /* return arg: virtual address of sampling buffer, is used */ - unsigned long ctx_reserved2[11];/* for future use */ -} pfarg_context_t; - -/* - * Request structure used to write/read a PMC or PMD - */ -typedef struct { - unsigned int reg_num; /* which register */ - unsigned short reg_set; /* event set for this register */ - unsigned short reg_reserved1; /* for future use */ - - unsigned long reg_value; /* initial pmc/pmd value */ - unsigned long reg_flags; /* input: pmc/pmd flags, return: reg error */ - - unsigned long reg_long_reset; /* reset after buffer overflow notification */ - unsigned long reg_short_reset; /* reset after counter overflow */ - - unsigned long reg_reset_pmds[4]; /* which other counters to reset on overflow */ - unsigned long reg_random_seed; /* seed value when randomization is used */ - unsigned long reg_random_mask; /* bitmask used to limit random value */ - unsigned long reg_last_reset_val;/* return: PMD last reset value */ - - unsigned long reg_smpl_pmds[4]; /* which pmds are accessed when PMC overflows */ - unsigned long reg_smpl_eventid; /* opaque sampling event identifier */ - - unsigned long reg_reserved2[3]; /* for future use */ -} pfarg_reg_t; - -typedef struct { - unsigned int dbreg_num; /* which debug register */ - unsigned short dbreg_set; /* event set for this register */ - unsigned short dbreg_reserved1; /* for future use */ - unsigned long dbreg_value; /* value for debug register */ - unsigned long dbreg_flags; /* return: dbreg error */ - unsigned long dbreg_reserved2[1]; /* for future use */ -} pfarg_dbreg_t; - -typedef struct { - unsigned int ft_version; /* perfmon: major [16-31], minor [0-15] */ - unsigned int ft_reserved; /* reserved for future use */ - unsigned long reserved[4]; /* for future use */ -} pfarg_features_t; - -typedef struct { - pid_t load_pid; /* process to load the context into */ - unsigned short load_set; /* first event set to load */ - unsigned short load_reserved1; /* for future use */ - unsigned long load_reserved2[3]; /* for future use */ -} pfarg_load_t; - -typedef struct { - int msg_type; /* generic message header */ - int msg_ctx_fd; /* generic message header */ - unsigned long msg_ovfl_pmds[4]; /* which PMDs overflowed */ - unsigned short msg_active_set; /* active set at the time of overflow */ - unsigned short msg_reserved1; /* for future use */ - unsigned int msg_reserved2; /* for future use */ - unsigned long msg_tstamp; /* for perf tuning/debug */ -} pfm_ovfl_msg_t; - -typedef struct { - int msg_type; /* generic message header */ - int msg_ctx_fd; /* generic message header */ - unsigned long msg_tstamp; /* for perf tuning */ -} pfm_end_msg_t; - -typedef struct { - int msg_type; /* type of the message */ - int msg_ctx_fd; /* unique identifier for the context */ - unsigned long msg_tstamp; /* for perf tuning */ -} pfm_gen_msg_t; - -#define PFM_MSG_OVFL 1 /* an overflow happened */ -#define PFM_MSG_END 2 /* task to which context was attached ended */ - -typedef union { - pfm_ovfl_msg_t pfm_ovfl_msg; - pfm_end_msg_t pfm_end_msg; - pfm_gen_msg_t pfm_gen_msg; -} pfm_msg_t; - -/* - * Define the version numbers for both perfmon as a whole and the sampling buffer format. - */ -#define PFM_VERSION_MAJ 2U -#define PFM_VERSION_MIN 0U -#define PFM_VERSION (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff)) -#define PFM_VERSION_MAJOR(x) (((x)>>16) & 0xffff) -#define PFM_VERSION_MINOR(x) ((x) & 0xffff) - - -/* - * miscellaneous architected definitions - */ -#define PMU_FIRST_COUNTER 4 /* first counting monitor (PMC/PMD) */ -#define PMU_MAX_PMCS 256 /* maximum architected number of PMC registers */ -#define PMU_MAX_PMDS 256 /* maximum architected number of PMD registers */ - - -#endif /* _UAPI_ASM_IA64_PERFMON_H */ diff --git a/arch/ia64/include/uapi/asm/perfmon_default_smpl.h b/arch/ia64/include/uapi/asm/perfmon_default_smpl.h deleted file mode 100644 index d3f36aff0e1f..000000000000 --- a/arch/ia64/include/uapi/asm/perfmon_default_smpl.h +++ /dev/null @@ -1,84 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ -/* - * Copyright (C) 2002-2003 Hewlett-Packard Co - * Stephane Eranian <er...@hp...> - * - * This file implements the default sampling buffer format - * for Linux/ia64 perfmon subsystem. - */ -#ifndef __PERFMON_DEFAULT_SMPL_H__ -#define __PERFMON_DEFAULT_SMPL_H__ 1 - -#define PFM_DEFAULT_SMPL_UUID { \ - 0x4d, 0x72, 0xbe, 0xc0, 0x06, 0x64, 0x41, 0x43, 0x82, 0xb4, 0xd3, 0xfd, 0x27, 0x24, 0x3c, 0x97} - -/* - * format specific parameters (passed at context creation) - */ -typedef struct { - unsigned long buf_size; /* size of the buffer in bytes */ - unsigned int flags; /* buffer specific flags */ - unsigned int res1; /* for future use */ - unsigned long reserved[2]; /* for future use */ -} pfm_default_smpl_arg_t; - -/* - * combined context+format specific structure. Can be passed - * to PFM_CONTEXT_CREATE - */ -typedef struct { - pfarg_context_t ctx_arg; - pfm_default_smpl_arg_t buf_arg; -} pfm_default_smpl_ctx_arg_t; - -/* - * This header is at the beginning of the sampling buffer returned to the user. - * It is directly followed by the first record. - */ -typedef struct { - unsigned long hdr_count; /* how many valid entries */ - unsigned long hdr_cur_offs; /* current offset from top of buffer */ - unsigned long hdr_reserved2; /* reserved for future use */ - - unsigned long hdr_overflows; /* how many times the buffer overflowed */ - unsigned long hdr_buf_size; /* how many bytes in the buffer */ - - unsigned int hdr_version; /* contains perfmon version (smpl format diffs) */ - unsigned int hdr_reserved1; /* for future use */ - unsigned long hdr_reserved[10]; /* for future use */ -} pfm_default_smpl_hdr_t; - -/* - * Entry header in the sampling buffer. The header is directly followed - * with the values of the PMD registers of interest saved in increasing - * index order: PMD4, PMD5, and so on. How many PMDs are present depends - * on how the session was programmed. - * - * In the case where multiple counters overflow at the same time, multiple - * entries are written consecutively. - * - * last_reset_value member indicates the initial value of the overflowed PMD. - */ -typedef struct { - int pid; /* thread id (for NPTL, this is gettid()) */ - unsigned char reserved1[3]; /* reserved for future use */ - unsigned char ovfl_pmd; /* index of overflowed PMD */ - - unsigned long last_reset_val; /* initial value of overflowed PMD */ - unsigned long ip; /* where did the overflow interrupt happened */ - unsigned long tstamp; /* ar.itc when entering perfmon intr. handler */ - - unsigned short cpu; /* cpu on which the overflow occurred */ - unsigned short set; /* event set active when overflow occurred */ - int tgid; /* thread group id (for NPTL, this is getpid()) */ -} pfm_default_smpl_entry_t; - -#define PFM_DEFAULT_MAX_PMDS 64 /* how many pmds supported by data structures (sizeof(unsigned long) */ -#define PFM_DEFAULT_MAX_ENTRY_SIZE (sizeof(pfm_default_smpl_entry_t)+(sizeof(unsigned long)*PFM_DEFAULT_MAX_PMDS)) -#define PFM_DEFAULT_SMPL_MIN_BUF_SIZE (sizeof(pfm_default_smpl_hdr_t)+PFM_DEFAULT_MAX_ENTRY_SIZE) - -#define PFM_DEFAULT_SMPL_VERSION_MAJ 2U -#define PFM_DEFAULT_SMPL_VERSION_MIN 0U -#define PFM_DEFAULT_SMPL_VERSION (((PFM_DEFAULT_SMPL_VERSION_MAJ&0xffff)<<16)|(PFM_DEFAULT_SMPL_VERSION_MIN & 0xffff)) - -#endif /* __PERFMON_DEFAULT_SMPL_H__ */ diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 78fa6579c9ea..64189f04c1a4 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c @@ -648,46 +648,6 @@ static int version_info(struct seq_file *m) return 0; } -static int perfmon_info(struct seq_file *m) -{ - u64 pm_buffer[16]; - pal_perf_mon_info_u_t pm_info; - - if (ia64_pal_perf_mon_info(pm_buffer, &pm_info) != 0) - return 0; - - seq_printf(m, - "PMC/PMD pairs : %d\n" - "Counter width : %d bits\n" - "Cycle event number : %d\n" - "Retired event number : %d\n" - "Implemented PMC : ", - pm_info.pal_perf_mon_info_s.generic, - pm_info.pal_perf_mon_info_s.width, - pm_info.pal_perf_mon_info_s.cycles, - pm_info.pal_perf_mon_info_s.retired); - - bitregister_process(m, pm_buffer, 256); - seq_puts(m, "\nImplemented PMD : "); - bitregister_process(m, pm_buffer+4, 256); - seq_puts(m, "\nCycles count capable : "); - bitregister_process(m, pm_buffer+8, 256); - seq_puts(m, "\nRetired bundles count capable : "); - -#ifdef CONFIG_ITANIUM - /* - * PAL_PERF_MON_INFO reports that only PMC4 can be used to count CPU_CYCLES - * which is wrong, both PMC4 and PMD5 support it. - */ - if (pm_buffer[12] == 0x10) - pm_buffer[12]=0x30; -#endif - - bitregister_process(m, pm_buffer+12, 256); - seq_putc(m, '\n'); - return 0; -} - static int frequency_info(struct seq_file *m) { struct pal_freq_ratio proc, itc, bus; @@ -816,7 +776,6 @@ static const palinfo_entry_t palinfo_entries[]={ { "power_info", power_info, }, { "register_info", register_info, }, { "processor_info", processor_info, }, - { "perfmon_info", perfmon_info, }, { "frequency_info", frequency_info, }, { "bus_info", bus_info }, { "tr_info", tr_info, } diff --git a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c deleted file mode 100644 index a40c56020fc5..000000000000 --- a/arch/ia64/kernel/perfmon_default_smpl.c +++ /dev/null @@ -1,297 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2002-2003 Hewlett-Packard Co - * Stephane Eranian <er...@hp...> - * - * This file implements the default sampling buffer format - * for the Linux/ia64 perfmon-2 subsystem. - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/module.h> -#include <linux/init.h> -#include <asm/delay.h> -#include <linux/smp.h> - -#include <asm/perfmon.h> -#include <asm/perfmon_default_smpl.h> - -MODULE_AUTHOR("Stephane Eranian <er...@hp...>"); -MODULE_DESCRIPTION("perfmon default sampling format"); -MODULE_LICENSE("GPL"); - -#define DEFAULT_DEBUG 1 - -#ifdef DEFAULT_DEBUG -#define DPRINT(a) \ - do { \ - if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \ - } while (0) - -#define DPRINT_ovfl(a) \ - do { \ - if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d ", __func__, __LINE__, smp_processor_id()); printk a; } \ - } while (0) - -#else -#define DPRINT(a) -#define DPRINT_ovfl(a) -#endif - -static int -default_validate(struct task_struct *task, unsigned int flags, int cpu, void *data) -{ - pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t*)data; - int ret = 0; - - if (data == NULL) { - DPRINT(("[%d] no argument passed\n", task_pid_nr(task))); - return -EINVAL; - } - - DPRINT(("[%d] validate flags=0x%x CPU%d\n", task_pid_nr(task), flags, cpu)); - - /* - * must hold at least the buffer header + one minimally sized entry - */ - if (arg->buf_size < PFM_DEFAULT_SMPL_MIN_BUF_SIZE) return -EINVAL; - - DPRINT(("buf_size=%lu\n", arg->buf_size)); - - return ret; -} - -static int -default_get_size(struct task_struct *task, unsigned int flags, int cpu, void *data, unsigned long *size) -{ - pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data; - - /* - * size has been validated in default_validate - */ - *size = arg->buf_size; - - return 0; -} - -static int -default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *data) -{ - pfm_default_smpl_hdr_t *hdr; - pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data; - - hdr = (pfm_default_smpl_hdr_t *)buf; - - hdr->hdr_version = PFM_DEFAULT_SMPL_VERSION; - hdr->hdr_buf_size = arg->buf_size; - hdr->hdr_cur_offs = sizeof(*hdr); - hdr->hdr_overflows = 0UL; - hdr->hdr_count = 0UL; - - DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u cur_offs=%lu\n", - task_pid_nr(task), - buf, - hdr->hdr_buf_size, - sizeof(*hdr), - hdr->hdr_version, - hdr->hdr_cur_offs)); - - return 0; -} - -static int -default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs, unsigned long stamp) -{ - pfm_default_smpl_hdr_t *hdr; - pfm_default_smpl_entry_t *ent; - void *cur, *last; - unsigned long *e, entry_size; - unsigned int npmds, i; - unsigned char ovfl_pmd; - unsigned char ovfl_notify; - - if (unlikely(buf == NULL || arg == NULL|| regs == NULL || task == NULL)) { - DPRINT(("[%d] invalid arguments buf=%p arg=%p\n", task->pid, buf, arg)); - return -EINVAL; - } - - hdr = (pfm_default_smpl_hdr_t *)buf; - cur = buf+hdr->hdr_cur_offs; - last = buf+hdr->hdr_buf_size; - ovfl_pmd = arg->ovfl_pmd; - ovfl_notify = arg->ovfl_notify; - - /* - * precheck for sanity - */ - if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full; - - npmds = hweight64(arg->smpl_pmds[0]); - - ent = (pfm_default_smpl_entry_t *)cur; - - prefetch(arg->smpl_pmds_values); - - entry_size = sizeof(*ent) + (npmds << 3); - - /* position for first pmd */ - e = (unsigned long *)(ent+1); - - hdr->hdr_count++; - - DPRINT_ovfl(("[%d] count=%lu cur=%p last=%p free_bytes=%lu ovfl_pmd=%d ovfl_notify=%d npmds=%u\n", - task->pid, - hdr->hdr_count, - cur, last, - last-cur, - ovfl_pmd, - ovfl_notify, npmds)); - - /* - * current = task running at the time of the overflow. - * - * per-task mode: - * - this is usually the task being monitored. - * Under certain conditions, it might be a different task - * - * system-wide: - * - this is not necessarily the task controlling the session - */ - ent->pid = current->pid; - ent->ovfl_pmd = ovfl_pmd; - ent->last_reset_val = arg->pmd_last_reset; //pmd[0].reg_last_reset_val; - - /* - * where did the fault happen (includes slot number) - */ - ent->ip = regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3); - - ent->tstamp = stamp; - ent->cpu = smp_processor_id(); - ent->set = arg->active_set; - ent->tgid = current->tgid; - - /* - * selectively store PMDs in increasing index number - */ - if (npmds) { - unsigned long *val = arg->smpl_pmds_values; - for(i=0; i < npmds; i++) { - *e++ = *val++; - } - } - - /* - * update position for next entry - */ - hdr->hdr_cur_offs += entry_size; - cur += entry_size; - - /* - * post check to avoid losing the last sample - */ - if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full; - - /* - * keep same ovfl_pmds, ovfl_notify - */ - arg->ovfl_ctrl.bits.notify_user = 0; - arg->ovfl_ctrl.bits.block_task = 0; - arg->ovfl_ctrl.bits.mask_monitoring = 0; - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 1; /* reset before returning from interrupt handler */ - - return 0; -full: - DPRINT_ovfl(("sampling buffer full free=%lu, count=%lu, ovfl_notify=%d\n", last-cur, hdr->hdr_count, ovfl_notify)); - - /* - * increment number of buffer overflow. - * important to detect duplicate set of samples. - */ - hdr->hdr_overflows++; - - /* - * if no notification requested, then we saturate the buffer - */ - if (ovfl_notify == 0) { - arg->ovfl_ctrl.bits.notify_user = 0; - arg->ovfl_ctrl.bits.block_task = 0; - arg->ovfl_ctrl.bits.mask_monitoring = 1; - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 0; - } else { - arg->ovfl_ctrl.bits.notify_user = 1; - arg->ovfl_ctrl.bits.block_task = 1; /* ignored for non-blocking context */ - arg->ovfl_ctrl.bits.mask_monitoring = 1; - arg->ovfl_ctrl.bits.reset_ovfl_pmds = 0; /* no reset now */ - } - return -1; /* we are full, sorry */ -} - -static int -default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs) -{ - pfm_default_smpl_hdr_t *hdr; - - hdr = (pfm_default_smpl_hdr_t *)buf; - - hdr->hdr_count = 0UL; - hdr->hdr_cur_offs = sizeof(*hdr); - - ctrl->bits.mask_monitoring = 0; - ctrl->bits.reset_ovfl_pmds = 1; /* uses long-reset values */ - - return 0; -} - -static int -default_exit(struct task_struct *task, void *buf, struct pt_regs *regs) -{ - DPRINT(("[%d] exit(%p)\n", task_pid_nr(task), buf)); - return 0; -} - -static pfm_buffer_fmt_t default_fmt={ - .fmt_name = "default_format", - .fmt_uuid = PFM_DEFAULT_SMPL_UUID, - .fmt_arg_size = sizeof(pfm_default_smpl_arg_t), - .fmt_validate = default_validate, - .fmt_getsize = default_get_size, - .fmt_init = default_init, - .fmt_handler = default_handler, - .fmt_restart = default_restart, - .fmt_restart_active = default_restart, - .fmt_exit = default_exit, -}; - -static int __init -pfm_default_smpl_init_module(void) -{ - int ret; - - ret = pfm_register_buffer_fmt(&default_fmt); - if (ret == 0) { - printk("perfmon_default_smpl: %s v%u.%u registered\n", - default_fmt.fmt_name, - PFM_DEFAULT_SMPL_VERSION_MAJ, - PFM_DEFAULT_SMPL_VERSION_MIN); - } else { - printk("perfmon_default_smpl: %s cannot register ret=%d\n", - default_fmt.fmt_name, - ret); - } - - return ret; -} - -static void __exit -pfm_default_smpl_cleanup_module(void) -{ - int ret; - ret = pfm_unregister_buffer_fmt(default_fmt.fmt_uuid); - - printk("perfmon_default_smpl: unregister %s=%d\n", default_fmt.fmt_name, ret); -} - -module_init(pfm_default_smpl_init_module); -module_exit(pfm_default_smpl_cleanup_module); - diff --git a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h deleted file mode 100644 index 96af4696cea9..000000000000 --- a/arch/ia64/kernel/perfmon_generic.h +++ /dev/null @@ -1,46 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This file contains the generic PMU register description tables - * and pmc checker used by perfmon.c. - * - * Copyright (C) 2002-2003 Hewlett Packard Co - * Stephane Eranian <er...@hp...> - */ - -static pfm_reg_desc_t pfm_gen_pmc_desc[PMU_MAX_PMCS]={ -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -static pfm_reg_desc_t pfm_gen_pmd_desc[PMU_MAX_PMDS]={ -/* pmd0 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, -/* pmd1 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, -/* pmd2 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, -/* pmd3 */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, -/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}}, -/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}}, -/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}}, -/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -/* - * impl_pmcs, impl_pmds are computed at runtime to minimize errors! - */ -static pmu_config_t pmu_conf_gen={ - .pmu_name = "Generic", - .pmu_family = 0xff, /* any */ - .ovfl_val = (1UL << 32) - 1, - .num_ibrs = 0, /* does not use */ - .num_dbrs = 0, /* does not use */ - .pmd_desc = pfm_gen_pmd_desc, - .pmc_desc = pfm_gen_pmc_desc -}; - diff --git a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h index f2d348648a03..dbd04028aafa 100644 --- a/arch/ia64/kernel/perfmon_itanium.h +++ b/arch/ia64/kernel/perfmon_itanium.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0 */ /* * This file contains the Itanium PMU register description tables - * and pmc checker used by perfmon.c. + * and pmc checker. * * Copyright (C) 2002-2003 Hewlett Packard Co * Stephane Eranian <er...@hp...> diff --git a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h deleted file mode 100644 index a993249e58bc..000000000000 --- a/arch/ia64/kernel/perfmon_mckinley.h +++ /dev/null @@ -1,188 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This file contains the McKinley PMU register description tables - * and pmc checker used by perfmon.c. - * - * Copyright (C) 2002-2003 Hewlett Packard Co - * Stephane Eranian <er...@hp...> - */ -static int pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); - -static pfm_reg_desc_t pfm_mck_pmc_desc[PMU_MAX_PMCS]={ -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc4 */ { PFM_REG_COUNTING, 6, 0x0000000000800000UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc5 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc6 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc7 */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc8 */ { PFM_REG_CONFIG , 0, 0xffffffff3fffffffUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc9 */ { PFM_REG_CONFIG , 0, 0xffffffff3ffffffcUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_pmc_check, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc11 */ { PFM_REG_MONITOR , 6, 0x0UL, 0x30f01cf, NULL, pfm_mck_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, 0xffffUL, NULL, pfm_mck_pmc_check, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc13 */ { PFM_REG_CONFIG , 0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc14 */ { PFM_REG_CONFIG , 0, 0x0db60db60db60db6UL, 0x2492UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, -/* pmc15 */ { PFM_REG_CONFIG , 0, 0x00000000fffffff0UL, 0xfUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -static pfm_reg_desc_t pfm_mck_pmd_desc[PMU_MAX_PMDS]={ -/* pmd0 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(1),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}}, -/* pmd1 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(0),0UL, 0UL, 0UL}, {RDEP(10),0UL, 0UL, 0UL}}, -/* pmd2 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}}, -/* pmd3 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(17),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}}, -/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(4),0UL, 0UL, 0UL}}, -/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(5),0UL, 0UL, 0UL}}, -/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(6),0UL, 0UL, 0UL}}, -/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {RDEP(7),0UL, 0UL, 0UL}}, -/* pmd8 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd9 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd10 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd11 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd12 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd13 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd14 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd15 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(16),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd16 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15),0UL, 0UL, 0UL}, {RDEP(12),0UL, 0UL, 0UL}}, -/* pmd17 */ { PFM_REG_BUFFER , 0, 0x0UL, -1UL, NULL, NULL, {RDEP(2)|RDEP(3),0UL, 0UL, 0UL}, {RDEP(11),0UL, 0UL, 0UL}}, - { PFM_REG_END , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -/* - * PMC reserved fields must have their power-up values preserved - */ -static int -pfm_mck_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs) -{ - unsigned long tmp1, tmp2, ival = *val; - - /* remove reserved areas from user value */ - tmp1 = ival & PMC_RSVD_MASK(cnum); - - /* get reserved fields values */ - tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum); - - *val = tmp1 | tmp2; - - DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n", - cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val)); - return 0; -} - -/* - * task can be NULL if the context is unloaded - */ -static int -pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs) -{ - int ret = 0, check_case1 = 0; - unsigned long val8 = 0, val14 = 0, val13 = 0; - int is_loaded; - - /* first preserve the reserved fields */ - pfm_mck_reserved(cnum, val, regs); - - /* sanitfy check */ - if (ctx == NULL) return -EINVAL; - - is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED; - - /* - * we must clear the debug registers if pmc13 has a value which enable - * memory pipeline event constraints. In this case we need to clear the - * the debug registers if they have not yet been accessed. This is required - * to avoid picking stale state. - * PMC13 is "active" if: - * one of the pmc13.cfg_dbrpXX field is different from 0x3 - * AND - * at the corresponding pmc13.ena_dbrpXX is set. - */ - DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, *val, ctx->ctx_fl_using_dbreg, is_loaded)); - - if (cnum == 13 && is_loaded - && (*val & 0x1e00000000000UL) && (*val & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) { - - DPRINT(("pmc[%d]=0x%lx has active pmc13 settings, clearing dbr\n", cnum, *val)); - - /* don't mix debug with perfmon */ - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; - - /* - * a count of 0 will mark the debug registers as in use and also - * ensure that they are properly cleared. - */ - ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs); - if (ret) return ret; - } - /* - * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled - * before they are (fl_using_dbreg==0) to avoid picking up stale information. - */ - if (cnum == 14 && is_loaded && ((*val & 0x2222UL) != 0x2222UL) && ctx->ctx_fl_using_dbreg == 0) { - - DPRINT(("pmc[%d]=0x%lx has active pmc14 settings, clearing ibr\n", cnum, *val)); - - /* don't mix debug with perfmon */ - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; - - /* - * a count of 0 will mark the debug registers as in use and also - * ensure that they are properly cleared. - */ - ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs); - if (ret) return ret; - - } - - switch(cnum) { - case 4: *val |= 1UL << 23; /* force power enable bit */ - break; - case 8: val8 = *val; - val13 = ctx->ctx_pmcs[13]; - val14 = ctx->ctx_pmcs[14]; - check_case1 = 1; - break; - case 13: val8 = ctx->ctx_pmcs[8]; - val13 = *val; - val14 = ctx->ctx_pmcs[14]; - check_case1 = 1; - break; - case 14: val8 = ctx->ctx_pmcs[8]; - val13 = ctx->ctx_pmcs[13]; - val14 = *val; - check_case1 = 1; - break; - } - /* check illegal configuration which can produce inconsistencies in tagging - * i-side events in L1D and L2 caches - */ - if (check_case1) { - ret = ((val13 >> 45) & 0xf) == 0 - && ((val8 & 0x1) == 0) - && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0) - ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0)); - - if (ret) DPRINT((KERN_DEBUG "perfmon: failure check_case1\n")); - } - - return ret ? -EINVAL : 0; -} - -/* - * impl_pmcs, impl_pmds are computed at runtime to minimize errors! - */ -static pmu_config_t pmu_conf_mck={ - .pmu_name = "Itanium 2", - .pmu_family = 0x1f, - .flags = PFM_PMU_IRQ_RESEND, - .ovfl_val = (1UL << 47) - 1, - .pmd_desc = pfm_mck_pmd_desc, - .pmc_desc = pfm_mck_pmc_desc, - .num_ibrs = 8, - .num_dbrs = 8, - .use_rr_dbregs = 1 /* debug register are use for range restrictions */ -}; - - diff --git a/arch/ia64/kernel/perfmon_montecito.h b/arch/ia64/kernel/perfmon_montecito.h deleted file mode 100644 index c0b5b9110c88..000000000000 --- a/arch/ia64/kernel/perfmon_montecito.h +++ /dev/null @@ -1,270 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * This file contains the Montecito PMU register description tables - * and pmc checker used by perfmon.c. - * - * Copyright (c) 2005-2006 Hewlett-Packard Development Company, L.P. - * Contributed by Stephane Eranian <er...@hp...> - */ -static int pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs); - -#define RDEP_MONT_ETB (RDEP(38)|RDEP(39)|RDEP(48)|RDEP(49)|RDEP(50)|RDEP(51)|RDEP(52)|RDEP(53)|RDEP(54)|\ - RDEP(55)|RDEP(56)|RDEP(57)|RDEP(58)|RDEP(59)|RDEP(60)|RDEP(61)|RDEP(62)|RDEP(63)) -#define RDEP_MONT_DEAR (RDEP(32)|RDEP(33)|RDEP(36)) -#define RDEP_MONT_IEAR (RDEP(34)|RDEP(35)) - -static pfm_reg_desc_t pfm_mont_pmc_desc[PMU_MAX_PMCS]={ -/* pmc0 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc1 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc2 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc3 */ { PFM_REG_CONTROL , 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc4 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(4),0, 0, 0}, {0,0, 0, 0}}, -/* pmc5 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(5),0, 0, 0}, {0,0, 0, 0}}, -/* pmc6 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(6),0, 0, 0}, {0,0, 0, 0}}, -/* pmc7 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(7),0, 0, 0}, {0,0, 0, 0}}, -/* pmc8 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(8),0, 0, 0}, {0,0, 0, 0}}, -/* pmc9 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(9),0, 0, 0}, {0,0, 0, 0}}, -/* pmc10 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(10),0, 0, 0}, {0,0, 0, 0}}, -/* pmc11 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(11),0, 0, 0}, {0,0, 0, 0}}, -/* pmc12 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(12),0, 0, 0}, {0,0, 0, 0}}, -/* pmc13 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(13),0, 0, 0}, {0,0, 0, 0}}, -/* pmc14 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(14),0, 0, 0}, {0,0, 0, 0}}, -/* pmc15 */ { PFM_REG_COUNTING, 6, 0x2000000, 0x7c7fff7f, NULL, pfm_mont_pmc_check, {RDEP(15),0, 0, 0}, {0,0, 0, 0}}, -/* pmc16 */ { PFM_REG_NOTIMPL, }, -/* pmc17 */ { PFM_REG_NOTIMPL, }, -/* pmc18 */ { PFM_REG_NOTIMPL, }, -/* pmc19 */ { PFM_REG_NOTIMPL, }, -/* pmc20 */ { PFM_REG_NOTIMPL, }, -/* pmc21 */ { PFM_REG_NOTIMPL, }, -/* pmc22 */ { PFM_REG_NOTIMPL, }, -/* pmc23 */ { PFM_REG_NOTIMPL, }, -/* pmc24 */ { PFM_REG_NOTIMPL, }, -/* pmc25 */ { PFM_REG_NOTIMPL, }, -/* pmc26 */ { PFM_REG_NOTIMPL, }, -/* pmc27 */ { PFM_REG_NOTIMPL, }, -/* pmc28 */ { PFM_REG_NOTIMPL, }, -/* pmc29 */ { PFM_REG_NOTIMPL, }, -/* pmc30 */ { PFM_REG_NOTIMPL, }, -/* pmc31 */ { PFM_REG_NOTIMPL, }, -/* pmc32 */ { PFM_REG_CONFIG, 0, 0x30f01ffffffffffUL, 0x30f01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc33 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc34 */ { PFM_REG_CONFIG, 0, 0xf01ffffffffffUL, 0xf01ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc35 */ { PFM_REG_CONFIG, 0, 0x0, 0x1ffffffffffUL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc36 */ { PFM_REG_CONFIG, 0, 0xfffffff0, 0xf, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc37 */ { PFM_REG_MONITOR, 4, 0x0, 0x3fff, NULL, pfm_mont_pmc_check, {RDEP_MONT_IEAR, 0, 0, 0}, {0, 0, 0, 0}}, -/* pmc38 */ { PFM_REG_CONFIG, 0, 0xdb6, 0x2492, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc39 */ { PFM_REG_MONITOR, 6, 0x0, 0xffcf, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, -/* pmc40 */ { PFM_REG_MONITOR, 6, 0x2000000, 0xf01cf, NULL, pfm_mont_pmc_check, {RDEP_MONT_DEAR,0, 0, 0}, {0,0, 0, 0}}, -/* pmc41 */ { PFM_REG_CONFIG, 0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mont_pmc_check, {0,0, 0, 0}, {0,0, 0, 0}}, -/* pmc42 */ { PFM_REG_MONITOR, 6, 0x0, 0x7ff4f, NULL, pfm_mont_pmc_check, {RDEP_MONT_ETB,0, 0, 0}, {0,0, 0, 0}}, - { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -static pfm_reg_desc_t pfm_mont_pmd_desc[PMU_MAX_PMDS]={ -/* pmd0 */ { PFM_REG_NOTIMPL, }, -/* pmd1 */ { PFM_REG_NOTIMPL, }, -/* pmd2 */ { PFM_REG_NOTIMPL, }, -/* pmd3 */ { PFM_REG_NOTIMPL, }, -/* pmd4 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(4),0, 0, 0}}, -/* pmd5 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(5),0, 0, 0}}, -/* pmd6 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(6),0, 0, 0}}, -/* pmd7 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(7),0, 0, 0}}, -/* pmd8 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(8),0, 0, 0}}, -/* pmd9 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(9),0, 0, 0}}, -/* pmd10 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(10),0, 0, 0}}, -/* pmd11 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(11),0, 0, 0}}, -/* pmd12 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(12),0, 0, 0}}, -/* pmd13 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(13),0, 0, 0}}, -/* pmd14 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(14),0, 0, 0}}, -/* pmd15 */ { PFM_REG_COUNTING, 0, 0x0, -1, NULL, NULL, {0,0, 0, 0}, {RDEP(15),0, 0, 0}}, -/* pmd16 */ { PFM_REG_NOTIMPL, }, -/* pmd17 */ { PFM_REG_NOTIMPL, }, -/* pmd18 */ { PFM_REG_NOTIMPL, }, -/* pmd19 */ { PFM_REG_NOTIMPL, }, -/* pmd20 */ { PFM_REG_NOTIMPL, }, -/* pmd21 */ { PFM_REG_NOTIMPL, }, -/* pmd22 */ { PFM_REG_NOTIMPL, }, -/* pmd23 */ { PFM_REG_NOTIMPL, }, -/* pmd24 */ { PFM_REG_NOTIMPL, }, -/* pmd25 */ { PFM_REG_NOTIMPL, }, -/* pmd26 */ { PFM_REG_NOTIMPL, }, -/* pmd27 */ { PFM_REG_NOTIMPL, }, -/* pmd28 */ { PFM_REG_NOTIMPL, }, -/* pmd29 */ { PFM_REG_NOTIMPL, }, -/* pmd30 */ { PFM_REG_NOTIMPL, }, -/* pmd31 */ { PFM_REG_NOTIMPL, }, -/* pmd32 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(33)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}}, -/* pmd33 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(36),0, 0, 0}, {RDEP(40),0, 0, 0}}, -/* pmd34 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(35),0, 0, 0}, {RDEP(37),0, 0, 0}}, -/* pmd35 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(34),0, 0, 0}, {RDEP(37),0, 0, 0}}, -/* pmd36 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP(32)|RDEP(33),0, 0, 0}, {RDEP(40),0, 0, 0}}, -/* pmd37 */ { PFM_REG_NOTIMPL, }, -/* pmd38 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd39 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd40 */ { PFM_REG_NOTIMPL, }, -/* pmd41 */ { PFM_REG_NOTIMPL, }, -/* pmd42 */ { PFM_REG_NOTIMPL, }, -/* pmd43 */ { PFM_REG_NOTIMPL, }, -/* pmd44 */ { PFM_REG_NOTIMPL, }, -/* pmd45 */ { PFM_REG_NOTIMPL, }, -/* pmd46 */ { PFM_REG_NOTIMPL, }, -/* pmd47 */ { PFM_REG_NOTIMPL, }, -/* pmd48 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd49 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd50 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd51 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd52 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd53 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd54 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd55 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd56 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd57 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd58 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd59 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd60 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd61 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd62 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, -/* pmd63 */ { PFM_REG_BUFFER, 0, 0x0, -1, NULL, NULL, {RDEP_MONT_ETB,0, 0, 0}, {RDEP(39),0, 0, 0}}, - { PFM_REG_END , 0, 0x0, -1, NULL, NULL, {0,}, {0,}}, /* end marker */ -}; - -/* - * PMC reserved fields must have their power-up values preserved - */ -static int -pfm_mont_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs) -{ - unsigned long tmp1, tmp2, ival = *val; - - /* remove reserved areas from user value */ - tmp1 = ival & PMC_RSVD_MASK(cnum); - - /* get reserved fields values */ - tmp2 = PMC_DFL_VAL(cnum) & ~PMC_RSVD_MASK(cnum); - - *val = tmp1 | tmp2; - - DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n", - cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val)); - return 0; -} - -/* - * task can be NULL if the context is unloaded - */ -static int -pfm_mont_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs) -{ - int ret = 0; - unsigned long val32 = 0, val38 = 0, val41 = 0; - unsigned long tmpval; - int check_case1 = 0; - int is_loaded; - - /* first preserve the reserved fields */ - pfm_mont_reserved(cnum, val, regs); - - tmpval = *val; - - /* sanity check */ - if (ctx == NULL) return -EINVAL; - - is_loaded = ctx->ctx_state == PFM_CTX_LOADED || ctx->ctx_state == PFM_CTX_MASKED; - - /* - * we must clear the debug registers if pmc41 has a value which enable - * memory pipeline event constraints. In this case we need to clear the - * the debug registers if they have not yet been accessed. This is required - * to avoid picking stale state. - * PMC41 is "active" if: - * one of the pmc41.cfg_dtagXX field is different from 0x3 - * AND - * at the corresponding pmc41.en_dbrpXX is set. - * AND - * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used) - */ - DPRINT(("cnum=%u val=0x%lx, using_dbreg=%d loaded=%d\n", cnum, tmpval, ctx->ctx_fl_using_dbreg, is_loaded)); - - if (cnum == 41 && is_loaded - && (tmpval & 0x1e00000000000UL) && (tmpval & 0x18181818UL) != 0x18181818UL && ctx->ctx_fl_using_dbreg == 0) { - - DPRINT(("pmc[%d]=0x%lx has active pmc41 settings, clearing dbr\n", cnum, tmpval)); - - /* don't mix debug with perfmon */ - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; - - /* - * a count of 0 will mark the debug registers if: - * AND - */ - ret = pfm_write_ibr_dbr(PFM_DATA_RR, ctx, NULL, 0, regs); - if (ret) return ret; - } - /* - * we must clear the (instruction) debug registers if: - * pmc38.ig_ibrpX is 0 (enabled) - * AND - * ctx_fl_using_dbreg == 0 (i.e., dbr not yet used) - */ - if (cnum == 38 && is_loaded && ((tmpval & 0x492UL) != 0x492UL) && ctx->ctx_fl_using_dbreg == 0) { - - DPRINT(("pmc38=0x%lx has active pmc38 settings, clearing ibr\n", tmpval)); - - /* don't mix debug with perfmon */ - if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL; - - /* - * a count of 0 will mark the debug registers as in use and also - * ensure that they are properly cleared. - */ - ret = pfm_write_ibr_dbr(PFM_CODE_RR, ctx, NULL, 0, regs); - if (ret) return ret; - - } - switch(cnum) { - case 32: val32 = *val; - val38 = ctx->ctx_pmcs[38]; - val41 = ctx->ctx_pmcs[41]; - check_case1 = 1; - break; - case 38: val38 = *val; - val32 = ctx->ctx_pmcs[32]; - val41 = ctx->ctx_pmcs[41]; - check_case1 = 1; - break; - case 41: val41 = *val; - val32 = ctx->ctx_pmcs[32]; - val38 = ctx->ctx_pmcs[38]; - check_case1 = 1; - break; - } - /* check illegal configuration which can produce inconsistencies in tagging - * i-side events in L1D and L2 caches - */ - if (check_case1) { - ret = (((val41 >> 45) & 0xf) == 0 && ((val32>>57) & 0x1) == 0) - && ((((val38>>1) & 0x3) == 0x2 || ((val38>>1) & 0x3) == 0) - || (((val38>>4) & 0x3) == 0x2 || ((val38>>4) & 0x3) == 0)); - if (ret) { - DPRINT(("invalid config pmc38=0x%lx pmc41=0x%lx pmc32=0x%lx\n", val38, val41, val32)); - return -EINVAL; - } - } - *val = tmpval; - return 0; -} - -/* - * impl_pmcs, impl_pmds are computed at runtime to minimize errors! - */ -static pmu_config_t pmu_conf_mont={ - .pmu_name = "Montecito", - .pmu_family = 0x20, - .flags = PFM_PMU_IRQ_RESEND, - .ovfl_val = (1UL << 47) - 1, - .pmd_desc = pfm_mont_pmd_desc, - .pmc_desc = pfm_mont_pmc_desc, - .num_ibrs = 8, - .num_dbrs = 8, - .use_rr_dbregs = 1 /* debug register are use for range retrictions */ -}; diff --git a/usr/include/Makefile b/usr/include/Makefile index f6b3c85d900e..1c2ae1368079 100644 --- a/usr/include/Makefile +++ b/usr/include/Makefile @@ -67,8 +67,6 @@ endif ifeq ($(SRCARCH),ia64) no-header-test += asm/setup.h no-header-test += asm/sigcontext.h -no-header-test += asm/perfmon.h -no-header-test += asm/perfmon_default_smpl.h no-header-test += linux/if_bonding.h endif -- 2.25.0.rc1.19.g042ed3e048af |
From: Viresh K. <vir...@li...> - 2021-01-14 12:07:38
|
The "oprofile" user-space tools don't use the kernel OPROFILE support any more, and haven't in a long time. User-space has been converted to the perf interfaces. Remove the old oprofile's architecture specific support. Suggested-by: Christoph Hellwig <hc...@in...> Suggested-by: Linus Torvalds <tor...@li...> Signed-off-by: Viresh Kumar <vir...@li...> --- arch/s390/Kconfig | 1 - arch/s390/Makefile | 3 --- arch/s390/configs/debug_defconfig | 1 - arch/s390/configs/defconfig | 1 - arch/s390/oprofile/Makefile | 10 --------- arch/s390/oprofile/init.c | 37 ------------------------------- 6 files changed, 53 deletions(-) delete mode 100644 arch/s390/oprofile/Makefile delete mode 100644 arch/s390/oprofile/init.c diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index c72874f09741..f84444ef3860 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig @@ -174,7 +174,6 @@ config S390 select HAVE_MOD_ARCH_SPECIFIC select HAVE_NMI select HAVE_NOP_MCOUNT - select HAVE_OPROFILE select HAVE_PCI select HAVE_PERF_EVENTS select HAVE_PERF_REGS diff --git a/arch/s390/Makefile b/arch/s390/Makefile index 8db267d2a543..e443ed9947bd 100644 --- a/arch/s390/Makefile +++ b/arch/s390/Makefile @@ -134,9 +134,6 @@ core-y += arch/s390/ libs-y += arch/s390/lib/ drivers-y += drivers/s390/ -# must be linked after kernel -drivers-$(CONFIG_OPROFILE) += arch/s390/oprofile/ - boot := arch/s390/boot syscalls := arch/s390/kernel/syscalls tools := arch/s390/tools diff --git a/arch/s390/configs/debug_defconfig b/arch/s390/configs/debug_defconfig index c4f6ff98a612..8b94347705e5 100644 --- a/arch/s390/configs/debug_defconfig +++ b/arch/s390/configs/debug_defconfig @@ -57,7 +57,6 @@ CONFIG_CMM=m CONFIG_APPLDATA_BASE=y CONFIG_KVM=m CONFIG_S390_UNWIND_SELFTEST=y -CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y CONFIG_STATIC_KEYS_SELFTEST=y diff --git a/arch/s390/configs/defconfig b/arch/s390/configs/defconfig index 51135893cffe..9db1232e09f4 100644 --- a/arch/s390/configs/defconfig +++ b/arch/s390/configs/defconfig @@ -55,7 +55,6 @@ CONFIG_CMM=m CONFIG_APPLDATA_BASE=y CONFIG_KVM=m CONFIG_S390_UNWIND_SELFTEST=m -CONFIG_OPROFILE=m CONFIG_KPROBES=y CONFIG_JUMP_LABEL=y # CONFIG_GCC_PLUGINS is not set diff --git a/arch/s390/oprofile/Makefile b/arch/s390/oprofile/Makefile deleted file mode 100644 index 36261f9d360b..000000000000 --- a/arch/s390/oprofile/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_OPROFILE) += oprofile.o - -DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ - oprof.o cpu_buffer.o buffer_sync.o \ - event_buffer.o oprofile_files.o \ - oprofilefs.o oprofile_stats.o \ - timer_int.o ) - -oprofile-y := $(DRIVER_OBJS) init.o diff --git a/arch/s390/oprofile/init.c b/arch/s390/oprofile/init.c deleted file mode 100644 index 7441857df51b..000000000000 --- a/arch/s390/oprofile/init.c +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * S390 Version - * Copyright IBM Corp. 2002, 2011 - * Author(s): Thomas Spatzier (ts...@de...) - * Author(s): Mahesh Salgaonkar (ma...@li...) - * Author(s): Heinz Graalfs (gr...@li...) - * Author(s): Andreas Krebbel (kr...@li...) - * - * @remark Copyright 2002-2011 OProfile authors - */ - -#include <linux/oprofile.h> -#include <linux/init.h> -#include <asm/processor.h> -#include <asm/unwind.h> - -static void s390_backtrace(struct pt_regs *regs, unsigned int depth) -{ - struct unwind_state state; - - unwind_for_each_frame(&state, current, regs, 0) { - if (depth-- == 0) - break; - oprofile_add_trace(state.ip); - } -} - -int __init oprofile_arch_init(struct oprofile_operations *ops) -{ - ops->backtrace = s390_backtrace; - return 0; -} - -void oprofile_arch_exit(void) -{ -} -- 2.25.0.rc1.19.g042ed3e048af |
From: Heiko C. <hc...@li...> - 2021-01-15 11:25:15
|
On Thu, Jan 14, 2021 at 05:05:25PM +0530, Viresh Kumar wrote: > The "oprofile" user-space tools don't use the kernel OPROFILE support > any more, and haven't in a long time. User-space has been converted to > the perf interfaces. > > Remove the old oprofile's architecture specific support. > > Suggested-by: Christoph Hellwig <hc...@in...> > Suggested-by: Linus Torvalds <tor...@li...> > Signed-off-by: Viresh Kumar <vir...@li...> > --- > arch/s390/Kconfig | 1 - > arch/s390/Makefile | 3 --- > arch/s390/configs/debug_defconfig | 1 - > arch/s390/configs/defconfig | 1 - > arch/s390/oprofile/Makefile | 10 --------- > arch/s390/oprofile/init.c | 37 ------------------------------- > 6 files changed, 53 deletions(-) > delete mode 100644 arch/s390/oprofile/Makefile > delete mode 100644 arch/s390/oprofile/init.c Acked-by: Heiko Carstens <hc...@li...> |