【发布时间】:2015-07-30 13:52:48
【问题描述】:
编辑:我认为我解决了这个问题。明天我再次上班时,我会添加自己的答案/解决方案。
我正在为 Linux 内核 3.16.x 开发一个内核模块。我的模块应该接收和发送以太网帧,所以我创建了两个线程。一个用于接收部分,一个用于发送部分。它工作正常。
当我尝试关闭模块的设备文件并卸载它时,我的问题出现了。准确地说,它发生在试图杀死我的线程时。机器(我正在使用 Ubuntu 14.04 的虚拟机上进行测试)在没有任何输出之前冻结。但是,当我从代码中删除“线程终止部分”时,它不再冻结。这就是为什么我很确定,这个问题源于我处理 kthread 的杀戮的方式。
这是我的两个主题:
TX THREAD:信号量 tx_sem 在代码的另一部分被更新。
static int tx_task(void *par)
{
device->tx_task_running = 1;
allow_signal(SIGTERM);
while (!signal_pending(current) && device->tx_task_running) {
/* wait until there is something to send */
down_interruptible(&device->tx_sem);
if (signal_pending(current)) {
PRINTD("device_TX_task(): Received kill signal\n");
break;
}
/* check if device is still initialized before continuing*/
if (!device->init_flag) {
break;
}
}
device->tx_task_running = 0;
return DEVICE_RET_OK;
}
接收线程
static int device_rx_task(void *par)
{
device->rx_task_running = 1;
/* task loop */
allow_signal(SIGTERM);
while (!signal_pending(current) && device->rx_task_running) {
rxlen = kernel_recvmsg(device->sock, &msg,
(struct kvec *)&iov, 1, DEVICE_PAY_SIZE, 0);
if (signal_pending(current)) {
PRINTD("device_rx_task(): Received kill signal\n");
break;
}
if(rxlen < 0) {
PRINTD("device_RX_task(): Got error when receiving\n");
break;
}
/* check if device is still initialized before continuing*/
if (!device->init_flag) {
break;
}
}
device->rx_task_running = 0;
return DEVICE_RET_OK;
}
这些家伙一直跑,直到我尝试关闭我的设备。当关闭内核模块时,这个函数被调用,这就是它崩溃的时候。例如,如果我将“send_sig”函数注释掉,它不会崩溃。当我尝试手动终止线程时它也会崩溃:
int Device_DevTerm(int dev)
{
device->init_flag = 0;
send_sig(SIGTERM, device->rx_thread, 0);
send_sig(SIGTERM, device->tx_thread, 0);
device->rx_task_running = 0;
device->tx_task_running = 0;
return DEVICE_RET_OK;
}
为了找到问题,我google搜索了很长时间,但到目前为止我没有成功。因为这个问题我已经花了很多时间,所以我决定问问你们。
我在这里做错了什么?
附言我想我从来没有在这里发过帖子,我只是读了很多。我希望我的问题足够清晰和简洁。应该不会吧。
【问题讨论】:
-
如果它崩溃发布堆栈跟踪。如果您的意思是挂起,请使用 SysRq 查找挂起的任务。
-
不幸的是,我似乎无法这样做。当我查看 /var/log/syslog/ 时,没有任何关于挂起的信息。我猜它在任何输出发生之前就冻结了。当我尝试 SysRq(我以前不知道)时,没有任何反应,它保持冻结状态。也许它是虚拟机这一事实并没有帮助,我不确定。我将继续尝试收集任何有用的信息,但到目前为止我还无法做到。
标签: c multithreading linux-kernel freeze