devm_kzalloc() 関数の実装を理解しようとしています。リソースを管理するために、要求されたメモリ (sizeof(struct devres) + size) を超えるメモリを割り当てています。
struct devres は次のように定義されています。2 番目のメンバーは不完全な配列です。
struct devres {
struct devres_node node;
/* -- 3 pointers */
unsigned long long data[]; /* guarantee ull alignment */
};
以下は、メモリを割り当てるソースです。
size_t tot_size = sizeof(struct devres) + size;
struct devres *dr;
dr = kmalloc_track_caller(tot_size, gfp);
if (unlikely(!dr))
return NULL;
memset(dr, 0, tot_size);
INIT_LIST_HEAD(&dr->node.entry);
dr->node.release = release;
return dr;
以下の疑問があります。. tot_size を計算していますが、struct devres では配列が不完全です。. devm_kzalloc() 関数 (以下を参照) は、要求されたメモリの開始として dr->data を返しています。配列名にその配列の開始アドレスが含まれていることがわかっている場合は、要求されたメモリよりも多くを割り当てています。つまり、unsigned long long + size のサイズです。
void * devm_kzalloc(struct device *dev, size_t size, gfp_t gfp)
{
struct devres *dr;
/* use raw alloc_dr for kmalloc caller tracing */
dr = alloc_dr(devm_kzalloc_release, size, gfp);
if (unlikely(!dr))
return NULL;
set_node_dbginfo(&dr->node, "devm_kzalloc_release", size);
devres_add(dev, dr->data);
return dr->data;
}
これを理解するのを手伝ってくれませんか。