Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Подвисание HAL ф-ции чтения  (Прочитано 605 раз)
0 Пользователей и 1 Гость смотрят эту тему.
WWX
Интересующийся

ru
Offline Offline

« : 29-10-2019 14:28 » 

Доброго времени суток.

В PCIe драйвере обнаружилась странность. При чтении относительно большого (порядка 64 МБ) куска памяти PCIe устройства хост (ПК) зависает приблизительно на 10 сек. Намертво (даже мышь не двигается). Затем развисает и продолжает нормально работать.

На текущий момент чтение реализовано через READ_REGISTER_BUFFER_ULONG в ф-ции StartIo (DriverObject->DriverStartIo = StartIo;).

DMA, возможно, решит проблему, но сейчас оно не используется.

Хотелось бы понять, почему так происходит.
Процессор на хосте 4-х ядерный. В то, что устройство во время пересылки забивает всю шину, не особо верится.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 29-10-2019 16:06 » 

ваша железка нормально эти данные выдает? какую скорость она способна осилить?
если 32Мб запросить - будет на 5 сек зависать?
есть возможность время транзакции чем-то измерить, в железке прошивкой счетчиков и ловушек наставить?

StartIO выполняется на Dispatch, но вроде в многоядерном варианте должно только на данном ядре переключение задач блокировать. может так вышло что на этом же ядре принудительно все системное исполняется но вроде не должно. попробуйте тестово на низком IRQL выполнить.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
WWX
Интересующийся

ru
Offline Offline

« Ответ #2 : 30-10-2019 09:09 » 

Спасибо за быстрый ответ.

Цитата
ваша железка нормально эти данные выдает? какую скорость она способна осилить?
если 32Мб запросить - будет на 5 сек зависать?
есть возможность время транзакции чем-то измерить, в железке прошивкой счетчиков и ловушек наставить?

Данные передаются нормально, ошибок не обнаружено.
При 32 МБ задержка 6.45 сек. (судя по принтам в DebugView). (Раньше передавал немного меньше 64 МБ, а зависание длилось немного более 10 сек., так что тут вроде бы всё сходится.)
Как измерить время транзакции на плате не знаю. Могу только обернуть принтами вызов одиночной HAL ф-ции чтения.

Цитата
StartIO выполняется на Dispatch, но вроде в многоядерном варианте должно только на данном ядре переключение задач блокировать. может так вышло что на этом же ядре принудительно все системное исполняется но вроде не должно. попробуйте тестово на низком IRQL выполнить.

Ф-ция DispatchReadWrite для этого подойдёт? Не уверен, но по-моему она на PASSIVE_LEVEL выполняется.
Код:
DriverObject->MajorFunction[IRP_MJ_READ] = DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchReadWrite;
В ней вообще можно напрямую осуществлять запись / чтение без StartIo или в общем случае так лучше не делать (реентерабельность страдает).

Кстати, ф-ция IoStartPacket (которую я пока что использую) вроде бы использует глобальную спин-блокировку. Это случайно не может служить причиной зависания?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 30-10-2019 12:54 » 

может. варианта собстно два - либо что то блокируется программно, либо вдруг - аппаратно(маловероятно но вдруг).
да, подойдет. любой вариант = попробовать чтоб проверить что это из за IRQL или нет
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
WWX
Интересующийся

ru
Offline Offline

« Ответ #4 : 30-10-2019 15:01 » 

Да, если перенести вызов ф-ции чтения из StartIo в DispatchReadWrite, то ничего не виснет.
Правда такое решение, как мне кажется, не годится даже в качестве временного (DMA мне всё равно придётся прикручивать, но это долго).

Ещё остаётся неопределённость: висло из-за высокого IRQL или из-за глобальной спин-блокировки (которая, судя по всему, где только (в Windows'е) не используется).
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 31-10-2019 12:43 » 

Поднимите IRQL вручную в DispatchReadWrite. Сможете убедится что дело не в IRQL а в глобальном спинлоке)
KeRaiseIrql()/KeLowerIrql 

ЗЫ перед выходом - верните обратно само собой.

Добавлено через 2 минуты и 37 секунд:
PS а зачем вам вообще StartIO?
« Последнее редактирование: 31-10-2019 12:47 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
WWX
Интересующийся

ru
Offline Offline

« Ответ #6 : 01-11-2019 09:08 » 

Цитата
Поднимите IRQL вручную в DispatchReadWrite. Сможете убедится что дело не в IRQL а в глобальном спинлоке)
Ну, похоже что причинами подвисания служили оба этих факта.
Поднятие IRQL до DISPATCH_LEVEL (в DispatchReadWrite) также приводит к полному зависанию на несколько секунд, несмотря на то, что процессор 4-х ядерный.

Цитата
а зачем вам вообще StartIO?
Мне почему-то казалось, что осуществлять всю пересылку данных в DispatchReadWrite и завершать там IRP не слишком хорошо (даже без DMA). Сейчас вот чё-то сомневаюсь.
Так нормально вообще делать?

Может в качестве промежуточного варианта (пока DMA не подоспеет) так и сделаю, защитив пересылку каким-нибудь мьютексом (в Linux'е когда-то давным давно так и делал).
Другого варианта как избавиться от зависания без DMA я чё-то не вижу.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 01-11-2019 09:45 » 

ну если транзакция такая длинная по времени - то не хорошо что вызывающее приложение будет подвисать и перестанет на сообщения отвечать. винда его может посчитать зависшим.
другой вариант - асинхронный вызов ReadWrite (все равно пригодится даже для DMA) данные получать в отдельной нитке kernel  завершать IRP после получения.
если бы обработка была короткая . но секунд на 10 - лучше PsCreateSystemThread сделать. только с контекстом повнимательнее - чтоб доступен был вне контекста приложения.
« Последнее редактирование: 01-11-2019 09:47 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
WWX
Интересующийся

ru
Offline Offline

« Ответ #8 : 01-11-2019 12:52 » new

Спасибо за помощь (в т. ч. за наводку). Поизучаю.
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines