简体   繁体   English

具有自旋锁冻结功能的Linux内核线程

[英]Linux Kernel Threads with spinlock freeze

I have two kernel threads and I am trying to print from these two threads in alternate fashion. 我有两个内核线程,我试图以替代方式从这两个线程中打印。 I am using spinlock to sync these two threads. 我正在使用自旋锁来同步这两个线程。

 int kthread_1_function(void *data)
 {
     while(1)
     {
         spin_lock(&lock1);
         pr_alert("In Kernel Thread 1!!!\n");
         spin_unlock(&lock2);

        if(kthread_should_stop())
        {
            spin_unlock(&lock2);
            return 1;
        }
     }

     return 0;
 }

 int kthread_2_function(void *data)
 {
     while(1)
     {
         spin_lock(&lock2);
         pr_alert("In Kernel Thread 2!!!\n");
         spin_unlock(&lock1);

        if(kthread_should_stop())
        {
            spin_unlock(&lock1);
            return 2;
        }
      }

     return 0;
 }

In init module, I create these kernel threads (kthread_run) and cleanup_module stop these threads (kthread_stop). 在初始化模块中,我创建了这些内核线程(kthread_run),并且cleanup_module停止了这些线程(kthread_stop)。

When I try to remove the module entire system hangs. 当我尝试卸下模块时,整个系统将挂起。 By browsing the kernel source I could see that spin_lock disables preemption and kthread_stop tries to wake up the thread which is supposed to be killed and waits for the thread to exit and return. 通过浏览内核源代码,我可以看到spin_lock禁用了抢占,而kthread_stop尝试唤醒应该被杀死的线程,并等待该线程退出并返回。 Not sure what is making my system hang. 不知道是什么导致我的系统挂起。 Logically speaking it should have worked fine. 从逻辑上讲,它应该工作正常。

Note: When I initialize the spinlocks, I set lock1 as UNLOCKED and lock2 as LOCKED. 注意:初始化自旋锁时,将lock1设置为UNLOCKED,将lock2设置为LOCKED。

You have a double unlock problem here. 您在这里遇到双重解锁问题。 Spinlock in linux is implemented using a mechanism called "spinlock ticketing". linux中的Spinlock是使用称为“ spinlock票务”的机制实现的。 If you unlock a spinlock twice under this scheme every other attempt to lock the spin lock will cause the thread to spin forever. 如果您在此方案下两次解锁了自旋锁,则每隔一次尝试锁定自旋锁的操作都会导致线程永远旋转。
So the issue is that if(kthread_should_stop()) is true, you unlock the lock twice, getting all the other threads trying to fetch it stuck. 因此,问题在于if(kthread_should_stop())为true,您将锁解锁两次,使所有其他试图将其获取的线程卡住了。

More about spinlock ticketing: http://en.wikipedia.org/wiki/Ticket_lock 有关自旋锁售票的更多信息: http : //en.wikipedia.org/wiki/Ticket_lock

Also note that using the two locks is somewhat obsolete. 另请注意,使用两个锁有些过时了。 I would just share one lock between the 2 threads. 我只是在两个线程之间共享一个锁。

Well, you just hinted the solution: in spinlock(), preemption is disabled. 好吧,您刚刚暗示了解决方案:在spinlock()中,抢占被禁用。 so in spin_unlock(), it is reenabled back. 因此在spin_unlock()中将其重新启用。

Now, problem is you have spin_unlocked on a different variable than before, and immediately upon spin_unlocked, preemption enabled, and normal CPU scheduling will then schedule the kernel threads to another CPU to continue the execution. 现在,问题是您将spin_unlocked到了与以前不同的变量上,并且在spin_unlocked上立即启用了抢占功能,然后正常的CPU调度会将内核线程调度到另一个CPU继续执行。

And since you have created two kthread, each of them can be schedule by the kernel independently. 并且由于您已经创建了两个kthread,因此每个kthread都可以由内核独立调度。 So you will end up one kthread blocking on another kthread, each running on different CPU. 因此,您将最终在另一个kthread上阻塞一个kthread,每个kthread运行在不同的CPU上。

The spin lock concept has been created due to the existence of multicore: in single core, no spin lock is needed: why should the CPU do nothing but spinning on a lock waiting for it to be unfree, when there is only one CPU? 自旋锁的概念是由于多核的存在而产生的:在单核中,不需要自旋锁:当只有一个CPU时,为什么CPU不做任何事情,而是旋转锁以等待它变为非空闲状态?

It is preferred that you unlock on spin lock before locking on another, because each spin lock can be running on a different CPU itself, as CPU scheduling is really out of your control. 最好先在自旋锁上解锁再锁定另一个,因为每个自旋锁都可以在不同的CPU本身上运行,因为CPU调度确实超出了您的控制范围。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM