📄 common.c
字号:
/** * @file common.c * * @remark Copyright 2004 Oprofile Authors * @remark Read the file COPYING * * @author Zwane Mwaikambo */#include <linux/init.h>#include <linux/oprofile.h>#include <linux/errno.h>#include <linux/slab.h>#include <linux/sysdev.h>#include <linux/mutex.h>#include "op_counter.h"#include "op_arm_model.h"static struct op_arm_model_spec *op_arm_model;static int op_arm_enabled;static DEFINE_MUTEX(op_arm_mutex);struct op_counter_config *counter_config;static int op_arm_create_files(struct super_block *sb, struct dentry *root){ unsigned int i; for (i = 0; i < op_arm_model->num_counters; i++) { struct dentry *dir; char buf[4]; snprintf(buf, sizeof buf, "%d", i); dir = oprofilefs_mkdir(sb, root, buf); oprofilefs_create_ulong(sb, dir, "enabled", &counter_config[i].enabled); oprofilefs_create_ulong(sb, dir, "event", &counter_config[i].event); oprofilefs_create_ulong(sb, dir, "count", &counter_config[i].count); oprofilefs_create_ulong(sb, dir, "unit_mask", &counter_config[i].unit_mask); oprofilefs_create_ulong(sb, dir, "kernel", &counter_config[i].kernel); oprofilefs_create_ulong(sb, dir, "user", &counter_config[i].user); } return 0;}static int op_arm_setup(void){ int ret; spin_lock(&oprofilefs_lock); ret = op_arm_model->setup_ctrs(); spin_unlock(&oprofilefs_lock); return ret;}static int op_arm_start(void){ int ret = -EBUSY; mutex_lock(&op_arm_mutex); if (!op_arm_enabled) { ret = op_arm_model->start(); op_arm_enabled = !ret; } mutex_unlock(&op_arm_mutex); return ret;}static void op_arm_stop(void){ mutex_lock(&op_arm_mutex); if (op_arm_enabled) op_arm_model->stop(); op_arm_enabled = 0; mutex_unlock(&op_arm_mutex);}#ifdef CONFIG_PMstatic int op_arm_suspend(struct sys_device *dev, pm_message_t state){ mutex_lock(&op_arm_mutex); if (op_arm_enabled) op_arm_model->stop(); mutex_unlock(&op_arm_mutex); return 0;}static int op_arm_resume(struct sys_device *dev){ mutex_lock(&op_arm_mutex); if (op_arm_enabled && op_arm_model->start()) op_arm_enabled = 0; mutex_unlock(&op_arm_mutex); return 0;}static struct sysdev_class oprofile_sysclass = { set_kset_name("oprofile"), .resume = op_arm_resume, .suspend = op_arm_suspend,};static struct sys_device device_oprofile = { .id = 0, .cls = &oprofile_sysclass,};static int __init init_driverfs(void){ int ret; if (!(ret = sysdev_class_register(&oprofile_sysclass))) ret = sysdev_register(&device_oprofile); return ret;}static void exit_driverfs(void){ sysdev_unregister(&device_oprofile); sysdev_class_unregister(&oprofile_sysclass);}#else#define init_driverfs() do { } while (0)#define exit_driverfs() do { } while (0)#endif /* CONFIG_PM */int __init oprofile_arch_init(struct oprofile_operations *ops){ struct op_arm_model_spec *spec = NULL; int ret = -ENODEV; ops->backtrace = arm_backtrace;#ifdef CONFIG_CPU_XSCALE spec = &op_xscale_spec;#endif#ifdef CONFIG_OPROFILE_ARMV6 spec = &op_armv6_spec;#endif#ifdef CONFIG_OPROFILE_MPCORE spec = &op_mpcore_spec;#endif if (spec) { ret = spec->init(); if (ret < 0) return ret; counter_config = kcalloc(spec->num_counters, sizeof(struct op_counter_config), GFP_KERNEL); if (!counter_config) return -ENOMEM; op_arm_model = spec; init_driverfs(); ops->create_files = op_arm_create_files; ops->setup = op_arm_setup; ops->shutdown = op_arm_stop; ops->start = op_arm_start; ops->stop = op_arm_stop; ops->cpu_type = op_arm_model->name; printk(KERN_INFO "oprofile: using %s\n", spec->name); } return ret;}void oprofile_arch_exit(void){ if (op_arm_model) { exit_driverfs(); op_arm_model = NULL; } kfree(counter_config);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -