DRMレンダリングノード番号

DRMレンダリングノード番号

デジタル権限管理が必要な理由レンダーノード番号付けは128から始まり/dev/dri/renderD<X>、特権インターフェイスは/dev/dri/card<X>0から始まりますか?

$ ls -al /dev/dri/
total 0
drwxr-xr-x   3 root root        100 Nov 21 07:46 .
drwxr-xr-x  23 root root       6040 Nov 22 11:09 ..
drwxr-xr-x   2 root root         80 Nov 21 07:46 by-path
crw-rw----+  1 root video  226,   0 Nov 21 07:46 card0
crw-rw----+  1 root render 226, 128 Nov 21 07:46 renderD128

答え1

特権DRIインターフェースが最初に提供され、最初は固定された週番号226が割り当てられました。ただ

ARMデバイスとGPGPUコンピューティングデバイスの進化が証明され、ディスプレイモードの設定とレンダリングは別々のデバイスとしてアクセスする必要があります。レンダーノードの開発。 128より大きい補助装置番号が割り当てられているようですが、これを明確に説明する文書をすばやく見つけることはできません。

装置番号割当コードは次から始まる。drm_dev_init()この関数はdrivers/gpu/drm/drm_drv.cカーネルソースコードにあります。次から始まった631番国道それはdrm_minor_alloc同じファイルの機能:

if (drm_core_check_feature(dev, DRIVER_RENDER)) {
    ret = drm_minor_alloc(dev, DRM_MINOR_RENDER);
    if (ret)
        goto err;
}

ret = drm_minor_alloc(dev, DRM_MINOR_PRIMARY);
if (ret)
    goto err;

それはidr_alloc()存在するlib/idr.c

r = idr_alloc(&drm_minors_idr,
          NULL,
          64 * type,
          64 * (type + 1),
          GFP_NOWAIT);

パラメータは次のとおりですidr_alloc()

* idr_alloc() - Allocate an ID.
* @idr: IDR handle.
* @ptr: Pointer to be associated with the new ID.
* @start: The minimum ID (inclusive).
* @end: The maximum ID (exclusive).
* @gfp: Memory allocation flags.

ドライバがこのDRIVER_RENDER機能をサポートしてレンダリングノードをサポートしている場合は、idr_allocまずレンダリングノードを割り当ててからマスターノードを割り当てるために2回呼び出されます。それ以外の場合は、プライマリノードのみが割り当てられます。

定数はDRM_MINOR_*次に定義されます。include/drm/drm_file.h:

/* Note that the order of this enum is ABI (it determines
 * /dev/dri/renderD* numbers).
 */
enum drm_minor_type {
    DRM_MINOR_PRIMARY,
    DRM_MINOR_CONTROL,
    DRM_MINOR_RENDER,
};

これが1つなので、その値はそれぞれ0、1、2ですenumDRM_MINOR_PRIMARYDRM_MINOR_CONTROLDRM_MINOR_RENDER

これにより、0 <= x < 64の範囲のマイナーデバイス番号がプライマリインターフェイスノードに割り当てられ、64 <= x < 128がDRM_MINOR_Controlノードに割り当てられます(いずれにせよ...現在は6.0.xでは使用されていないようです) )。カーネル? ) と 128 <= x < 192 を DRM_MINOR_RENDER ノードに追加します。

次に、デバイスのsysfs名をdrivers/gpu/drm/drm_sysfs.c関数drm_sysfs_minor_alloc()の名前の一部としてマイナー番号を使用します。

if (minor->type == DRM_MINOR_RENDER)
    minor_str = "renderD%d";
else
    minor_str = "card%d";

[...]

r = dev_set_name(kdev, minor_str, minor->index);

そして、udevデフォルトのデバイス名を変更するためにルールを使用しない限り、sysfs名はデバイスノードの名前になります。

これは、これがレンダリングノードの場合、デフォルトのデバイス名を割り当てるときにマイナーデバイスノード番号から128を引く条件句を追加することに気づいた人がいなかったためです。

また注意事項この2013年のDRM開発ブログ投稿説明する:

レンダーノードを理解することも重要です。 いいえ特定のカードにバインドします。内部的には、レガシーノードと同じドライバによって作成されますが、ユーザースペースはレンダリングノードとレガシー/モード設定ノード間の接続を想定してはいけません。逆に、ユーザースペースにハードウェアアクセラレーションが必要な場合はオンにする必要があります。 どの ノードを使用しています。

[...]

「特定のカードのレンダリングノードをどのように見つけますか?」などの質問は意味がありません。はい、ドライバー固有のユーザースペースは、どのレンダーノードがどのドライバーによって作成されたか、どのレンダーノードがどのドライバーによって作成されたかを確認できますが、ドライバーではない特定のユーザースペースでこれを行うべきではありません。

これらの意図を念頭に置いて、意図的に128から始まるレンダリングノード番号を指定することは合理的です(同じカードの潜在的に間違った仮定を中断し、card0常に参照するため)。renderD0

関連情報