LINUX.ORG.RU

[kernel] schedule_timeout() влияет на задержку в обработке ip-пакетов?

 


0

0

Собственно, есть две машины - A и B, объединённые в сеть. На A запущен флуд-пинг по направлению к B. На B в драйвере одного устройства есть место, где вызывается
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(500);
На момент этого вызова пинг показывает, что задержка растёт, по окончанию же работы показывает, что на все пакеты был получен ответ.

Я не сильно хорошо представляю работу сети в линукс, поэтому вопрос - как schedule_timeout() влияет на обработку входящих ip/icmp пакетов и, если он эту обработку задерживает, то есть ли возможность заменить его чем-нибудь эквивалентным (чтобы выполнялось отложенное действие), но чтобы сеть не "висла"?

Спасибо.

★★
Ответ на: комментарий от fang

> Укажите, в каком модуле и какой функции вы это видели?
Модуль для одной разрабатываемой железки - так как всё в разработке - он сейчас не распространён. В функции по этим таймаутам происходит обмен с устройством, но на время таймаута, как я понял, ядро не может обрабатывать icmp-пакеты.

lv ★★
() автор топика
Ответ на: комментарий от lv

Вообще, хотелось бы побольше информации... В общем случае, на время реакции на приход пакета значение тайм-аута не влияет, поскольку процесс находится в прерываемом состоянии. Это значит, что если он перед schedule_timeout() добавляется в очередь ожидания, для которой драйвер по приходе пакета делает wakeup, то пакеты будут обрабатываться по мере поступления. Для более конкретного ответа хотелось бы видеть код.

fang
()
Ответ на: комментарий от fang

> Для более конкретного ответа хотелось бы видеть код.

Код довольно обширный, данный конкретно вызов schedule_timeout происходит в обработчике ioctl-вызова.

> Это значит, что если он перед schedule_timeout() добавляется в очередь ожидания, для которой драйвер по приходе пакета делает wakeup, то пакеты будут обрабатываться по мере поступления.


Вот тут хотелось бы по-подробнее. schedule_timeout ставится на 500 jiffies - то есть на пол секунды где-то. То есть получается, что обработка всех пакетов, пришедших в этот период откладывается до истечения этих пол секунды?
Драйвер пакеты не обрабатывает - он шедулится для взаимодействия с управляемым оборудованием в определённый интервалы времени, но это вызывает вот такой вот сайд-эффект на траффик.
Возможно тут нужно применять другой механизм для отсчёта времени перед дёрганьем оборудования - тасклеты или что-нибудь подобное - буду внимательнее читать LDD. Возможно вы что-нибудь присоветуете?

lv ★★
() автор топика
Ответ на: комментарий от lv

Ага, то есть этот ваш код напрямую работает с оборудованием. Ну тогда кошерно это делать не по тайм-аутам, а по приходу прерывания. В Linux это делается в контексте soft irq (net_rx_action()). Тонкостей передачи пакетов вверх по стеку уже не знаю.

fang
()
Ответ на: комментарий от lv

На девайсе ядро версии 2.6.16, посмотрел как в нём реализован schedule_timeout - вроде ничего неожиданного - через таймеры

... всякие проверки параметров ...

1132 expire = timeout + jiffies;
1133
1134 setup_timer(&timer, process_timeout, (unsigned long)current);
1135 __mod_timer(&timer, expire);
1136 schedule();
1137 del_singleshot_timer_sync(&timer);
1138
1139 timeout = expire - jiffies;
1140
1141 out:
1142 return timeout < 0 ? 0 : timeout;
1143 }

Почему зашедленный процесс не даёт обрабатывать ping - так и не понял :(

lv ★★
() автор топика
Ответ на: комментарий от lv

Вроде бы проблема ясна. Дело в том, что приложение, которое отсылало ioctl драйверу само работает с траффиком, но не по принципу "форкнулся, нагенерил", а по poll-у на сокетах, которые этот трафик поставляют. В результате, такой ioctl порождал задержку в обработке этого траффике, а этот траффик уже задерживал тот, который идёт от пинга. Вобщем, нужно в необходимый момент форкаться и в дочернем процессе отрабатывать этот задерживающий ioctl.

lv ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.