デバイスドライバプログラムでdevm_kzalloc()
とkzalloc()
を見つけました。しかし、これらの機能をいつどこで使用するかはわかりません。誰でもこれらの機能の重要性とその使用法を指定できますか?.
kzalloc()
はkmalloc()
のようにカーネルメモリを割り当てますが、割り当てられたメモリをゼロで初期化します。 devm_kzalloc()
は管理されていますkzalloc()
。管理対象機能に割り当てられたメモリは、デバイスに関連付けられています。デバイスがシステムから切り離されるか、デバイスのドライバーがアンロードされると、そのメモリは自動的に解放されます。複数の管理対象リソース(メモリまたはその他のリソース)がデバイスに割り当てられている場合、最後に割り当てられたリソースが最初に解放されます。
管理対象リソースは、任意の時点での初期化の失敗と、初期化の成功とそれに続くデバイスの削除の両方で、ドライバーが正しく動作することを保証するのに非常に役立ちます。
管理対象リソース(メモリまたはその他のリソース)は、デバイスのプローブを担当するコードで使用されることを意図していることに注意してください。デバイスはシステムから切断せずに閉じることができるため、これらは通常、デバイスを開くために使用されるコードに対して間違った選択です。デバイスを閉じるには、リソースを手動で解放する必要があります。これにより、管理対象リソースの目的が損なわれます。
kzalloc()
で割り当てられたメモリは、kfree()
で解放する必要があります。 devm_kzalloc()
で割り当てられたメモリは自動的に解放されます。 devm_kfree()
で解放できますが、通常は、マネージメモリの割り当てがタスクに適していないことを示しています。
簡単に言うと、devm_kzalloc()とkzalloc()はどちらもデバイスドライバーのメモリ割り当てに使用されますが、違いは、kzalloc()によってメモリを割り当てる場合、そのデバイスドライバーのライフサイクルが終了したとき、またはいつメモリを解放する必要があるかです。カーネルからアンロードされますが、devm_kzalloc()で同じことを行う場合、メモリの解放について心配する必要はありません。そのメモリは、デバイスライブラリ自体によって自動的に解放されます。
どちらもまったく同じことをしますが、devm_kzallocを使用することで、メモリを解放するオーバーヘッドがプログラマーから解放されます。
例を挙げて説明しましょう。最初の例はkzallocを使用しています
static int pxa3xx_u2d_probe(struct platform_device *pdev)
{
int err;
u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL); 1
if (!u2d)
return -ENOMEM;
u2d->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(u2d->clk)) {
err = PTR_ERR(u2d->clk); 2
goto err_free_mem;
}
...
return 0;
err_free_mem:
kfree(u2d);
return err;
}
static int pxa3xx_u2d_remove(struct platform_device *pdev)
{
clk_put(u2d->clk);
kfree(u2d); 3
return 0;
}
この例では、関数pxa3xx_u2d_remove()でこれを行うことができます。kfree(u2d)(3で示される行)は、u2dによって割り当てられたメモリを解放するためにあり、devm_kzalloc()を使用して同じコードを表示します。
static int pxa3xx_u2d_probe(struct platform_device *pdev)
{
int err;
u2d = devm_kzalloc(&pdev->dev, sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL);
if (!u2d)
return -ENOMEM;
u2d->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(u2d->clk)) {
err = PTR_ERR(u2d->clk);
goto err_free_mem;
}
...
return 0;
err_free_mem:
return err;
}
static int pxa3xx_u2d_remove(struct platform_device *pdev)
{
clk_put(u2d->clk);
return 0;
}
同じことがdevm_kzalloc()によって行われるため、関数を解放するためのkfree()はありません。