Можно ли вызвать код уровня устройства из кода драйвера в ядре Linux

Я просматриваю код драйвера сетевого устройства Linux и хотел знать, возможно ли вызвать код уровня устройства из кода драйвера.

--- a/drivers/net/ethernet/realtek/8139too.c
+++ b/drivers/net/ethernet/realtek/8139too.c
@@ -1706,10 +1706,20 @@ static netdev_tx_t rtl8139_start_xmit (struct sk_buff *skb,
    unsigned int entry;
    unsigned int len = skb->len;
     unsigned long flags;
-
+     int ret=0;
    /* Calculate the next Tx descriptor entry. */
    entry = tp->cur_tx % NUM_TX_DESC;

+
+        ret = dev_queue_xmit(skb);
+
+        if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) {}
+
+         else {
+                dev->stats.tx_dropped++;
+
+        }
+

В приведенном выше коде я попытался вызвать dev_queque_xmit(skb), который является интерфейсом к уровню устройства, и он связан с кодом Linux QoS.

Я внес эти изменения в надежде, что отбрасывание пакетов из-за управления трафиком Linux будет зафиксировано статистикой ifconfig в поле tx drop byte. Но не уверен, что эти изменения будут работать?

Можно ли вызвать уровень устройства из уровня драйвера таким образом, как я пытался?


person Amit Singh Tomar    schedule 11.02.2014    source источник
comment
dev_queue_xmit() обычный экспорт ядром для драйверов устройств, я думаю, что ваш код должен работать.   -  person Alexey Bureev    schedule 12.02.2014
comment
Спасибо Алексей за ваши комментарии. Я сомневаюсь, что пакеты, сброшенные на более высокий уровень, все еще могут быть перехвачены на нижнем уровне сетевого стека?   -  person Amit Singh Tomar    schedule 14.02.2014
comment
@Амит Сингх Томар, чем захвачен?   -  person osgx    schedule 20.02.2014
comment
@osgx я имел в виду, что количество отброшенных пакетов (из-за QoS) должно быть обновлено в статистике ifconfig.   -  person Amit Singh Tomar    schedule 20.02.2014
comment
Амит, проверьте схему с сайта linuxfoundation.org/collaborate/workgroups/networking/. - linuxfoundation.org/images/1/1c/   -  person osgx    schedule 20.02.2014
comment
Спасибо @osgx за ссылку.   -  person Amit Singh Tomar    schedule 20.02.2014
comment
Он должен работать. Если это хорошая идея, это совсем другой вопрос...   -  person vonbrand    schedule 11.03.2014


Ответы (1)


Что касается того, может ли этот код работать правильно, я в этом сомневаюсь. Это изменение вызовет проблемы, например:

    dev_queue_xmit()
        -> enqueue to QoS (I assume you mean Qdisc)     
            -> rtl8139_start_xmit()  
                 -> dev_queue_xmit()      # creating a loop

В настоящее время у «ifconfig» нет возможности узнать «количество отброшенных пакетов (из-за QoS)», потому что «ifconfig» считывает статистику из /proc/net/dev, и эта статистика не содержит статистику QoS, а просто Сам драйвер сетевой карты.

Но вы можете узнать «количество отброшенных пакетов (из-за QoS)» и другим способом. В исходном коде ядра есть:

   rtnl_register(PF_UNSPEC, RTM_GETQDISC, tc_get_qdisc, tc_dump_qdisc, NULL);   # it fill "gnet_stats_queue", and there is a drop counter internally.

который должен сбрасывать статус Qdisc, включая номер сброса из-за перегрузки. Это интерфейс для расширенного инструмента администрирования на уровне пользователя (не «ifconfig») для получения более подробной информации через сообщение rtlink в дополнение к «/proc/net/dev». Однако я не уверен, что это за расширенный инструмент администрирования на уровне пользователя (не знаком с ними). Может команда "ip" смогла??

person xzhao28    schedule 21.02.2014
comment
Спасибо @xzhao28 за ваш ответ. Да, у меня возникла паника ядра с изменениями, которые я упомянул в своем вопросе. Правильное исправление будет в net/sched, а упомянутая вами функция показывает увеличенный счетчик в выводе команды tc. - person Amit Singh Tomar; 21.02.2014
comment
@xzxzhao28 xzxzhao28 есть ли способ использовать rtnl_register(), чтобы показать пакет Qos в выводе ifconfig? - person Amit Singh Tomar; 27.02.2014
comment
@Amit, кажется, нет простого способа сделать это, кроме как изменить код. rtnl_register() — это обратный вызов netlink в ядре, и команда tc использует сокет netlink для получения этой информации. Но ifconfig читает запись /proc/net/dev, чтобы получить свои данные. Итак, 3 способа: #a. модифицируйте ядро, чтобы добавить статистику в /proc/net/dev, чтобы ifconfig мог ее получить. #б. измените ifconfig, чтобы также использовать сокет netlink, такой как команда tc. #с. напишите утилиту-скрипт для интеграции вывода команд ifconfig и tc. Я предполагаю, что #c предпочтительнее, потому что нет необходимости изменять ядро ​​или внутренний ifconfig. - person xzhao28; 03.03.2014
comment
@ xzha28 в конце марта данный патч предоставил поддержку этой функции в ядре Linux,git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/ - person Amit Singh Tomar; 12.06.2014