Проблема с производительностью после перехода с KEXT без кода на DEXT - PullRequest
2 голосов
/ 06 мая 2020

Я работаю над переносом KEXT без кода на DriverKit. Он используется для отключения драйвера IOKit HID для USB-устройств, которые в режиме обновления прошивки представляют себя как HID-совместимые.

До сих пор мне удалось сопоставить пустой подкласс IOService с соответствующими устройствами. Вот пример IOKitPersonalities записей, которые я использую:

<dict>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleIdentifierKernel</key>
    <string>com.apple.kpi.iokit</string>
    <key>IOClass</key>
    <string>IOUserService</string>
    <key>IOProviderClass</key>
    <string>IOUSBHostInterface</string>
    <key>IOResourceMatch</key>
    <string>IOKit</string>
    <key>IOUserClass</key>
    <string>DriverKitTestExtension</string>
    <key>IOUserServerName</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>bConfigurationValue</key>
    <integer>1</integer>
    <key>bInterfaceNumber</key>
    <integer>0</integer>
    <key>idVendor</key>
    <integer><!-- USB Vendor ID --></integer>
    <key>idProduct</key>
    <integer><!-- USB Product ID --></integer>
</dict>

Правильно ли использовать IOUSBHostInterface в качестве класса провайдера для этого варианта использования? Я также пробовал использовать старую (устаревшую) IOUSBInterface, но у нее те же проблемы, что и у IOUSBHostInterface.

Новый DEXT работает, но я вижу некоторое снижение производительности в нашем коде обновления прошивки . Вызов libusb занимает десятки секунд. Если я использую старый KEXT, они возвращаются немедленно.

Вот несколько примеров следов проблемы:

   5 redacted 3168.0  libusb_claim_interface ..../libusb/Sources/libusb/core.c:1310
   4 redacted 3168.0  darwin_claim_interface ..../libusb/Sources/libusb/darwin_usb.c:1089
   3 IOUSBLib 1668.0  IOUSBInterfaceClass::USBInterfaceOpen(bool)
   2 IOKit 1668.0  io_service_wait_quiet
   1 libsystem_kernel.dylib 1668.0  mach_msg
   0 libsystem_kernel.dylib 1668.0  mach_msg_trap

И:

   7 redacted 1859.0  libusb_get_device_list ..../libusb/Sources/libusb/core.c:632
   6 redacted 1859.0  darwin_get_device_list ..../libusb/Sources/libusb/darwin_usb.c:780
   5 redacted 1859.0  process_new_device ..../libusb/Sources/libusb/darwin_usb.c:726
   4 redacted 1766.0  darwin_check_configuration ..../libusb/Sources/libusb/darwin_usb.c:540
   3 IOKit 1766.0  IOIteratorNext
   2 IOKit 1766.0  io_iterator_next
   1 libsystem_kernel.dylib 1766.0  mach_msg
   0 libsystem_kernel.dylib 1766.0  mach_msg_trap
   0 libsystem_kernel.dylib 1766.0  mach_msg_trap

Они записаны в инструмент «Time Profiler» с включенной функцией «Record Waiting Threads».

Могу ли я сделать что-нибудь в DEXT, чтобы решить эту проблему? Я пробовал создать подклассы IOUSBHostInterface вместо IOService, но это не имело значения.

Вот соответствующий результат выполнения «ioreg -lir c IOUSBHostInterface»:

+-o IOUSBHostInterface@0  
  | {
  |   "USBSpeed" = 1
  |   "iInterface" = 0
  |   "IOServiceLegacyMatchingRegistryID" = 4294971983
  |   "bInterfaceProtocol" = 0
  |   "bAlternateSetting" = 0
  |   "idProduct" = 
  |   "bcdDevice" = 292
  |   "USB Product Name" = 
  |   "locationID" = 338690048
  |   "bInterfaceClass" = 3
  |   "bInterfaceSubClass" = 0
  |   "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBHostFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
  |   "USBPortType" = 0
  |   "bConfigurationValue" = 1
  |   "bInterfaceNumber" = 0
  |   "USB Vendor Name" = 
  |   "IOServiceDEXTEntitlements" = (("com.apple.developer.driverkit.transport.usb"))
  |   "idVendor" = 
  |   "bNumEndpoints" = 2
  |   "IOGeneralInterest" = "IOCommand is not serializable"
  |   "IOClassNameOverride" = "IOUSBInterface"
  | }
  | 
  +-o DriverKitTestExtension  
      {
        "IOClass" = "IOUserService"
        "CFBundleIdentifier" = 
        "IOProviderClass" = "IOUSBHostInterface"
        "IOUserServerCDHash" = "faa70138281d36b53946591685ccdceba4a5d638"
        "idProduct" = 
        "IOResourceMatch" = "IOKit"
        "bConfigurationValue" = 1
        "IOProbeScore" = 90000
        "IOMatchCategory" = "com.apple.null.driver"
        "IOUserServerName" = 
        "IOMatchedPersonality" = {"IOClass"="IOUserService","CFBundleIdentifier"=" ","IOProviderClass"="IOUSBHostInterface","IOUserServerCDHash"="faa70138281d36b53946591685ccdceba4a5d638","idProduct"=,"IOResourceMatch"="IOKit","bConfigurationValue"=1,"IOMatchCategory"="com.apple.null.driver","IOUserServerName"=,"idVendor"=,"CFBundleIdentifierKernel"="com.apple.kpi.iokit","bInterfaceNumber"=0,"IOUserClass"="DriverKitTestExtension"}
        "idVendor" = 
        "CFBundleIdentifierKernel" = "com.apple.kpi.iokit"
        "bInterfaceNumber" = 0
        "IOUserClass" = "DriverKitTestExtension"
      }

Любой ввод приветствуется!

1 Ответ

1 голос
/ 15 мая 2020

Я наконец нашел проблему! Прочитав Как установить права на `com.apple.developer.driverkit.transport.usb`? , я решил поэкспериментировать с правами для моего DEXT. Это заставило меня понять, что DEXT вообще не загружался.

Я изменил права DEXT с:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.developer.driverkit</key>
    <true/>
    <key>com.apple.developer.driverkit.transport.usb</key>
    <true/>
</dict>
</plist>

на:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.developer.driverkit</key>
    <true/>
    <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
        <dict>
            <key>idVendor</key>
            <integer><!-- USB Vendor ID --></integer>
        </dict>
    </array>
</dict>
</plist>

После этого, теперь появляется сообщение журнала из моего подкласса IOService (с использованием log stream с grep). Производительность во время обновления прошивки вернулась к норме.

...