#linux #linux-kernel #kernel #linux-device-driver
#linux #linux-ядро #ядро #linux-драйвер устройства
Вопрос:
У меня есть конкретный вопрос относительно использования модуля net_device в ядре Linux.
Давайте рассмотрим этот пример кода, пожалуйста.
Когда я инициализирую свое устройство, я вызываю alloc_netdev и предоставляю ему размер личных данных, чтобы он правильно их распределял.
Теперь, что происходит, когда я вызываю snull_cleanup, когда я хочу прекратить использование этого устройства. я вижу, что в основном это свободная структура (включая личные данные).
Вопрос в том, что, если выполняемый в данный момент код является внутренней функцией внутри моего модуля устройства, которая использует личные данные, полученные cally netdev_priv(), содержит ссылку на личные данные, и внезапно я получаю переключение контекста в пространстве ядра на функцию snull_cleanup, которая освобождаетличные данные.
Затем, при переключении контекста обратно на функцию, содержащую ссылку на личные данные, не получу ли я ссылку на освобожденную структуру?
Я был бы рад, если бы вы могли решить эту проблему для меня, спасибо
Комментарии:
1. Я не вижу никакого освобождения
snull_priv
структуры. Можете ли вы уточнить и вставить фрагменты кода?2. ДА. Когда snull_cleanup вызывает free_netdev , модуль netdev освобождает всю структуру, включая личные данные.
Ответ №1:
Моя первоначальная мысль заключалась в том, что это не имеет смысла: это ваши личные данные, поэтому разбирайтесь сами — вы их выделили, поэтому вам нужно их освободить. Это обычная схема для личных данных — вы можете увидеть ее, например, в struct bio
. Но то, что я увидел, было действительно грязным взломом.
Итак, я просмотрел код alloc_netdev, и вот что я нашел.
Вы не выделяете свою частную структуру, вы можете передать размер alloc_netdev
. Если вы передадите размер своих личных данных в alloc_netdev
(первый аргумент), то это произведет выделение размера:
ALIGN_OF_32( sizeof(struct net_device) sizeof(struct snull_private) )
Таким образом, ваши личные данные являются неотъемлемой частью struct net_device — они добавляются после него
Whole struct net_device
you're working with
-------------------------------
| --------------------------- |
| | | |
| | | |
| | Actual struct net_device | |
| | | |
| | | |
| --------------------------- |
| | --> Your private data <-- | |
| --------------------------- |
| | Alignment to 32 | |
| --------------------------- |
-------------------------------
Для получения личных данных, которые вы используете netdev_priv
, это просто добавляет размер struct net_device
к указателю, таким образом получая начальный адрес ваших личных данных:
static inline void *netdev_priv(const struct net_device *dev)
{
return (char *)dev ALIGN(sizeof(struct net_device), NETDEV_ALIGN);
}
Освобождение устройства с free_netdev
помощью освободит всю структуру, включая личные данные. Хотя это будет сделано не сразу, так что вы сможете получить доступ к своим данным через некоторое время.
Эта сложная вещь сделает работу с вашим структурным кэшем удобной, что повысит вашу производительность. Похоже, что предполагается, что эти личные данные имеют смысл только для срока службы net_device, поэтому, если вы хотите получить некоторые данные после уничтожения net_device, вы можете встроить сам net_device в свою структуру, поэтому ваша структура будет своего рода оболочкой.
Комментарии:
2. Я обновил свой ответ, спасибо, что указали мне правильное направление.