cregit-Linux how code gets into the kernel

Release 4.7 drivers/oprofile/oprof.c

Directory: drivers/oprofile
/**
 * @file oprof.c
 *
 * @remark Copyright 2002 OProfile authors
 * @remark Read the file COPYING
 *
 * @author John Levon <levon@movementarian.org>
 */

#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; }

Contributors

PersonTokensPropCommitsCommitProp
john levonjohn levon10864.67%240.00%
bob nelsonbob nelson4929.34%120.00%
markus armbrustermarkus armbruster63.59%120.00%
greg banksgreg banks42.40%120.00%
Total167100.00%5100.00%

#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); }

Contributors

PersonTokensPropCommitsCommitProp
jason yehjason yeh1568.18%133.33%
robert richterrobert richter731.82%266.67%
Total22100.00%3100.00%


static void stop_switch_worker(void) { cancel_delayed_work_sync(&switch_work); }

Contributors

PersonTokensPropCommitsCommitProp
robert richterrobert richter14100.00%1100.00%
Total14100.00%1100.00%


static void switch_worker(struct work_struct *work) { if (oprofile_ops.switch_events()) return; atomic_inc(&oprofile_stats.multiplex_counter); start_switch_worker(); }

Contributors

PersonTokensPropCommitsCommitProp
jason yehjason yeh2170.00%150.00%
robert richterrobert richter930.00%150.00%
Total30100.00%2100.00%

/* 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; }

Contributors

PersonTokensPropCommitsCommitProp
robert richterrobert richter93100.00%1100.00%
Total93100.00%1100.00%

#else
static inline void start_switch_worker(void) { }

Contributors

PersonTokensPropCommitsCommitProp
robert richterrobert richter8100.00%1100.00%
Total8100.00%1100.00%


static inline void stop_switch_worker(void) { }

Contributors

PersonTokensPropCommitsCommitProp
robert richterrobert richter8100.00%1100.00%
Total8100.00%1100.00%

#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; }

Contributors

PersonTokensPropCommitsCommitProp
john levonjohn levon6589.04%240.00%
markus armbrustermarkus armbruster45.48%120.00%
jason yehjason yeh34.11%120.00%
greg banksgreg banks11.37%120.00%
Total73100.00%5100.00%

/* 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); }

Contributors

PersonTokensPropCommitsCommitProp
john levonjohn levon3782.22%120.00%
markus armbrustermarkus armbruster48.89%120.00%
robert richterrobert richter24.44%120.00%
greg banksgreg banks12.22%120.00%
jason yehjason yeh12.22%120.00%
Total45100.00%5100.00%


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); }

Contributors

PersonTokensPropCommitsCommitProp
bob nelsonbob nelson4249.41%120.00%
john levonjohn levon3743.53%240.00%
markus armbrustermarkus armbruster44.71%120.00%
greg banksgreg banks22.35%120.00%
Total85100.00%5100.00%


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; }

Contributors

PersonTokensPropCommitsCommitProp
john levonjohn levon1733.33%457.14%
greg banksgreg banks1733.33%114.29%
robert richterrobert richter1325.49%114.29%
markus armbrustermarkus armbruster47.84%114.29%
Total51100.00%7100.00%

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(); }

Contributors

PersonTokensPropCommitsCommitProp
robert richterrobert richter4452.38%222.22%
greg banksgreg banks2428.57%222.22%
martin schwidefskymartin schwidefsky89.52%111.11%
john levonjohn levon44.76%222.22%
will deaconwill deacon22.38%111.11%
akinobu mitaakinobu mita22.38%111.11%
Total84100.00%9100.00%


static void __exit oprofile_exit(void) { oprofilefs_unregister(); if (!timer_mode) oprofile_arch_exit(); }

Contributors

PersonTokensPropCommitsCommitProp
john levonjohn levon1260.00%240.00%
robert richterrobert richter630.00%240.00%
martin schwidefskymartin schwidefsky210.00%120.00%
Total20100.00%5100.00%

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 <levon@movementarian.org>"); MODULE_DESCRIPTION("OProfile system profiler");

Overall Contributors

PersonTokensPropCommitsCommitProp
john levonjohn levon38245.21%832.00%
robert richterrobert richter23027.22%832.00%
bob nelsonbob nelson9110.77%14.00%
greg banksgreg banks526.15%28.00%
jason yehjason yeh516.04%14.00%
markus armbrustermarkus armbruster242.84%14.00%
martin schwidefskymartin schwidefsky101.18%14.00%
will deaconwill deacon20.24%14.00%
akinobu mitaakinobu mita20.24%14.00%
anton blanchardanton blanchard10.12%14.00%
Total845100.00%25100.00%
Directory: drivers/oprofile
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.
{% endraw %}