Running kextunload
for an IOKit kext will (if no other kexts depend on it) cause the kernel to attempt to terminate()
any instances of classes in that kext which are in the I/O Kit registry. It will then wait a bit and check if any of that kext's classes still have instances. If not, it will unload the kext. If instances remain, kextunload
fails (the terminated instances stay terminated, though; by this I mean that I/O kit matching is not re-run on their providers).
So somehow, you're still ending up with live instances.
One possibility is that your objects are refusing to
terminate()
. This can happen if they have clients that won't give up control, e.g. you can't unload the driver for a disk with a mounted file system on top. Userspace clients that don't respond to termination messages are another example.Otherwise, the instances terminate, but are not freed. Since they seem to be of two of your main driver classes, if you don't have any user clients that won't give up their claim, I'm going to go out on a limb and suggest that you might have a circular reference. If that's not it, you'll just have to hunt for
retain()
s which are not matched by arelease()
. I give some tips on how to track these down in this answer.
If the instances terminate and are deregistered, they will no longer appear in the output of the ioreg
commandline tool, so that's an easy way of checking which of the two cases applies here.