]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOStatistics.cpp
xnu-2782.1.97.tar.gz
[apple/xnu.git] / iokit / Kernel / IOStatistics.cpp
index 9235b293d8f6c003c10fb016d7ff879cd8f06754..6e72eb49592685df4e862d305f39db7ff9e60293 100644 (file)
@@ -28,6 +28,7 @@
 
 #include <sys/sysctl.h>
 #include <kern/host.h>
+#include <kern/zalloc.h>
 
 #include <IOKit/system.h>
 #include <libkern/c++/OSKext.h>
@@ -39,7 +40,6 @@
 #include <IOKit/IOKitDebug.h>
 
 #if IOKITSTATS
-
 bool IOStatistics::enabled = false;
 
 uint32_t IOStatistics::sequenceID = 0;
@@ -178,14 +178,10 @@ void IOStatistics::initialize()
                return;
        }
 
-#if DEVELOPMENT || DEBUG
-       /* Always enabled in development and debug builds. */
-#else
-       /* Only enabled in release builds if the boot argument is set. */
+       /* Only enabled if the boot argument is set. */
        if (!(kIOStatistics & gIOKitDebug)) {
                return;
        }
-#endif 
        
        sysctl_register_oid(&sysctl__debug_iokit_statistics_general);
        sysctl_register_oid(&sysctl__debug_iokit_statistics_workloop);
@@ -264,10 +260,10 @@ void IOStatistics::onKextUnload(OSKext *kext)
                IOWorkLoopCounter *wlc;
                IOUserClientProcessEntry *uce;
 
-               /* Free up the list of counters */
+               /* Disconnect workloop counters; cleanup takes place in unregisterWorkLoop() */
                while ((wlc = SLIST_FIRST(&found->workLoopList))) {
                        SLIST_REMOVE_HEAD(&found->workLoopList, link);
-                       kfree(wlc, sizeof(IOWorkLoopCounter));
+                       wlc->parentKext = NULL;
                }
 
                /* Free up the user client list */
@@ -525,8 +521,9 @@ void IOStatistics::unregisterWorkLoop(IOWorkLoopCounter *counter)
        }
        
        IORWLockWrite(lock);
-
-       SLIST_REMOVE(&counter->parentKext->workLoopList, counter, IOWorkLoopCounter, link);
+       if (counter->parentKext) {
+               SLIST_REMOVE(&counter->parentKext->workLoopList, counter, IOWorkLoopCounter, link);
+       }
        kfree(counter, sizeof(IOWorkLoopCounter));
        registeredWorkloops--;
        
@@ -1219,7 +1216,12 @@ KextNode *IOStatistics::getKextNodeFromBacktrace(boolean_t write) {
        uint32_t i;
        KextNode *found = NULL, *ke = NULL;
 
-       btCount = OSBacktrace(bt, btCount);
+       /*
+        * Gathering the backtrace is a significant source of
+        * overhead. OSBacktrace does many safety checks that
+        * are not needed in this situation.
+        */
+       btCount = fastbacktrace((uintptr_t*)bt, btCount);
 
        if (write) {
                IORWLockWrite(lock);
@@ -1230,7 +1232,7 @@ KextNode *IOStatistics::getKextNodeFromBacktrace(boolean_t write) {
        /* Ignore first levels */
        scanAddr = (vm_offset_t *)&bt[btMin - 1];
 
-       for (i = 0; i < btCount; i++, scanAddr++) {
+       for (i = btMin - 1; i < btCount; i++, scanAddr++) {
                ke = RB_ROOT(&kextAddressHead);
                while (ke) {
                        if (*scanAddr < ke->address) {