web-dev-qa-db-ja.com

Linuxドライバープログラミングにおけるdevm_kzalloc()とkzalloc()の違いは何ですか

デバイスドライバプログラムでdevm_kzalloc()kzalloc()を見つけました。しかし、これらの機能をいつどこで使用するかはわかりません。誰でもこれらの機能の重要性とその使用法を指定できますか?.

17

kzalloc()kmalloc()のようにカーネルメモリを割り当てますが、割り当てられたメモリをゼロで初期化します。 devm_kzalloc()は管理されていますkzalloc()。管理対象機能に割り当てられたメモリは、デバイスに関連付けられています。デバイスがシステムから切り離されるか、デバイスのドライバーがアンロードされると、そのメモリは自動的に解放されます。複数の管理対象リソース(メモリまたはその他のリソース)がデバイスに割り当てられている場合、最後に割り当てられたリソースが最初に解放されます。

管理対象リソースは、任意の時点での初期化の失敗と、初期化の成功とそれに続くデバイスの削除の両方で、ドライバーが正しく動作することを保証するのに非常に役立ちます。

管理対象リソース(メモリまたはその他のリソース)は、デバイスのプローブを担当するコードで使用されることを意図していることに注意してください。デバイスはシステムから切断せずに閉じることができるため、これらは通常、デバイスを開くために使用されるコードに対して間違った選択です。デバイスを閉じるには、リソースを手動で解放する必要があります。これにより、管理対象リソースの目的が損なわれます。

kzalloc()で割り当てられたメモリは、kfree()で解放する必要があります。 devm_kzalloc()で割り当てられたメモリは自動的に解放されます。 devm_kfree()で解放できますが、通常は、マネージメモリの割り当てがタスクに適していないことを示しています。

35
proski

簡単に言うと、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()はありません。