Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ Β«Π Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° ядра LinuxΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 57

Автор Π ΠΎΠ±Π΅Ρ€Ρ‚ Π›Π°Π²

УсловныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ ΠΏΡ€Π΅Π΄ΡΡ‚Π°Π²Π»ΡΡŽΡ‚ΡΡ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ структуры struct completion, которая ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π° Π² Ρ„Π°ΠΉΠ»Π΅ <linux/completion.h>.

БтатичСски условная пСрСмСнная ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ создана с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ макроса

DECLARE_COMPLETION(mr_comp);

ДинамичСски созданная условная пСрСмСнная ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ init_completion().

Π—Π°Π΄Π°Π½ΠΈΠ΅, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΎΠΆΠΈΠ΄Π°Ρ‚ΡŒ Π½Π° условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ wait_for_completion(). ПослС Ρ‚ΠΎΠ³ΠΎ ΠΊΠ°ΠΊ наступило ΠΎΠΆΠΈΠ΄Π°Π΅ΠΌΠΎΠ΅ событиС, Π²Ρ‹Π·ΠΎΠ² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ complete() посылаСт сигнал заданию, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ Π½Π° условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ, ΠΈ это Π·Π°Π΄Π°Π½ΠΈΠ΅ возвращаСтся ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ. Π’ Ρ‚Π°Π±Π». 9.7 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½Ρ‹ ΠΌΠ΅Ρ‚ΠΎΠ΄Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с условными ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ.


Π’Π°Π±Π»ΠΈΡ†Π°. 9.7. ΠœΠ΅Ρ‚ΠΎΠ΄Ρ‹ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с условными ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹ΠΌΠΈ

ΠœΠ΅Ρ‚ΠΎΠ΄ ОписаниС init_completion(struct completion*) Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ динамичСски созданной условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ Π² Π·Π°Π΄Π°Π½Π½ΠΎΠΉ области памяти wait_for_completion(struct completion*) ОТиданиС сигнала Π½Π° ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ условной ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎΠΉ complete(struct completion*) ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° сигнала всСм ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠΌ заданиям ΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ ΠΈΡ… ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ

Для ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠ² использования условных ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… смотритС Ρ„Π°ΠΉΠ»Ρ‹ kernel/sched.c ΠΈ kernel/fork.с. НаиболСС часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ условныС ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΡΠΎΠ·Π΄Π°ΡŽΡ‚ΡΡ динамичСски, ΠΊΠ°ΠΊ Ρ‡Π°ΡΡ‚ΡŒ структур Π΄Π°Π½Π½Ρ‹Ρ…. Код ядра, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΎΠΆΠΈΠ΄Π°Π΅Ρ‚ Π½Π° ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡŽ структуры Π΄Π°Π½Π½Ρ‹Ρ…, Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ wait_for_completion(). Когда инициализация Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Π°, ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‰ΠΈΠ΅ задания Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ΡΡ ΠΊ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡŽ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Ρ‹Π·ΠΎΠ²Π° Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ complete().

BKL: Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ядра

Π”ΠΎΠ±Ρ€ΠΎ ΠΏΠΎΠΆΠ°Π»ΠΎΠ²Π°Ρ‚ΡŒ ΠΊ "Ρ€Ρ‹ΠΆΠ΅ΠΌΡƒ пасынку" ядра. Π‘ΠΎΠ»ΡŒΡˆΠ°Ρ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° ядра (Big Kernel Lock, BKL) β€” это глобальная спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°, которая Π±Ρ‹Π»Π° создана ΡΠΏΠ΅Ρ†ΠΈΠ°Π»ΡŒΠ½ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΎΠ±Π»Π΅Π³Ρ‡ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΎΡ‚ ΠΏΠ΅Ρ€Π²ΠΎΠ½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ SMP Π² ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΎΠ½Π½ΠΎΠΉ систСмС Linux ΠΊ мСлкоструктурным Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌ. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° BKL ΠΈΠΌΠ΅Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ интСрСсныС свойства.

β€’ Π’ΠΎ врСмя удСрТания BKL ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² состояниС оТидания. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° автоматичСски освобоТдаСтся, ΠΊΠΎΠ³Π΄Π° Π·Π°Π΄Π°Π½ΠΈΠ΅ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ Π² состояниС оТидания, ΠΈ снова захватываСтся, ΠΊΠΎΠ³Π΄Π° Π·Π°Π΄Π°Π½ΠΈΠ΅ планируСтся Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅. ΠšΠΎΠ½Π΅Ρ‡Π½ΠΎ, это Π½Π΅ ΠΎΠ·Π½Π°Ρ‡Π°Π΅Ρ‚, Ρ‡Ρ‚ΠΎ бСзопасно ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² состояниС оТидания ΠΏΡ€ΠΈ ΡƒΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠΈ BKL, просто это ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅Π»Π°Ρ‚ΡŒ ΠΈ это Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ Π²Π·Π°ΠΈΠΌΠΎΠ±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ΅.

β€’ Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° BKL рСкурсивна. Один процСсс ΠΌΠΎΠΆΠ΅Ρ‚ Π·Π°Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ эту Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ нСсколько Ρ€Π°Π· подряд, ΠΈ это Π½Π΅ ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Ρ‚ ΠΊ самоблокировкС, ΠΊΠ°ΠΊ Π² случаС ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹Ρ… спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ.

β€’ Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° BKL ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² контСкстС процСсса.

β€’ Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° BKL β€” это ΠΎΡ‚ Π»ΡƒΠΊΠ°Π²ΠΎΠ³ΠΎ.

РассмотрСнныС свойства Π΄Π°Π»ΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΎΡ‚ ядСр сСрии 2.0 ΠΊ сСрии 2.2. Когда Π² ядро 2.0 Π±Ρ‹Π»Π° Π²Π²Π΅Π΄Π΅Π½Π° ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° SMP, Ρ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΎΠ΄Π½ΠΎ Π·Π°Π΄Π°Π½ΠΈΠ΅ ΠΌΠΎΠ³Π»ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒΡΡ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ ядра Π² любой ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ (ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎ, сСйчас ядро распараллСлСно ΠΎΡ‡Π΅Π½ΡŒ Ρ…ΠΎΡ€ΠΎΡˆΠΎ β€” ΠΏΡ€ΠΎΠΉΠ΄Π΅Π½ ΠΎΠ³Ρ€ΠΎΠΌΠ½Ρ‹ΠΉ ΠΏΡƒΡ‚ΡŒ). ЦСлью создания ядра сСрии 2.2 Π±Ρ‹Π»ΠΎ обСспСчСниС возмоТности ΠΏΠ°Ρ€Π°Π»Π»Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ выполнСния ΠΊΠΎΠ΄Π° ядра Π½Π° Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… процСссорах. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° BKL Π±Ρ‹Π»Π° Π²Π²Π΅Π΄Π΅Π½Π° для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΡƒΠΏΡ€ΠΎΡΡ‚ΠΈΡ‚ΡŒ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ ΠΊ мСлкоструктурным Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌ. Π’ Ρ‚Π΅ Π²Ρ€Π΅ΠΌΠ΅Π½Π° ΠΎΠ½Π° ΠΎΠΊΠ°Π·Π°Π»Π° Π±ΠΎΠ»ΡŒΡˆΡƒΡŽ ΠΏΠΎΠΌΠΎΡ‰ΡŒ, Π° сСгодня ΠΎΠ½Π° ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ ΡƒΡ…ΡƒΠ΄ΡˆΠ΅Π½ΠΈΡŽ ΠΌΠ°ΡΡˆΡ‚Π°Π±ΠΈΡ€ΡƒΠ΅ΠΌΠΎΡΡ‚ΠΈ[51].

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ BKL Π½Π΅ рСкомСндуСтся. На самом Π΄Π΅Π»Π΅, Π½ΠΎΠ²Ρ‹ΠΉ ΠΊΠΎΠ΄ Π½ΠΈΠΊΠΎΠ³Π΄Π° Π½Π΅ Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ BKL. Однако эта Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° всС Π΅Ρ‰Π΅ достаточно интСнсивно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… частях ядра. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π²Π°ΠΆΠ½ΠΎ ΠΏΠΎΠ½ΠΈΠΌΠ°Ρ‚ΡŒ особСнности большой Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ядра ΠΈ интСрфСйса ΠΊ Π½Π΅ΠΉ. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° BKL Π²Π΅Π΄Π΅Ρ‚ сСбя, ΠΊΠ°ΠΊ обычная спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°, Π·Π° ΠΈΡΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ΠΌ Ρ‚Π΅Ρ… особСнностСй, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π±Ρ‹Π»ΠΈ рассмотрСны Π²Ρ‹ΡˆΠ΅. Ѐункция lock_kernel() позволяСт Π·Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, Π° функция unlock_kernel() β€” ΠΎΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ. ΠšΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ выполнСния ΠΌΠΎΠΆΠ΅Ρ‚ рСкурсивно Π·Π°Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒ эту Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ, Π½ΠΎ послС этого Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ ΠΆΠ΅ Ρ€Π°Π· Π²Ρ‹Π·Π²Π°Ρ‚ΡŒ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ unlock_kernel(). ΠŸΡ€ΠΈ послСднСм Π²Ρ‹Π·ΠΎΠ²Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ освобоТдСния Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π±ΡƒΠ΄Π΅Ρ‚ освобоТдСна. Ѐункция kernel_locked() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ссли Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π² Π΄Π°Π½Π½Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π°, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС возвращаСтся Π½ΡƒΠ»ΡŒ. Π­Ρ‚ΠΈ интСрфСйсы ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Ρ‹ Π² Ρ„Π°ΠΉΠ»Π΅ <linux/smp_lock.h>. Рассмотрим простой ΠΏΡ€ΠΈΠΌΠ΅Ρ€ использования этой Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ.

lock_kernel();


/*

* ΠšΡ€ΠΈΡ‚ΠΈΡ‡Π΅ΡΠΊΠΈΠΉ Ρ€Π°Π·Π΄Π΅Π», ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ синхронизирован со всСми ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡΠΌΠΈ

* Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ BKL...

* Π—Π°ΠΌΠ΅Ρ‚ΠΈΠΌ, Ρ‡Ρ‚ΠΎ здСсь ΠΌΠΎΠΆΠ½ΠΎ бСзопасно ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² состояниС оТидания

* ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ ΠΎΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ‚ΡŒΡΡ.

* ПослС пСрСпланирования Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ снова

* Π·Π°Ρ…Π²Π°Ρ‚Ρ‹Π²Π°Ρ‚ΡŒΡΡ.

* Π­Ρ‚ΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ‚ состояния Π²Π·Π°ΠΈΠΌΠΎΠ±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ,

* Π½ΠΎ всС-Ρ‚Π°ΠΊΠΈ Π»ΡƒΡ‡ΡˆΠ΅ Π½Π΅ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚ΡŒ Π² состояниС оТидания,

* Ссли Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Ρ‰ΠΈΡ‚Ρƒ Π΄Π°Π½Π½Ρ‹Ρ…!

*/


unlock_kernel();

Когда эта Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π°, происходит Π·Π°ΠΏΡ€Π΅Ρ‰Π΅Π½ΠΈΠ΅ прССмптивности. Для ядСр, скомпилированных ΠΏΠΎΠ΄ ΠΎΠ΄Π½ΠΎΠΏΡ€ΠΎΡ†Π΅ΡΡΠΎΡ€Π½ΡƒΡŽ ΠΌΠ°ΡˆΠΈΠ½Ρƒ, ΠΊΠΎΠ΄ BKL Π½Π° самом Π΄Π΅Π»Π΅ Π½Π΅ выполняСт Π½ΠΈΠΊΠ°ΠΊΠΈΡ… Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ. Π’ Ρ‚Π°Π±Π». 9.8 ΠΏΡ€ΠΈΠ²Π΅Π΄Π΅Π½ ΠΏΠΎΠ»Π½Ρ‹ΠΉ список Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с BKL.


Π’Π°Π±Π»ΠΈΡ†Π° 9.8. Π€ΡƒΠ½ΠΊΡ†ΠΈΠΈ Ρ€Π°Π±ΠΎΡ‚Ρ‹ с большой Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ ядра

Ѐункция ОписаниС lock_kernel() Π—Π°Ρ…Π²Π°Ρ‚ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ BKL unlock_kernel() ΠžΡΠ²ΠΎΠ±ΠΎΠ΄ΠΈΡ‚ΡŒ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ BKL kernel_locked() Π’ΠΎΠ·Π²Ρ€Π°Ρ‚ΠΈΡ‚ΡŒ Π½Π΅Π½ΡƒΠ»Π΅Π²ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅, Ссли Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π°, ΠΈ Π½ΡƒΠ»ΡŒ- Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎΠΌ случаС

Одна ΠΈΠ· самых Π³Π»Π°Π²Π½Ρ‹Ρ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, связанных с большой Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ ядра, β€” ΠΊΠ°ΠΊ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ защищаСтся с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π΄Π°Π½Π½ΠΎΠΉ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ. Часто Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° BKL ассоциируСтся с ΠΊΠΎΠ΄ΠΎΠΌ (Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΎΠ½Π° "синхронизируСт Π²Ρ‹Π·ΠΎΠ²Ρ‹ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ foo()"), Π° Π½Π΅ с Π΄Π°Π½Π½Ρ‹ΠΌΠΈ ("Π·Π°Ρ‰ΠΈΡ‚Π° структуры foo"). Π­Ρ‚ΠΎ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ ΠΊ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡ‚ΡŒ BKL ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌΠΈ спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°ΠΌΠΈ Π±Ρ‹Π²Π°Π΅Ρ‚ слоТно, ΠΏΠΎΡ‚ΠΎΠΌΡƒ Ρ‡Ρ‚ΠΎ Π½Π΅Π»Π΅Π³ΠΊΠΎ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΆΠ΅ всС-Ρ‚Π°ΠΊΠΈ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ. На самом Π΄Π΅Π»Π΅, подобная Π·Π°ΠΌΠ΅Π½Π° Π΅Ρ‰Π΅ Π±ΠΎΠ»Π΅Π΅ слоТна, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΡƒΡ‡ΠΈΡ‚Ρ‹Π²Π°Ρ‚ΡŒ всС Π²Π·Π°ΠΈΠΌΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΌΠ΅ΠΆΠ΄Ρƒ всСми участками ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ эту Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ.

Π‘Π΅ΠΊΠ²Π΅Π½Ρ‚Π½Ρ‹Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ

БСквСнтная Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° (seq lock) β€” это Π½ΠΎΠ²Ρ‹ΠΉ Ρ‚ΠΈΠΏ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ появился Π² ядрах сСрии 2.6. Π­Ρ‚ΠΈ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΏΡ€Π΅Π΄ΠΎΡΡ‚Π°Π²Π»ΡΡŽΡ‚ ΠΎΡ‡Π΅Π½ΡŒ простой ΠΌΠ΅Ρ…Π°Π½ΠΈΠ·ΠΌ чтСния ΠΈ записи совмСстно ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Ρ… Π΄Π°Π½Π½Ρ‹Ρ…. Π Π°Π±ΠΎΡ‚Π° Ρ‚Π°ΠΊΠΈΡ… Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ основана Π½Π° счСтчикС ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ событий. ΠŸΠ΅Ρ€Π΅Π΄ записью рассматриваСмых Π΄Π°Π½Π½Ρ‹Ρ… захватываСтся спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ°, ΠΈ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика увСличиваСтся Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ. ПослС записи Π΄Π°Π½Π½Ρ‹Ρ… Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика снова увСличиваСтся Π½Π° Π΅Π΄ΠΈΠ½ΠΈΡ†Ρƒ, ΠΈ спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° освобоТдаСтся, давая Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ записи Π΄Ρ€ΡƒΠ³ΠΈΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ. ΠŸΠ΅Ρ€Π΅Π΄ Ρ‡Ρ‚Π΅Π½ΠΈΠ΅ΠΌ ΠΈ послС чтСния Π΄Π°Π½Π½Ρ‹Ρ… провСряСтся Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика. Если Π΄Π²Π° ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½Ρ‹Ρ… значСния ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹, Ρ‚ΠΎ Π²ΠΎ врСмя чтСния Π΄Π°Π½Π½Ρ‹Ρ… Π½ΠΎΠ²Ρ‹ΠΉ Π°ΠΊΡ‚ записи Π½Π΅ начинался, Если ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΆΠ΅ ΠΎΠ±Π° эти значСния Ρ‡Π΅Ρ‚Π½Ρ‹Π΅, Ρ‚ΠΎ ΠΊ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρƒ Π½Π°Ρ‡Π°Π»Π° чтСния Π°ΠΊΡ‚ записи Π±Ρ‹Π» Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½ (ΠΏΡ€ΠΈ Π·Π°Ρ…Π²Π°Ρ‚Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ Π½Π° запись Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика становится Π½Π΅Ρ‡Π΅Ρ‚Π½Ρ‹ΠΌ, Π° ΠΏΠ΅Ρ€Π΅Π΄ освобоТдСниСм β€” снова Ρ‡Π΅Ρ‚Π½Ρ‹ΠΌ, Ρ‚Π°ΠΊ ΠΊΠ°ΠΊ ΠΈΠ·Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Ρ€Π°Π²Π½ΠΎ Π½ΡƒΠ»ΡŽ).

ΠžΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½ΠΈΠ΅ сСквСнтной Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

seqlock_t mr_seq_lock = SEQLOCK_UNLOCKED;

Участок ΠΊΠΎΠ΄Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ осущСствляСт запись, ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΌ ΠΎΠ±Ρ€Π°Π·ΠΎΠΌ.

write_seqlock(&mr_seq_lock);

/* Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π° Π½Π° запись ... */

write_sequnlock(&mr_seq_lock);

Π­Ρ‚ΠΎ выглядит, ΠΊΠ°ΠΊ Ρ€Π°Π±ΠΎΡ‚Π° с ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΠΉ спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΎΠΉ. ΠΠ΅ΠΎΠ±Ρ‹Ρ‡Π½ΠΎΡΡ‚ΡŒ появляСтся Π² ΠΊΠΎΠ΄Π΅ чтСния, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ нСсколько отличаСтся ΠΎΡ‚ Ρ€Π°Π½Π΅Π΅ рассмотрСнных.

unsigned long seq;

do {

 seq = read_seqbegin(&mr_seq_lock);

 /* здСсь Π½ΡƒΠΆΠ½ΠΎ Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ ... */

} while (read_seqretry(&mr_seq_lock, seq));

Π‘Π΅ΠΊΠ²Π΅Π½Ρ‚Π½Ρ‹Π΅ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹ для обСспСчСния ΠΎΡ‡Π΅Π½ΡŒ быстрого доступа ΠΊ Π΄Π°Π½Π½Ρ‹ΠΌ Π² случаС, ΠΊΠΎΠ³Π΄Π° примСняСтся ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² чтСния ΠΈ ΠΌΠ°Π»ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² записи. ΠšΡ€ΠΎΠΌΠ΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΡ€ΠΈ использовании этого Ρ‚ΠΈΠΏΠ° Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ ΠΏΠΎΡ‚ΠΎΠΊΠΈ записи ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ Π±ΠΎΠ»Π΅Π΅ высокий ΠΏΡ€ΠΈΠΎΡ€ΠΈΡ‚Π΅Ρ‚ ΠΏΠ΅Ρ€Π΅Π΄ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ чтСния. Π‘Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠ° записи всСгда Π±ΡƒΠ΄Π΅Ρ‚ ΡƒΡΠΏΠ΅ΡˆΠ½ΠΎ Π·Π°Ρ…Π²Π°Ρ‡Π΅Π½Π°, Ссли Π½Π΅Ρ‚ Π΄Ρ€ΡƒΠ³ΠΈΡ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² записи. ΠŸΠΎΡ‚ΠΎΠΊΠΈ чтСния Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ Π²Π»ΠΈΡΡŽΡ‚ Π½Π° Π·Π°Ρ…Π²Π°Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΠΈ записи, Π² ΠΏΡ€ΠΎΡ‚ΠΈΠ²ΠΎΠΏΠΎΠ»ΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ Ρ‚ΠΎΠΌΡƒ, Ρ‡Ρ‚ΠΎ ΠΈΠΌΠ΅Π΅Ρ‚ мСсто для спин-Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΎΠΊ ΠΈ сСмафоров чтСния-записи. Π‘ΠΎΠ»Π΅Π΅ Ρ‚ΠΎΠ³ΠΎ, ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΎΠΆΠΈΠ΄Π°ΡŽΡ‚ Π½Π° запись, Π±ΡƒΠ΄ΡƒΡ‚ Π²Ρ‹Π·Ρ‹Π²Π°Ρ‚ΡŒ постоянныС повторСния Ρ†ΠΈΠΊΠ»Π° чтСния (ΠΊΠ°ΠΊ Π² ΠΏΠΎΠΊΠ°Π·Π°Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅) Π΄ΠΎ Ρ‚Π΅Ρ… ΠΏΠΎΡ€, ΠΏΠΎΠΊΠ° Π½Π΅ останСтся Π½ΠΈ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠ°, ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°ΡŽΡ‰Π΅Π³ΠΎ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²ΠΊΡƒ записи Π²ΠΎ врСмя чтСния Π΄Π°Π½Π½Ρ‹Ρ….