Поделиться через


Обнаружение зависания UE: шаги 1–14

Шаги 1–14 для обнаружения зависания UE описаны ниже. Шаги соответствуют схеме, показанной в потоке обнаружения зависания и восстановления UE.

В этом примере используется OID_SET_POWER.

  1. NDIS получает системный IRP питания или активные ссылки сетевого адаптера удаляются до 0.

  2. NDIS создает OID_SET_POWER D3 для драйвера WDI.

  3. WDI устанавливает таймер для команды WDI (M1), включая задачу перед отправкой идентификатора WDI вниз в LE. Если команда является задачей, для нее также устанавливается дополнительный таймер. Время ожидания обоих таймеров может истекло, но не более одного из них может активировать восстановление сброса.

  4. WDI отправляет команду WDI в LE. Для le le рекомендуется запомнить WDI OID в структуре адаптера, если ему требуется команда встроенного ПО для завершения OID. Когда встроенное ПО завершает задание для WDI OID, LE завершает OID и удаляет его из структуры адаптера. Так как WDI сериализует идентификаторы OID в LE, для запоминания ожидающего объекта WDI требуется только один слот. Если команда встроенного ПО зависла, LE может вернуть OID в любое время, но не позже, чем при неожиданном удалении (это может быть в контексте неожиданного удаления) на шаге 17, когда встроенное ПО было отключено. В других случаях le le просто завершает WDI OID, когда встроенное ПО выполняет соответствующее задание, независимо от того, до или после обратного вызова диагностики. Если le le необходимо запомнить WDI OID после диагностики, ему требуется другой слот для его запоминания. Однако для идентификаторов OID, полученных после диагностики, LE не должен касаться встроенного ПО, чтобы избежать каскадных зависаний.

  5. Le отправляет команду встроенному ПО.

  6. Если время ожидания команды встроенного ПО истекло, это может быть вызвано тем, что встроенное ПО зависло или занимает слишком много времени.

    • Если встроенное ПО просто занимает слишком много времени для выполнения команды после истечения времени ожидания, le может завершить команду WDI. UE обрабатывает его соответствующим образом.
    • Если встроенное ПО зависло, команда WDI не будет выполнена в ближайшее время. Le должен завершить его при неожиданном удалении на шаге 16, когда оборудование было сброшено, поэтому его безопасно выполнить без специальной обработки для потенциального состояния гонки.
  7. Таймер WDI срабатывает для создания команды диагностики WDI. Эта команда WDI является вызовом драйвера LE MiniportWdiAdapterHangDiagnose, а не WDI OID.

  8. LE собирает состояния регистра управления оборудованием и, при необходимости, полное состояние встроенного ПО.

    • Предполагается, что драйвер IHV будет собирать содержимое регистра оборудования размером не более 1 КБ и возвращать его в функции. Кроме того, в подготовительной среде LE также следует попытаться создать дамп контекста встроенного ПО в файлы, чтобы IHV вел тщательную отладку после вскрытия. Параметр можно реализовать в виде раздела реестра для управления сбором аппаратных регистров и образа встроенного ПО.
    • Le также помечает текущую команду для отмены. Если завершение команды гонки, чтобы победить диагноз, это приемлемо, если LE ничего не делает для этой команды.
    • Если эта команда находится в состоянии ожидания, UE может отправлять дополнительные команды WDI в результате сброса. Это команды в режиме выполнения или команды очистки. После вызова диагностики le должен обработать их, не касаясь встроенного ПО.
  9. WDI получает состояние регистра управления.

  10. WDI помечает команду зависания WDI, чтобы она была указана позже le.

  11. WDI возвращает (завершает) команду NDIS без завершения WDI. Это безопасно, так как WDI создает двойные буферы команд NDIS.

  12. WDI вызывает NDIS для сброса и вызывает NdisWriteErrorLogEntry с кодом ошибкиNDIS_ERROR_CODE_HARDWARE_FAILURE (0xc000138a). В результате в журнале системных событий будет записано событие с именем модуля LE. Идентификатор события ошибки автоматически отображается как (0xc000138a | 0xffff) – 0n5002. Если le также использует тот же код ошибки для записи журналов ошибок, первое значение DWORD данных должно содержать набор больших битов (0x80000000), чтобы легко разделять события с помощью LE. WDI использует 0x00000000 для 0x7fffffff первых данных DWORD.

  13. Вызов возвращается.

  14. NDIS завершает IRP.

После этого NDIS вызывает шину, чтобы неожиданно удалить и повторно перечислить нас. Важно отметить, что WDI дважды буферизует команды NDIS, чтобы не ждать, пока команда WDI вернется, чтобы завершить команду NDIS. Это избавляет от необходимости выполнения логики отмены, которые, как известно, сложны.

Выполнение OID_SET_POWER NDIS необходимо, чтобы избежать взаимоблокировки операций PnP. Все события изменения состояния PnP и состояния питания сериализуются. Это означает, что если OID питания set не возвращается, NDIS не может вернуть IRP питания Set, что означает, что восстановление сброса блокируется с Surprise-Remove IRP.

MiniportWdiAdapterHangDiagnose

Сброс (неожиданное удаление): шаги 15–20

Поток обнаружения зависаний и восстановления UE