]> git.saurik.com Git - apple/xnu.git/blobdiff - iokit/Kernel/IOStatistics.cpp
xnu-4570.51.1.tar.gz
[apple/xnu.git] / iokit / Kernel / IOStatistics.cpp
index def362e60fff448676276e77cce1d7d5f1bc04c0..f3771602a03c174a6316689a1e9b3857719336ae 100644 (file)
@@ -27,7 +27,9 @@
  */
 
 #include <sys/sysctl.h>
  */
 
 #include <sys/sysctl.h>
+#include <kern/backtrace.h>
 #include <kern/host.h>
 #include <kern/host.h>
+#include <kern/zalloc.h>
 
 #include <IOKit/system.h>
 #include <libkern/c++/OSKext.h>
 
 #include <IOKit/system.h>
 #include <libkern/c++/OSKext.h>
@@ -259,10 +261,10 @@ void IOStatistics::onKextUnload(OSKext *kext)
                IOWorkLoopCounter *wlc;
                IOUserClientProcessEntry *uce;
 
                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);
                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 */
                }
 
                /* Free up the user client list */
@@ -520,8 +522,9 @@ void IOStatistics::unregisterWorkLoop(IOWorkLoopCounter *counter)
        }
        
        IORWLockWrite(lock);
        }
        
        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--;
        
        kfree(counter, sizeof(IOWorkLoopCounter));
        registeredWorkloops--;
        
@@ -812,8 +815,11 @@ int IOStatistics::getUserClientStatistics(sysctl_req *req)
                goto exit;
        }
 
                goto exit;
        }
 
-       SYSCTL_IN(req, &requestedLoadTag, sizeof(requestedLoadTag));
-       
+       error = SYSCTL_IN(req, &requestedLoadTag, sizeof(requestedLoadTag));
+       if (error) {
+               goto exit;
+       }
+
        LOG(2, "IOStatistics::getUserClientStatistics - requesting kext w/load tag: %d\n", requestedLoadTag);
 
        buffer = (char*)kalloc(calculatedSize);
        LOG(2, "IOStatistics::getUserClientStatistics - requesting kext w/load tag: %d\n", requestedLoadTag);
 
        buffer = (char*)kalloc(calculatedSize);
@@ -1213,8 +1219,13 @@ KextNode *IOStatistics::getKextNodeFromBacktrace(boolean_t write) {
        vm_offset_t *scanAddr = NULL;
        uint32_t i;
        KextNode *found = NULL, *ke = NULL;
        vm_offset_t *scanAddr = NULL;
        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 = backtrace((uintptr_t*)bt, btCount);
 
        if (write) {
                IORWLockWrite(lock);
 
        if (write) {
                IORWLockWrite(lock);