私はそれに気づいたstruct pid
。
pid.h、このメンバーはnumbers
サイズ 1 の配列で定義されます。
struct pid
{
refcount_t count;
unsigned int level;
spinlock_t lock;
/* lists of tasks that use this pid */
struct hlist_head tasks[PIDTYPE_MAX];
struct hlist_head inodes;
/* wait queue for pidfd notifications */
wait_queue_head_t wait_pidfd;
struct rcu_head rcu;
struct upid numbers[1];
};
しかしpid.c、メンバーにアクセスするには、ゼロ以外のインデックスを使用してください。
pid->numbers[i].nr = nr;
線を越えずにどのように機能しますか?
答え1
これは、現在の標準構文を使用していなくても柔軟な配列のバリエーションですstruct upid numbers[];
。一般的なアイデアは、すべてのフィールドに対してこれらの構造に十分なスペースを割り当て、構造の最後に配列の実際のサイズに十分なスペースを割り当てることです。
これらの構造はキャッシュに割り当てられ、サイズ計算を見ることができます。create_pid_cachep
:
len = sizeof(struct pid) + level * sizeof(struct upid);
struct pid
これは与えられたレベルで十分なスペースを割り当てます(ゼロから始まるので、1つにスペースを割り当てますstruct upid
)。
struct pid
numbers
配列の要素のためのスペース自体があります。レベル 0 キャッシュの割り当てと使用KMEM_CACHE
、そして期待する完全なキャッシュ項目を表す単一構造。
ここ数年、これらすべてのアレイの使用を標準化された柔軟なアレイに切り替えることに専念してきました。詳細については、次を参照してください。カーネル自己保護プロジェクトに関するGustavo AR Silvaによる最近の講演2022年カーネルレシピ。