看门狗不断复位


最近遇到一个问题,在zynq上跑起linux 4.4的kernel出现如下状况:
板子出现死机,在串口上无法敲命令,最后60s后被watchdog 复位。这个状况出现频率不固定。
/*****************************************************************************/
请教了一个kernel大神,初步怀疑是deadlock。
排除步骤如下
首先要先考虑deadlock是hard lock还是soft lock引起。首先找一个按键中断控制gpio灯,当出现死机时候,按下按键,如果点灯ok,说明没有关中断,只是soft lock,可以开softlock lockdep(还没学习),会进行死锁检测,找到两个死锁进程进行分析。Hardlock 关中断比较难弄。

后续我通过gitlog 发现有我在网卡中断中不停的ioremap和unmap,ioremap设置kmalloc 且标志位GFP_KERNEL,也就是可能会引起睡眠。我把ioremap在注册驱动中的函数实现,目前还没有出现死机问题。且加了中断控制led灯还没起到检测作用。
/*****************************************************************************/
模拟出现问题:
1.我在中断中加入睡眠函数,会主动调度。进程上下文和中断上下文,两个不同的东东,中断的优先级一定高于进程,且中断里面没有进程(task struct)概念,所以中断里面无法完成调度工作。Schedule函数如下:

asmlinkage void __sched schedule(void)
{
	struct task_struct *prev, *next;
	struct prio_array *array;
	struct list_head *queue;
	unsigned long long now;
	unsigned long run_time;
	int cpu, idx, new_prio;
	long *switch_count;
	struct rq *rq;

	/*
	 * Test if we are atomic.  Since do_exit() needs to call into
	 * schedule() atomically, we ignore that path for now.
	 * Otherwise, whine if we are scheduling when we should not be.
	 */
	if (unlikely(in_atomic() && !current->exit_state)) {
		printk(KERN_ERR "BUG: scheduling while atomic: "
			"%s/0x%08x/%d\n",
			current->comm, preempt_count(), current->pid);
		debug_show_held_locks(current);
		if (irqs_disabled())
			print_irqtrace_events(current);
		dump_stack();
	}
  ...............................................................
}
打印如下:

"BUG: scheduling while atomic: swapper1/0/0x00010002





2.故意使用spin_lock造成死锁。
此现象和 问题出现的一致,但是中断指示灯还是亮的。就是spin_lock关抢占引起。又试验了mutex_lock(学习下区别呗),会进入D状态(uninterruptible sleep),确实,系统不会挂掉只是进入不可中断睡眠。


后续我又写成了AB-BA死锁,由于我是双核的SMP,所以只有线程p获得A且线程B获取B锁,才会造成死锁(有点儿随机哦,不是必现)。

现在状况:
现象还是没有复现,但是怀疑不是中断函数里面睡眠引起的。

 

你可能感兴趣的:(linux,驱动)