从无代码 KEXT 迁移到 DEXT 后的性能问题
Performance issue after migrating from codeless KEXT to DEXT
我正在努力将无代码 KEXT 迁移到 DriverKit。它用于为在固件升级模式下显示为符合 HID 标准的 USB 设备禁用 IOKit HID 驱动程序。
到目前为止,我已经设法将 IOService
的空子 class 匹配到相关设备。
这是我正在使用的 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
作为此用例的提供者 class 是否正确?我也尝试过使用旧的(已弃用)IOUSBInterface
,但它与 IOUSBHostInterface
.
存在相同的问题
新的 DEXT 正在运行,但我发现我们的固件更新代码中出现了一些糟糕的性能回归。调用 libusb 需要数十秒。如果我使用旧的 KEXT,它们会立即 return。
以下是问题的一些示例痕迹:
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
这些记录在启用 "Record Waiting Threads" 的 "Time Profiler" 仪器中。
我可以在 DEXT 中做些什么来解决这个问题吗?我试过 subclassing IOUSBHostInterface
而不是 IOService
,但这没有什么区别。
这是 运行 "ioreg -lirc 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"
}
欢迎任何意见!
终于找到问题了!阅读 后,我决定尝试使用 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
)。固件升级期间性能恢复正常
我正在努力将无代码 KEXT 迁移到 DriverKit。它用于为在固件升级模式下显示为符合 HID 标准的 USB 设备禁用 IOKit HID 驱动程序。
到目前为止,我已经设法将 IOService
的空子 class 匹配到相关设备。
这是我正在使用的 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
作为此用例的提供者 class 是否正确?我也尝试过使用旧的(已弃用)IOUSBInterface
,但它与 IOUSBHostInterface
.
新的 DEXT 正在运行,但我发现我们的固件更新代码中出现了一些糟糕的性能回归。调用 libusb 需要数十秒。如果我使用旧的 KEXT,它们会立即 return。
以下是问题的一些示例痕迹:
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
这些记录在启用 "Record Waiting Threads" 的 "Time Profiler" 仪器中。
我可以在 DEXT 中做些什么来解决这个问题吗?我试过 subclassing IOUSBHostInterface
而不是 IOService
,但这没有什么区别。
这是 运行 "ioreg -lirc 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"
}
欢迎任何意见!
终于找到问题了!阅读
我更改了 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
)。固件升级期间性能恢复正常