2015-07-16 3 views
0

В последнее время я изучаю сетевой драйвер linux, и у меня есть некоторая проблема для выравнивания памяти в структуре.выравнивание памяти в alloc_netdev_mqs

вот фрагмент кода для в сети/ядро ​​/ dev.c alloc_netdev_mqs:

alloc_size = sizeof(struct net_device) 
if(sizeof_priv) 
{ 
    alloc_size = ALIGN(alloc_size, NETDEV_ALIGN) ---------(1) 
    alloc_size += sizeof_priv; 
} 
/*ensure 32-byte alignment of whole construct*/ 
alloc_size += NETDEV_ALIGN - 1;     ----------(2) 

В (1) место, я думаю, что это разумно сделать ALIGN, так как мы хотим, чтобы выровнять-структуру net_device для множителя NETDEV_ALIGN.

Но в (2) месте, чтобы сделать выравнивание, почему бы не использовать: ALIGN (alloc_size, NETDEV_ALIGN) снова ??

, например, если мы имеем: net_device 3 байта, NETDEV_ALIGN 4 байта и частного дата 2 байта:

в (1) место мы имеем ALIGN (3, 4) => длину 4 байта затем в (личных данных размер) + (размер нетто-устройства) = 4 + 2 = 6 байт

в (2) почему бы не использовать ALIGN (6, 4) => 8byte ??

Я просто не могу понять, почему, а не найти ответ по поиску. Любая помощь будет оценена!

ответ

0

Дело в том, что NETDEV_ALIGN = 32 больше, чем выравнивание, предоставляемое kmalloc (не более 16 байт). Из-за этого выравнивания структуры принудительно, используя дополнительное заполнение:

p = kzalloc(alloc_size,...); 
.... 
dev = PTR_ALIGN(p, NETDEV_ALIGN); 
dev->padded = (char *)dev - (char *)p; 

Дополнительное значение NETDEV_ALIGN - 1 используется для обеспечения байтов для заполнения (которое никогда не может превышать это значение).

+0

@AnakinTung: выравнивание gautances 'kmalloc' (и связанных функций), подходящее для любого ** родного типа **, которое соответствует требуемому размеру. Например, на x86_64 указатель имеет размер 8 байтов и должен быть выровнен на 8 байтов для правильной работы. Этот тип является наиболее ограниченным по выравниванию для данной арки, поэтому даже вы выделяете 1024 байта, 'kmalloc' может вернуться, например, 0x ************** 20. Как вы можете видеть, это значение не выровнено на 1024 байта, но только на 8 байтов. – Tsyvarev

+0

Вы имеете в виду, что указатель, возвращаемый kmalloc, не выровнен по 32 байтам, поэтому нам нужно добавить NETDEV_ALIGN, чтобы убедиться, что заполненных битов достаточно, не так ли? –

+0

@AnakinTung: Да, я имею в виду именно это. – Tsyvarev

Смежные вопросы