Возможное удаление ссылок на личные данные с помощью net_device

#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 в свою структуру, поэтому ваша структура будет своего рода оболочкой.

Комментарии:

1. Ну, в коде alloc_netdev, похоже, что личные данные выделяются вместе с самой структурой net_device в том же kzalloc. Итак, я предположил, что когда вы освобождаете структуру устройства (в netdev_freemem в dev.c), вы также освобождаете личные данные. Возможно, я ошибаюсь, я был бы рад, если бы вы могли указать мне на мою ошибку. Спасибо

2. Я обновил свой ответ, спасибо, что указали мне правильное направление.