Freezing of tasks(2/2)

もともと、Linux Kernelのソースコードの一部なので、GPLv2扱いになる（はずの認識）。

> https://www.kernel.org/doc/html/latest/index.html
> 
> Licensing documentation
> 
> The following describes the license of the Linux kernel source code (GPLv2), how to properly mark the license of individual files in the source tree, as well as links to the full license text.
> 
> https://www.kernel.org/doc/html/latest/process/license-rules.html#kernel-licensing


https://www.kernel.org/doc/html/latest/power/freezing-of-tasks.html

---

Docs » Power Management » Freezing of tasks

# V. Are there any problems related to the freezing of tasks?（taskの凍結に関する問題はありますか？）

Yes, there are.（はい、あります）

.

> First of all, the freezing of kernel threads may be tricky if they depend one on another. 

まず最初に、kernel threadの凍結は、他のものを要求している場合、トリッキーになります。

> For example, if kernel thread A waits for a completion (in the TASK_UNINTERRUPTIBLE state) that needs to be done by freezable kernel thread B and B is frozen in the meantime, then A will be blocked until B is thawed, which may be undesirable. 
例えば、kernel thread Aが(TASK_UNINTERRUPTIBLE stateで）freezable kernel thread Bによる完了を待ち、更に、その間にBが凍結した場合、AはBが解凍されるまでブロックされ、望ましくないことになるでしょう。

> That’s why kernel threads are not freezable by default.

これが、kernel threadがデフォルトでfreezableにしない理由です。

.

> Second, there are the following two problems related to the freezing of user space processes:

次に、ユーザー空間プロセスの凍結に関連した、下記２つの理由があります。

.

> Putting processes into an uninterruptible sleep distorts the load average.

プロセスを中断できないスリープにすると、平均負荷が歪みが生じます。

> Now that we have FUSE, plus the framework for doing device drivers in userspace, it gets even more complicated because some userspace processes are now doing the sorts of things that kernel threads do (https://lists.linux-foundation.org/pipermail/linux-pm/2007-May/012309.html).

現在、FUSEと、更に、ユーザー空間でのデバイスドライバを実行するフレームワークがあります。これは、いくつかのユーザー空間プロセスが、kernel threadの実行する類の処理を実行しているので、更に複雑になります。(https://lists.linux-foundation.org/pipermail/linux-pm/2007-May/012309.html)

> The problem 1. seems to be fixable, although it hasn’t been fixed so far. 

問題１は、解決できそうに見えますが、それは解決できていません。

> The other one is more serious, but it seems that we can work around it by using hibernation (and suspend) notifiers 

もう１つは、更に重大な問題です、しかしこれは、hibernation(そしてsuspend)のnotifiersで使われるワークアラウンドを用いて回避できます。

> (in that case, though, we won’t be able to avoid the realization by the user space processes that the hibernation is taking place).

（ただしその場合、hibernationが行われるユーザー空間プロセスによって、realizationすることを回避できません）。

.

> There are also problems that the freezing of tasks tends to expose, although they are not directly related to it. 

また、タスクのフリーズには直接関係しないが、タスクのフリーズによって顕在化しやすくなる問題もまたあります。

> For example, if request_firmware() is called from a device driver’s .resume() routine, it will timeout and eventually fail, because the user land process that should respond to the request is frozen at this point. 

例えば、request_firmware()がデバイスドライバーのresume()ルーチンから呼ばれた場合、これはtimeoutして最終的には失敗します。なぜならば、この要求に応答しなければならないユーザー空間のプロセスは、この時点で凍結しています。

> So, seemingly, the failure is due to the freezing of tasks.

したがって、一見すると、失敗する原因はタスクの凍結にあります。

> Suppose, however, that the firmware file is located on a filesystem accessible only through another device that hasn’t been resumed yet.

ただ、しかし、firmware fileはfilesystem にあります。file systemはresumeが完了していない別のデバイスを通してからのみ、アクセスできます。

> In that case, request_firmware() will fail regardless of whether or not the freezing of tasks is used. 

この場合、タスクの凍結が使用されているかどうかには関係なく、request_firmware()は失敗するでしょう。

> Consequently, the problem is not really related to the freezing of tasks, since it generally exists anyway.

その結果、問題は通常発生するので、タスクの凍結には関連していません。

.

> A driver must have all firmwares it may need in RAM before suspend() is called. 

ドライバーは、suspend()が呼ばれる前に、RAM上にすべてのfirmwareを有していなければなりません。

> If keeping them is not practical, for example due to their size, they must be requested early enough using the suspend notifier API described in Documentation/driver-api/pm/notifiers.rst.

例えば、そのサイズなど、保持することが実用的でない場合には、suspend notifier API(Documentation/driver-api/pm/notifiers.rst参照)を用いて早期に要求をするべきです。

# VI. Are there any precautions to be taken to prevent freezing failures?（凍結問題を防ぐための予防策はありますか？）

Yes, there are.（はい、あります）

.

> First of all, grabbing the ‘system_transition_mutex’ lock to mutually exclude a piece of code from system-wide sleep such as suspend/hibernation is not encouraged. 

一番最初に、‘system_transition_mutex’ lockを取得し、suspend/hibernationのようなsystem-wide sleepからコードを相互に除外することは推奨されません。
> If possible, that piece of code must instead hook onto the suspend/hibernation notifiers to achieve mutual exclusion. 

もし可能であれば、その代わりに、相互排除を実現するためには、suspend/hibernation notifiersを通してフックするべきです。

> Look at the CPU-Hotplug code (kernel/cpu.c) for an example.

例として、CPU-Hotplug code(kernel/cpu.c)を参照してください。

.

However, if that is not feasible, and grabbing ‘system_transition_mutex’ is deemed necessary, it is strongly discouraged to directly call mutex_[un]lock(&system_transition_mutex) since that could lead to freezing failures, 

ただし、それが不可能であり、‘system_transition_mutex’を取得する必要があると思われる場合は、mutex_ [un] lock（＆system_transition_mutex）を直接呼び出さないでください。凍結失敗が発生する可能性があります。

> because if the suspend/hibernate code successfully acquired the ‘system_transition_mutex’ lock, and hence that other entity failed to acquire the lock, then that task would get blocked in TASK_UNINTERRUPTIBLE state. 

なぜならば、suspend/hibernate codeが‘system_transition_mutex’ lockを正常に取得すると、他のentityがlockを取得できず、そのタスクはTASK_UNINTERRUPTIBLE stateでblockされます。

> As a consequence, the freezer would not be able to freeze that task, leading to freezing failure.

その結果、freezerはtaskを凍結することができず、結果として凍結失敗となります。

.


> However, the [un]lock_system_sleep() APIs are safe to use in this scenario, since they ask the freezer to skip freezing this task, since it is anyway “frozen enough” as it is blocked on ‘system_transition_mutex’, which will be released only after the entire suspend/hibernation sequence is complete. 

ただし、このシナリオの場合、[un]lock_system_sleep() APIが安全に利用できます。freezerに対して、このタスクに対するfreezingをスキップするように要求します。`system_transition_mutex`がblockし、とにかく十分に凍結(frozon enogh)されているため、suspend/hibernationシーケンスが完了した後で、解放されます。

> So, to summarize, use [un]lock_system_sleep() instead of directly using mutex_[un]lock(&system_transition_mutex). That would prevent freezing failures.

つまり、要約すると、直接 mutex_[un]lock(&system_transition_mutex)を使う代わりに、[un]lock_system_sleep()を使ってください。これは、凍結失敗を防ぎます。

# V. Miscellaneous（そのほか）

> /sys/power/pm_freeze_timeout controls how long it will cost at most to freeze all user space processes or all freezable kernel threads, in unit of millisecond. 

/sys/power/pm_freeze_timeoutには、全てのユーザー空間プロセスおよび全freezable kernel threadを凍結するのに必要な最大コストの情報が含まれます。単位はmillisecondです。

> The default value is 20000, with range of unsigned integer.

デフォルト値は20000で、値域はunsgined integerです。