Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

#include <linux/log.h>
#include <linux/preempt.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/utsname.h>
#include "kernelversion.gen.h"
//#define DBG_ASM_IRQ_TRACE

/* Since we run our experiment in a single-core environment, 
 * we can safely use *only* one buffer.
 * If someone wants to run the experiment on a multi-core system some day,
 * he or she has to allocate #cores vars.
 */
struct log_action la_buffer;

__visible void trace_hardirqs_on_caller(unsigned long ip) {
#ifdef DBG_ASM_IRQ_TRACE
	__log_lock(0, "static", (void*)0x44, __FILE__, __LINE__,  __func__, "irq", ip, 0);
#else
	log_lock(0, "static", (void*)0x44, __FILE__, __LINE__,  __func__,0);
#endif
}
EXPORT_SYMBOL(trace_hardirqs_on_caller)

__visible void trace_hardirqs_off_caller(unsigned long ip) {
#ifdef DBG_ASM_IRQ_TRACE
	__log_lock(1, "static", (void*)0x44, __FILE__, __LINE__,  __func__, "irq", ip, 0);
#else
	log_lock(1, "static", (void*)0x44, __FILE__, __LINE__,  __func__,0);
#endif
}
EXPORT_SYMBOL(trace_hardirqs_off_caller)

void print_irqtrace_events(struct task_struct *curr) {
	
}
EXPORT_SYMBOL(print_irqtrace_events)

int log_preempt_count(void) {
	return preempt_count();
}
EXPORT_SYMBOL(log_preempt_count);

static int preempt_count_addr_show(struct seq_file *m, void *v)
{
	/* Since we run our experiment in a single-core environment, 
	 * we can safely use the preempt_count of the first core.
	 */
	int *foo = per_cpu_ptr(&__preempt_count,0);
        seq_printf(m, "0x%p\n",
                foo);
        return 0;
}

static int preempt_count_addr_open(struct inode *inode, struct file *file)
{
        return single_open(file, preempt_count_addr_show, NULL);
}

static const struct file_operations preempt_count_addr_fops = {
        .open           = preempt_count_addr_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
};


static int version_ext_show(struct seq_file *m, void *v)
{
        seq_printf(m, "%s%s\n",
                utsname()->release,
                KERNEL_VERSION_EXTENDED);
        return 0;
}

static int version_ext_open(struct inode *inode, struct file *file)
{
        return single_open(file, version_ext_show, NULL);
}

static const struct file_operations version_ext_fops = {
        .open           = version_ext_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
};

static int __init log_init(void) {
	proc_create("version-git", 0, NULL, &version_ext_fops);
	proc_create("preemptcount-addr", 0, NULL, &preempt_count_addr_fops);
	return 0;
}
fs_initcall(log_init);