2014-09-16 7 views
0

У меня есть два потока ядра, и я пытаюсь поочередно печатать из этих двух потоков. Я использую spinlock для синхронизации этих двух потоков.Темы ядра Linux с замораживанием спин-блокировки

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; 
} 

В модуле инициализации, я создаю эти потоки ядра (kthread_run) и cleanup_module остановить эти потоки (kthread_stop).

Когда я пытаюсь удалить модуль, вся система зависает. Просмотрев исходный код ядра, я увидел, что spin_lock отключает preemption, и kthread_stop пытается пробудить поток, который должен быть убит, и ждет, пока поток выйдет и вернется. Не уверен, что заставляет мою систему зависать. Логически это должно было хорошо работать.

Примечание: Когда я инициализирую шпиндельные блоки, я устанавливаю lock1 как UNLOCKED и lock2 как LOCKED.

+0

Одна проблема, которую я вижу, заключается в том, что 'kthread_1_function' открывает' lock2' для 'kthread_should_stop()' условие, и соответственно 'kthread_2_function' разблокирует' lock1'. Но они были просто разблокированы. Я думаю, что вы хотите, вы должны попробовать их заменить. – Anton

ответ

0

У вас проблема с двойной разблокировкой. Spinlock в linux реализуется с использованием механизма, называемого «спин-блокировка». Если вы разблокируете спин-блокировку дважды по этой схеме, любая другая попытка заблокировать блокировку вращения заставит нить вращаться навсегда.
Итак, проблема заключается в том, что если (kthread_should_stop()) истинно, вы разблокируете блокировку дважды, получая все остальные потоки, пытаясь забрать их.

Подробнее о спин-блокировки билетов: http://en.wikipedia.org/wiki/Ticket_lock

Также отметим, что с помощью двух замков, несколько устарели. Я бы просто разделил один замок между двумя потоками.

+0

Хорошо. Идея состояла в том, чтобы синхронизировать эти два потока и заставить их печатать один за другим. Если вы сказали, что проблема, удаление второго spin_unlock должно решить проблему. Я попытался найти код, связанный с идентификатором ticket_lock, в ядре, но не смог его найти. Не могли бы вы помочь мне найти этот фрагмент кода. Также spin_lock отключает превенцию. Имеет ли это какое-либо отношение к проблеме? – TSP

+0

С одной спин-блокировкой у вас будет такая же проблема. У вас двойная разблокировка. Вам нужно удалить второй spin_unlock и объединить обе спин-блокировку в одну спин-блокировку. – kipodi

+0

Я снял вторую разблокировку, но она все еще зависает. На самом деле я использовал msleep между разблокировкой и kthread_should_stop.Это может быть причиной? – TSP

0

Ну, вы просто намекнули на решение: в spinlock() преемственность отключена. поэтому в spin_unlock() он снова подключается обратно.

Теперь проблема заключается в том, что у вас есть spin_unlocked для другой переменной, чем раньше, и сразу же после включения spin_unlocked, preemption enabled и обычного планирования CPU будет планировать потоки ядра на другой CPU для продолжения выполнения.

И так как вы создали два kthread, каждый из них может быть запланирован ядром независимо. Таким образом, вы закончите один kthread, блокирующий другой kthread, каждый из которых работает на разных CPU.

Концепция блокировки спина создана из-за существования многоядерных процессоров: в одном ядре нет необходимости блокировать прямую блокировку: зачем ЦП ничего не делать, кроме того, что он вращается на замке, ожидая, что он будет несвободным, когда есть только один процессор?

Предпочтительно, чтобы вы открывали блокировку спина перед блокировкой на другом, потому что каждая прямая блокировка может работать на другом самом процессоре, поскольку планирование ЦП действительно не под вашим контролем.