使用tracepoint debug IRQ的方法

1. 介绍

tracepoint为我们trace 内核event提供了钩子函数,我们可以通过tracepoint追踪内核事件。

tracepoint详细介绍:https://blog.csdn.net/geshifei/article/details/94360470

 

2.使用tracepoint统计IRQ频繁发生的次数,以及打印每次IRQ所用的时间。

思路:创建一个数组,数组中每个成员都是int型,用来统计对应IRQ的发生次数。

a. 首先,定义要保存的irq计数次数的结构体。

struct irq_state{
    int irq_count[NR_IRQS];
    ktime_t irq_time_stamp[NR_IRQS];
}

 

b. 使用tracepoint,可以让我们每次进入某个IRQ时,都先进钩子函数,所以,在这里可以统计IRQ发生的次数。

void irq_handler_entry_probe(void *data, int irq, struct irqaction *action)

{
    struct irq_state * irqs;
  if (action && (action->flags & IRQF_PERCPU)) //只关注SPI
    reuturn;

  irqs = this_cpu_ptr(data);
global_time = ktime_get();
  irqs->irq_count[irq] ++;
  //记录1000次irq的时间间隔
  if (irqs->irq_count[irq] > 1000){
    pr_notice("the irq=%d was entry 1000 times, take %lld ms.\n", irq, ktime_get() - irqs->irq_time_stamp[irq]);
    irqs->irq_count[irq] = 0;
  irqs->irq_time_stamp[irq] = ktime_get(); //记录进入irq的时间
}
}

 

c. 再写一个irq退出的函数,可以用来统计每个irq中执行的时间。

void irq_handler_exit_probe(void *data, int irq, struct irqaction *action, int res)
{
    strcut irq_state *irqs;

    //irqs = this_cpu_ptr(data);
    pr_notice("the irq=%d action time is %lld.\n",irq, ktime_get() - global_time);
  global_time = 0; }

 

d. 写一个kernel model,在init函数中连接钩子函数并分配cpu memory。

static int __init irq_count_init()
{   irq_state
= alloc_percpu(struct irq_state);   ret = register_trace_irq_handler_entry(irq_handler_entry_probe, irq_state);   ret = register_trace_irq_handler_exit(irq_handler_exit_probe, irq_state);
}

 

posted @ 2020-11-25 19:37  smilingsusu  阅读(384)  评论(0编辑  收藏  举报