Loading...
--- xnu/xnu-12377.101.15/iokit/Kernel/IOStatistics.cpp
+++ xnu/xnu-3789.41.3/iokit/Kernel/IOStatistics.cpp
@@ -2,7 +2,7 @@
* Copyright (c) 2010 Apple Computer, Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
- *
+ *
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
@@ -11,10 +11,10 @@
* unlawful or unlicensed copies of an Apple operating system, or to
* circumvent, violate, or enable the circumvention or violation of, any
* terms of an Apple operating system software license agreement.
- *
+ *
* Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this file.
- *
+ *
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
@@ -22,7 +22,7 @@
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
- *
+ *
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
@@ -64,7 +64,7 @@
#define LOG(level, format, ...) \
do { \
if (level <= LOG_LEVEL) \
- printf(format, ##__VA_ARGS__); \
+ printf(format, ##__VA_ARGS__); \
} while (0)
/* Locks */
@@ -77,16 +77,14 @@
IOStatistics::KextTreeHead IOStatistics::kextHead = RB_INITIALIZER(&IOStatistics::kextHead);
-int
-IOStatistics::kextNodeCompare(KextNode *e1, KextNode *e2)
-{
- if (e1->kext < e2->kext) {
- return -1;
- } else if (e1->kext > e2->kext) {
- return 1;
- } else {
- return 0;
- }
+int IOStatistics::kextNodeCompare(KextNode *e1, KextNode *e2)
+{
+ if (e1->kext < e2->kext)
+ return -1;
+ else if (e1->kext > e2->kext)
+ return 1;
+ else
+ return 0;
}
RB_GENERATE(IOStatistics::KextTree, KextNode, link, kextNodeCompare);
@@ -95,16 +93,14 @@
IOStatistics::KextAddressTreeHead IOStatistics::kextAddressHead = RB_INITIALIZER(&IOStatistics::kextAddressHead);
-int
-IOStatistics::kextAddressNodeCompare(KextNode *e1, KextNode *e2)
-{
- if (e1->address < e2->address) {
- return -1;
- } else if (e1->address > e2->address) {
- return 1;
- } else {
- return 0;
- }
+int IOStatistics::kextAddressNodeCompare(KextNode *e1, KextNode *e2)
+{
+ if (e1->address < e2->address)
+ return -1;
+ else if (e1->address > e2->address)
+ return 1;
+ else
+ return 0;
}
RB_GENERATE(IOStatistics::KextAddressTree, KextNode, addressLink, kextAddressNodeCompare);
@@ -113,82 +109,71 @@
IOStatistics::ClassTreeHead IOStatistics::classHead = RB_INITIALIZER(&IOStatistics::classHead);
-int
-IOStatistics::classNodeCompare(ClassNode *e1, ClassNode *e2)
-{
- if (e1->metaClass < e2->metaClass) {
- return -1;
- } else if (e1->metaClass > e2->metaClass) {
- return 1;
- } else {
- return 0;
- }
+int IOStatistics::classNodeCompare(ClassNode *e1, ClassNode *e2) {
+ if (e1->metaClass < e2->metaClass)
+ return -1;
+ else if (e1->metaClass > e2->metaClass)
+ return 1;
+ else
+ return 0;
}
RB_GENERATE(IOStatistics::ClassTree, ClassNode, tLink, classNodeCompare);
/* Workloop dependencies */
-int
-IOWorkLoopCounter::loadTagCompare(IOWorkLoopDependency *e1, IOWorkLoopDependency *e2)
-{
- if (e1->loadTag < e2->loadTag) {
- return -1;
- } else if (e1->loadTag > e2->loadTag) {
- return 1;
- } else {
- return 0;
- }
+int IOWorkLoopCounter::loadTagCompare(IOWorkLoopDependency *e1, IOWorkLoopDependency *e2) {
+ if (e1->loadTag < e2->loadTag)
+ return -1;
+ else if (e1->loadTag > e2->loadTag)
+ return 1;
+ else
+ return 0;
}
RB_GENERATE(IOWorkLoopCounter::DependencyTree, IOWorkLoopDependency, link, IOWorkLoopCounter::loadTagCompare);
/* sysctl stuff */
-static int
+static int
oid_sysctl(__unused struct sysctl_oid *oidp, __unused void *arg1, int arg2, struct sysctl_req *req)
{
int error = EINVAL;
uint32_t request = arg2;
- if (!IOStatistics::isEnabled()) {
- return ENOENT;
- }
-
- switch (request) {
- case kIOStatisticsGeneral:
- error = IOStatistics::getStatistics(req);
- break;
- case kIOStatisticsWorkLoop:
- error = IOStatistics::getWorkLoopStatistics(req);
- break;
- case kIOStatisticsUserClient:
- error = IOStatistics::getUserClientStatistics(req);
- break;
- default:
- break;
+ switch (request)
+ {
+ case kIOStatisticsGeneral:
+ error = IOStatistics::getStatistics(req);
+ break;
+ case kIOStatisticsWorkLoop:
+ error = IOStatistics::getWorkLoopStatistics(req);
+ break;
+ case kIOStatisticsUserClient:
+ error = IOStatistics::getUserClientStatistics(req);
+ break;
+ default:
+ break;
}
return error;
}
-
-SYSCTL_NODE(_debug, OID_AUTO, iokit_statistics, CTLFLAG_RW | CTLFLAG_LOCKED, NULL, "IOStatistics");
+
+SYSCTL_NODE(_debug, OID_AUTO, iokit_statistics, CTLFLAG_RW | CTLFLAG_LOCKED, 0, "IOStatistics");
static SYSCTL_PROC(_debug_iokit_statistics, OID_AUTO, general,
- CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
- NULL, kIOStatisticsGeneral, oid_sysctl, "S", "");
+ CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
+ 0, kIOStatisticsGeneral, oid_sysctl, "S", "");
static SYSCTL_PROC(_debug_iokit_statistics, OID_AUTO, workloop,
- CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_KERN | CTLFLAG_LOCKED,
- NULL, kIOStatisticsWorkLoop, oid_sysctl, "S", "");
+ CTLTYPE_STRUCT | CTLFLAG_RD | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
+ 0, kIOStatisticsWorkLoop, oid_sysctl, "S", "");
static SYSCTL_PROC(_debug_iokit_statistics, OID_AUTO, userclient,
- CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_KERN | CTLFLAG_LOCKED,
- NULL, kIOStatisticsUserClient, oid_sysctl, "S", "");
-
-
-void
-IOStatistics::initialize()
+ CTLTYPE_STRUCT | CTLFLAG_RW | CTLFLAG_NOAUTO | CTLFLAG_KERN | CTLFLAG_LOCKED,
+ 0, kIOStatisticsUserClient, oid_sysctl, "S", "");
+
+void IOStatistics::initialize()
{
if (enabled) {
return;
@@ -198,22 +183,25 @@
if (!(kIOStatistics & gIOKitDebug)) {
return;
}
-
+
+ sysctl_register_oid(&sysctl__debug_iokit_statistics_general);
+ sysctl_register_oid(&sysctl__debug_iokit_statistics_workloop);
+ sysctl_register_oid(&sysctl__debug_iokit_statistics_userclient);
+
lock = IORWLockAlloc();
if (!lock) {
return;
}
-
- nextWorkLoopDependency = kalloc_type(IOWorkLoopDependency, Z_WAITOK);
+
+ nextWorkLoopDependency = (IOWorkLoopDependency*)kalloc(sizeof(IOWorkLoopDependency));
if (!nextWorkLoopDependency) {
return;
}
-
+
enabled = true;
}
-void
-IOStatistics::onKextLoad(OSKext *kext, kmod_info_t *kmod_info)
+void IOStatistics::onKextLoad(OSKext *kext, kmod_info_t *kmod_info)
{
KextNode *ke;
@@ -224,13 +212,15 @@
}
LOG(1, "IOStatistics::onKextLoad: %s, tag %d, address 0x%llx, address end 0x%llx\n",
- kext->getIdentifierCString(), kmod_info->id, (uint64_t)kmod_info->address, (uint64_t)(kmod_info->address + kmod_info->size));
-
- ke = kalloc_type(KextNode, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ kext->getIdentifierCString(), kmod_info->id, (uint64_t)kmod_info->address, (uint64_t)(kmod_info->address + kmod_info->size));
+
+ ke = (KextNode *)kalloc(sizeof(KextNode));
if (!ke) {
return;
}
+ memset(ke, 0, sizeof(KextNode));
+
ke->kext = kext;
ke->loadTag = kmod_info->id;
ke->address = kmod_info->address;
@@ -243,27 +233,26 @@
RB_INSERT(KextTree, &kextHead, ke);
RB_INSERT(KextAddressTree, &kextAddressHead, ke);
-
+
sequenceID++;
loadedKexts++;
lastKextIndex++;
-
+
IORWLockUnlock(lock);
}
-void
-IOStatistics::onKextUnload(OSKext *kext)
+void IOStatistics::onKextUnload(OSKext *kext)
{
KextNode sought, *found;
-
+
assert(kext);
-
+
if (!enabled) {
return;
}
LOG(1, "IOStatistics::onKextUnload: %s\n", kext->getIdentifierCString());
-
+
IORWLockWrite(lock);
sought.kext = kext;
@@ -281,7 +270,7 @@
/* Free up the user client list */
while ((uce = TAILQ_FIRST(&found->userClientCallList))) {
TAILQ_REMOVE(&found->userClientCallList, uce, link);
- kfree_type(IOUserClientProcessEntry, uce);
+ kfree(uce, sizeof(IOUserClientProcessEntry));
}
/* Remove from kext trees */
@@ -295,21 +284,21 @@
if (found == kextHint) {
kextHint = NULL;
}
-
+
/* Finally, free the class node */
- kfree_type(KextNode, found);
-
+ kfree(found, sizeof(KextNode));
+
sequenceID++;
loadedKexts--;
- } else {
+ }
+ else {
panic("IOStatistics::onKextUnload: cannot find kext: %s", kext->getIdentifierCString());
}
IORWLockUnlock(lock);
}
-void
-IOStatistics::onClassAdded(OSKext *parentKext, OSMetaClass *metaClass)
+void IOStatistics::onClassAdded(OSKext *parentKext, OSMetaClass *metaClass)
{
ClassNode *ce;
KextNode soughtKext, *foundKext = NULL;
@@ -322,17 +311,20 @@
LOG(1, "IOStatistics::onClassAdded: %s\n", metaClass->getClassName());
- ce = kalloc_type(ClassNode, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ ce = (ClassNode *)kalloc(sizeof(ClassNode));
if (!ce) {
- return;
- }
+ return;
+ }
+
+ memset(ce, 0, sizeof(ClassNode));
IORWLockWrite(lock);
/* Hinted? */
if (kextHint && kextHint->kext == parentKext) {
foundKext = kextHint;
- } else {
+ }
+ else {
soughtKext.kext = parentKext;
foundKext = RB_FIND(KextTree, &kextHead, &soughtKext);
}
@@ -344,9 +336,9 @@
ce->metaClass = metaClass;
ce->classID = lastClassIndex++;
ce->parentKext = foundKext;
-
+
/* Has superclass? */
- superClass = ce->metaClass->getSuperClass();
+ superClass = ce->metaClass->getSuperClass();
if (superClass) {
soughtClass.metaClass = superClass;
foundClass = RB_FIND(ClassTree, &classHead, &soughtClass);
@@ -355,25 +347,25 @@
SLIST_INIT(&ce->counterList);
SLIST_INIT(&ce->userClientList);
-
+
RB_INSERT(ClassTree, &classHead, ce);
SLIST_INSERT_HEAD(&foundKext->classList, ce, lLink);
-
+
foundKext->classes++;
-
+
kextHint = foundKext;
-
- sequenceID++;
+
+ sequenceID++;
registeredClasses++;
- } else {
+ }
+ else {
panic("IOStatistics::onClassAdded: cannot find parent kext: %s", parentKext->getIdentifierCString());
}
-
+
IORWLockUnlock(lock);
}
-void
-IOStatistics::onClassRemoved(OSKext *parentKext, OSMetaClass *metaClass)
+void IOStatistics::onClassRemoved(OSKext *parentKext, OSMetaClass *metaClass)
{
ClassNode sought, *found;
@@ -392,54 +384,56 @@
if (found) {
IOEventSourceCounter *esc;
IOUserClientCounter *ucc;
-
+
/* Free up the list of counters */
while ((esc = SLIST_FIRST(&found->counterList))) {
SLIST_REMOVE_HEAD(&found->counterList, link);
- kfree_type(IOEventSourceCounter, esc);
+ kfree(esc, sizeof(IOEventSourceCounter));
}
/* Free up the user client list */
while ((ucc = SLIST_FIRST(&found->userClientList))) {
SLIST_REMOVE_HEAD(&found->userClientList, link);
- kfree_type(IOUserClientCounter, ucc);
+ kfree(ucc, sizeof(IOUserClientCounter));
}
/* Remove from class tree */
RB_REMOVE(ClassTree, &classHead, found);
-
+
/* Remove from parent */
SLIST_REMOVE(&found->parentKext->classList, found, ClassNode, lLink);
-
+
/* Finally, free the class node */
- kfree_type(ClassNode, found);
-
+ kfree(found, sizeof(ClassNode));
+
sequenceID++;
registeredClasses--;
- } else {
+ }
+ else {
panic("IOStatistics::onClassRemoved: cannot find class: %s", metaClass->getClassName());
}
IORWLockUnlock(lock);
}
-IOEventSourceCounter *
-IOStatistics::registerEventSource(OSObject *inOwner)
+IOEventSourceCounter *IOStatistics::registerEventSource(OSObject *inOwner)
{
IOEventSourceCounter *counter = NULL;
ClassNode sought, *found = NULL;
boolean_t createDummyCounter = FALSE;
-
+
assert(inOwner);
if (!enabled) {
return NULL;
}
- counter = kalloc_type(IOEventSourceCounter, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ counter = (IOEventSourceCounter*)kalloc(sizeof(IOEventSourceCounter));
if (!counter) {
return NULL;
}
+
+ memset(counter, 0, sizeof(IOEventSourceCounter));
IORWLockWrite(lock);
@@ -449,7 +443,8 @@
if (inOwner->retainCount > 0xFFFFFF) {
kprintf("IOStatistics::registerEventSource - bad metaclass %p\n", inOwner);
createDummyCounter = TRUE;
- } else {
+ }
+ else {
sought.metaClass = inOwner->getMetaClass();
found = RB_FIND(ClassTree, &classHead, &sought);
}
@@ -463,14 +458,13 @@
if (!(createDummyCounter || found)) {
panic("IOStatistics::registerEventSource: cannot find parent class: %s", inOwner->getMetaClass()->getClassName());
}
-
+
IORWLockUnlock(lock);
-
+
return counter;
}
-void
-IOStatistics::unregisterEventSource(IOEventSourceCounter *counter)
+void IOStatistics::unregisterEventSource(IOEventSourceCounter *counter)
{
if (!counter) {
return;
@@ -482,13 +476,12 @@
SLIST_REMOVE(&counter->parentClass->counterList, counter, IOEventSourceCounter, link);
registeredCounters--;
}
- kfree_type(IOEventSourceCounter, counter);
-
+ kfree(counter, sizeof(IOEventSourceCounter));
+
IORWLockUnlock(lock);
}
-IOWorkLoopCounter*
-IOStatistics::registerWorkLoop(IOWorkLoop *workLoop)
+IOWorkLoopCounter* IOStatistics::registerWorkLoop(IOWorkLoop *workLoop)
{
IOWorkLoopCounter *counter = NULL;
KextNode *found;
@@ -499,10 +492,12 @@
return NULL;
}
- counter = kalloc_type(IOWorkLoopCounter, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ counter = (IOWorkLoopCounter*)kalloc(sizeof(IOWorkLoopCounter));
if (!counter) {
return NULL;
}
+
+ memset(counter, 0, sizeof(IOWorkLoopCounter));
found = getKextNodeFromBacktrace(TRUE);
if (!found) {
@@ -520,25 +515,23 @@
return counter;
}
-void
-IOStatistics::unregisterWorkLoop(IOWorkLoopCounter *counter)
+void IOStatistics::unregisterWorkLoop(IOWorkLoopCounter *counter)
{
if (!counter) {
return;
}
-
+
IORWLockWrite(lock);
if (counter->parentKext) {
SLIST_REMOVE(&counter->parentKext->workLoopList, counter, IOWorkLoopCounter, link);
}
- kfree_type(IOWorkLoopCounter, counter);
+ kfree(counter, sizeof(IOWorkLoopCounter));
registeredWorkloops--;
-
+
IORWLockUnlock(lock);
}
-IOUserClientCounter *
-IOStatistics::registerUserClient(IOUserClient *userClient)
+IOUserClientCounter *IOStatistics::registerUserClient(IOUserClient *userClient)
{
ClassNode sought, *found;
IOUserClientCounter *counter = NULL;
@@ -549,10 +542,12 @@
return NULL;
}
- counter = kalloc_type(IOUserClientCounter, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ counter = (IOUserClientCounter*)kalloc(sizeof(IOUserClientCounter));
if (!counter) {
return NULL;
}
+
+ memset(counter, 0, sizeof(IOUserClientCounter));
IORWLockWrite(lock);
@@ -562,7 +557,8 @@
if (found) {
counter->parentClass = found;
SLIST_INSERT_HEAD(&found->userClientList, counter, link);
- } else {
+ }
+ else {
panic("IOStatistics::registerUserClient: cannot find parent class: %s", sought.metaClass->getClassName());
}
@@ -571,73 +567,69 @@
return counter;
}
-void
-IOStatistics::unregisterUserClient(IOUserClientCounter *counter)
+void IOStatistics::unregisterUserClient(IOUserClientCounter *counter)
{
if (!counter) {
return;
}
-
+
IORWLockWrite(lock);
-
+
SLIST_REMOVE(&counter->parentClass->userClientList, counter, IOUserClientCounter, link);
- kfree_type(IOUserClientCounter, counter);
+ kfree(counter, sizeof(IOUserClientCounter));
IORWLockUnlock(lock);
}
-void
-IOStatistics::attachWorkLoopEventSource(IOWorkLoopCounter *wlc, IOEventSourceCounter *esc)
+void IOStatistics::attachWorkLoopEventSource(IOWorkLoopCounter *wlc, IOEventSourceCounter *esc)
{
if (!wlc) {
- return;
- }
-
+ return;
+ }
+
IORWLockWrite(lock);
-
+
if (!nextWorkLoopDependency) {
return;
}
-
+
attachedEventSources++;
wlc->attachedEventSources++;
-
+
/* Track the kext dependency */
nextWorkLoopDependency->loadTag = esc->parentClass->parentKext->loadTag;
if (NULL == RB_INSERT(IOWorkLoopCounter::DependencyTree, &wlc->dependencyHead, nextWorkLoopDependency)) {
- nextWorkLoopDependency = kalloc_type(IOWorkLoopDependency, Z_WAITOK);
- }
-
+ nextWorkLoopDependency = (IOWorkLoopDependency*)kalloc(sizeof(IOWorkLoopDependency));
+ }
+
IORWLockUnlock(lock);
}
-void
-IOStatistics::detachWorkLoopEventSource(IOWorkLoopCounter *wlc, IOEventSourceCounter *esc)
+void IOStatistics::detachWorkLoopEventSource(IOWorkLoopCounter *wlc, IOEventSourceCounter *esc)
{
IOWorkLoopDependency sought, *found;
-
+
if (!wlc) {
return;
}
-
+
IORWLockWrite(lock);
attachedEventSources--;
wlc->attachedEventSources--;
-
+
sought.loadTag = esc->parentClass->parentKext->loadTag;
found = RB_FIND(IOWorkLoopCounter::DependencyTree, &wlc->dependencyHead, &sought);
if (found) {
RB_REMOVE(IOWorkLoopCounter::DependencyTree, &wlc->dependencyHead, found);
- kfree_type(IOWorkLoopDependency, found);
+ kfree(found, sizeof(IOWorkLoopDependency));
}
IORWLockUnlock(lock);
}
-int
-IOStatistics::getStatistics(sysctl_req *req)
+int IOStatistics::getStatistics(sysctl_req *req)
{
int error;
uint32_t calculatedSize, size;
@@ -645,39 +637,41 @@
IOStatisticsHeader *header;
assert(IOStatistics::enabled && req);
-
+
IORWLockRead(IOStatistics::lock);
/* Work out how much we need to allocate. IOStatisticsKext is of variable size. */
- calculatedSize = sizeof(IOStatisticsHeader) +
- sizeof(IOStatisticsGlobal) +
- (sizeof(IOStatisticsKext) * loadedKexts) + (sizeof(uint32_t) * registeredClasses) +
- (sizeof(IOStatisticsMemory) * loadedKexts) +
- (sizeof(IOStatisticsClass) * registeredClasses) +
- (sizeof(IOStatisticsCounter) * registeredClasses) +
- (sizeof(IOStatisticsKextIdentifier) * loadedKexts) +
- (sizeof(IOStatisticsClassName) * registeredClasses);
+ calculatedSize = sizeof(IOStatisticsHeader) +
+ sizeof(IOStatisticsGlobal) +
+ (sizeof(IOStatisticsKext) * loadedKexts) + (sizeof(uint32_t) * registeredClasses) +
+ (sizeof(IOStatisticsMemory) * loadedKexts) +
+ (sizeof(IOStatisticsClass) * registeredClasses) +
+ (sizeof(IOStatisticsCounter) * registeredClasses) +
+ (sizeof(IOStatisticsKextIdentifier) * loadedKexts) +
+ (sizeof(IOStatisticsClassName) * registeredClasses);
/* Size request? */
if (req->oldptr == USER_ADDR_NULL) {
error = SYSCTL_OUT(req, NULL, calculatedSize);
goto exit;
}
-
+
/* Read only */
if (req->newptr != USER_ADDR_NULL) {
error = EPERM;
goto exit;
}
- buffer = (char*)kalloc_data(calculatedSize, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ buffer = (char*)kalloc(calculatedSize);
if (!buffer) {
error = ENOMEM;
goto exit;
}
+ memset(buffer, 0, calculatedSize);
+
ptr = buffer;
-
+
header = (IOStatisticsHeader*)((void*)ptr);
header->sig = IOSTATISTICS_SIG;
@@ -701,17 +695,17 @@
header->memoryStatsOffset = header->kextStatsOffset + size;
size = copyMemoryStatistics((IOStatisticsMemory*)((void*)ptr));
ptr += size;
-
+
/* Class statistics */
header->classStatsOffset = header->memoryStatsOffset + size;
size = copyClassStatistics((IOStatisticsClass*)((void*)ptr));
ptr += size;
-
+
/* Dynamic class counter data */
header->counterStatsOffset = header->classStatsOffset + size;
size = copyCounterStatistics((IOStatisticsCounter*)((void*)ptr));
ptr += size;
-
+
/* Kext identifiers */
header->kextIdentifiersOffset = header->counterStatsOffset + size;
size = copyKextIdentifiers((IOStatisticsKextIdentifier*)((void*)ptr));
@@ -721,23 +715,22 @@
header->classNamesOffset = header->kextIdentifiersOffset + size;
size = copyClassNames((IOStatisticsClassName*)ptr);
ptr += size;
-
+
LOG(2, "IOStatistics::getStatistics - calculatedSize 0x%x, kexts 0x%x, classes 0x%x.\n",
- calculatedSize, loadedKexts, registeredClasses);
-
- assert((uint32_t)(ptr - buffer) == calculatedSize );
+ calculatedSize, loadedKexts, registeredClasses);
+
+ assert( (uint32_t)(ptr - buffer) == calculatedSize );
error = SYSCTL_OUT(req, buffer, calculatedSize);
- kfree_data(buffer, calculatedSize);
+ kfree(buffer, calculatedSize);
exit:
IORWLockUnlock(IOStatistics::lock);
return error;
}
-int
-IOStatistics::getWorkLoopStatistics(sysctl_req *req)
+int IOStatistics::getWorkLoopStatistics(sysctl_req *req)
{
int error;
uint32_t calculatedSize, size;
@@ -750,32 +743,33 @@
/* Approximate how much we need to allocate (worse case estimate) */
calculatedSize = sizeof(IOStatisticsWorkLoop) * registeredWorkloops +
- sizeof(uint32_t) * attachedEventSources;
+ sizeof(uint32_t) * attachedEventSources;
/* Size request? */
if (req->oldptr == USER_ADDR_NULL) {
error = SYSCTL_OUT(req, NULL, calculatedSize);
goto exit;
}
-
+
/* Read only */
if (req->newptr != USER_ADDR_NULL) {
error = EPERM;
goto exit;
}
- buffer = (char*)kalloc_data(calculatedSize, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ buffer = (char*)kalloc(calculatedSize);
if (!buffer) {
error = ENOMEM;
goto exit;
}
+
header = (IOStatisticsWorkLoopHeader*)((void*)buffer);
-
+
header->sig = IOSTATISTICS_SIG_WORKLOOP;
header->ver = IOSTATISTICS_VER;
header->seq = sequenceID;
-
+
header->workloopCount = registeredWorkloops;
size = copyWorkLoopStatistics(&header->workLoopStats);
@@ -786,16 +780,15 @@
error = SYSCTL_OUT(req, buffer, size);
- kfree_data(buffer, calculatedSize);
+ kfree(buffer, calculatedSize);
exit:
IORWLockUnlock(IOStatistics::lock);
return error;
}
-int
-IOStatistics::getUserClientStatistics(sysctl_req *req)
-{
+int IOStatistics::getUserClientStatistics(sysctl_req *req)
+{
int error;
uint32_t calculatedSize, size;
char *buffer;
@@ -807,9 +800,9 @@
IORWLockRead(IOStatistics::lock);
/* Work out how much we need to allocate */
- calculatedSize = sizeof(IOStatisticsUserClientHeader) +
- sizeof(IOStatisticsUserClientCall) * IOKIT_STATISTICS_RECORDED_USERCLIENT_PROCS * loadedKexts;
-
+ calculatedSize = sizeof(IOStatisticsUserClientHeader) +
+ sizeof(IOStatisticsUserClientCall) * IOKIT_STATISTICS_RECORDED_USERCLIENT_PROCS * loadedKexts;
+
/* Size request? */
if (req->oldptr == USER_ADDR_NULL) {
error = SYSCTL_OUT(req, NULL, calculatedSize);
@@ -822,56 +815,53 @@
goto exit;
}
- error = SYSCTL_IN(req, &requestedLoadTag, sizeof(requestedLoadTag));
- if (error) {
- goto exit;
- }
-
+ SYSCTL_IN(req, &requestedLoadTag, sizeof(requestedLoadTag));
+
LOG(2, "IOStatistics::getUserClientStatistics - requesting kext w/load tag: %d\n", requestedLoadTag);
- buffer = (char*)kalloc_data(calculatedSize, (zalloc_flags_t)(Z_WAITOK | Z_ZERO));
+ buffer = (char*)kalloc(calculatedSize);
if (!buffer) {
error = ENOMEM;
goto exit;
}
+
header = (IOStatisticsUserClientHeader*)((void*)buffer);
header->sig = IOSTATISTICS_SIG_USERCLIENT;
header->ver = IOSTATISTICS_VER;
-
+
header->seq = sequenceID;
header->processes = 0;
size = copyUserClientStatistics(header, requestedLoadTag);
-
+
assert((sizeof(IOStatisticsUserClientHeader) + size) <= calculatedSize);
-
+
if (size) {
error = SYSCTL_OUT(req, buffer, sizeof(IOStatisticsUserClientHeader) + size);
- } else {
+ }
+ else {
error = EINVAL;
}
- kfree_data(buffer, calculatedSize);
+ kfree(buffer, calculatedSize);
exit:
IORWLockUnlock(IOStatistics::lock);
return error;
}
-uint32_t
-IOStatistics::copyGlobalStatistics(IOStatisticsGlobal *stats)
+uint32_t IOStatistics::copyGlobalStatistics(IOStatisticsGlobal *stats)
{
stats->kextCount = loadedKexts;
stats->classCount = registeredClasses;
stats->workloops = registeredWorkloops;
-
+
return sizeof(IOStatisticsGlobal);
}
-uint32_t
-IOStatistics::copyKextStatistics(IOStatisticsKext *stats)
+uint32_t IOStatistics::copyKextStatistics(IOStatisticsKext *stats)
{
KextNode *ke;
ClassNode *ce;
@@ -887,21 +877,20 @@
SLIST_FOREACH(ce, &ke->classList, lLink) {
stats->classIndexes[index++] = ce->classID;
}
-
+
stats = (IOStatisticsKext *)((void*)((char*)stats + sizeof(IOStatisticsKext) + (ke->classes * sizeof(uint32_t))));
}
- return sizeof(IOStatisticsKext) * loadedKexts + sizeof(uint32_t) * registeredClasses;
-}
-
-uint32_t
-IOStatistics::copyMemoryStatistics(IOStatisticsMemory *stats)
+ return (sizeof(IOStatisticsKext) * loadedKexts + sizeof(uint32_t) * registeredClasses);
+}
+
+uint32_t IOStatistics::copyMemoryStatistics(IOStatisticsMemory *stats)
{
KextNode *ke;
RB_FOREACH(ke, KextTree, &kextHead) {
stats->allocatedSize = ke->memoryCounters[kIOStatisticsMalloc];
- stats->freedSize = ke->memoryCounters[kIOStatisticsFree];
+ stats->freedSize = ke->memoryCounters[kIOStatisticsFree];
stats->allocatedAlignedSize = ke->memoryCounters[kIOStatisticsMallocAligned];
stats->freedAlignedSize = ke->memoryCounters[kIOStatisticsFreeAligned];
stats->allocatedContiguousSize = ke->memoryCounters[kIOStatisticsMallocContiguous];
@@ -910,12 +899,11 @@
stats->freedPageableSize = ke->memoryCounters[kIOStatisticsFreePageable];
stats++;
}
-
- return sizeof(IOStatisticsMemory) * loadedKexts;
-}
-
-uint32_t
-IOStatistics::copyClassStatistics(IOStatisticsClass *stats)
+
+ return (sizeof(IOStatisticsMemory) * loadedKexts);
+}
+
+uint32_t IOStatistics::copyClassStatistics(IOStatisticsClass *stats)
{
KextNode *ke;
ClassNode *ce;
@@ -923,7 +911,7 @@
RB_FOREACH(ke, KextTree, &kextHead) {
SLIST_FOREACH(ce, &ke->classList, lLink) {
stats->classID = ce->classID;
- stats->superClassID = ce->superClassID;
+ stats->superClassID = ce->superClassID;
stats->classSize = ce->metaClass->getClassSize();
stats++;
@@ -933,8 +921,7 @@
return sizeof(IOStatisticsClass) * registeredClasses;
}
-uint32_t
-IOStatistics::copyCounterStatistics(IOStatisticsCounter *stats)
+uint32_t IOStatistics::copyCounterStatistics(IOStatisticsCounter *stats)
{
KextNode *ke;
ClassNode *ce;
@@ -964,45 +951,45 @@
/* Event source counters */
SLIST_FOREACH(counter, &ce->counterList, link) {
- switch (counter->type) {
- case kIOStatisticsInterruptEventSourceCounter:
- iec->created++;
- iec->produced += counter->u.interrupt.produced;
- iec->checksForWork += counter->u.interrupt.checksForWork;
- break;
- case kIOStatisticsFilterInterruptEventSourceCounter:
- fiec->created++;
- fiec->produced += counter->u.filter.produced;
- fiec->checksForWork += counter->u.filter.checksForWork;
- break;
- case kIOStatisticsTimerEventSourceCounter:
- tec->created++;
- tec->timeouts += counter->u.timer.timeouts;
- tec->checksForWork += counter->u.timer.checksForWork;
- tec->timeOnGate += counter->timeOnGate;
- tec->closeGateCalls += counter->closeGateCalls;
- tec->openGateCalls += counter->openGateCalls;
- break;
- case kIOStatisticsCommandGateCounter:
- cgc->created++;
- cgc->timeOnGate += counter->timeOnGate;
- cgc->actionCalls += counter->u.commandGate.actionCalls;
- break;
- case kIOStatisticsCommandQueueCounter:
- cqc->created++;
- cqc->actionCalls += counter->u.commandQueue.actionCalls;
- break;
- case kIOStatisticsDerivedEventSourceCounter:
- dec->created++;
- dec->timeOnGate += counter->timeOnGate;
- dec->closeGateCalls += counter->closeGateCalls;
- dec->openGateCalls += counter->openGateCalls;
- break;
- default:
- break;
+ switch (counter->type) {
+ case kIOStatisticsInterruptEventSourceCounter:
+ iec->created++;
+ iec->produced += counter->u.interrupt.produced;
+ iec->checksForWork += counter->u.interrupt.checksForWork;
+ break;
+ case kIOStatisticsFilterInterruptEventSourceCounter:
+ fiec->created++;
+ fiec->produced += counter->u.filter.produced;
+ fiec->checksForWork += counter->u.filter.checksForWork;
+ break;
+ case kIOStatisticsTimerEventSourceCounter:
+ tec->created++;
+ tec->timeouts += counter->u.timer.timeouts;
+ tec->checksForWork += counter->u.timer.checksForWork;
+ tec->timeOnGate += counter->timeOnGate;
+ tec->closeGateCalls += counter->closeGateCalls;
+ tec->openGateCalls += counter->openGateCalls;
+ break;
+ case kIOStatisticsCommandGateCounter:
+ cgc->created++;
+ cgc->timeOnGate += counter->timeOnGate;
+ cgc->actionCalls += counter->u.commandGate.actionCalls;
+ break;
+ case kIOStatisticsCommandQueueCounter:
+ cqc->created++;
+ cqc->actionCalls += counter->u.commandQueue.actionCalls;
+ break;
+ case kIOStatisticsDerivedEventSourceCounter:
+ dec->created++;
+ dec->timeOnGate += counter->timeOnGate;
+ dec->closeGateCalls += counter->closeGateCalls;
+ dec->openGateCalls += counter->openGateCalls;
+ break;
+ default:
+ break;
}
}
-
+
stats++;
}
}
@@ -1010,8 +997,7 @@
return sizeof(IOStatisticsCounter) * registeredClasses;
}
-uint32_t
-IOStatistics::copyKextIdentifiers(IOStatisticsKextIdentifier *kextIDs)
+uint32_t IOStatistics::copyKextIdentifiers(IOStatisticsKextIdentifier *kextIDs)
{
KextNode *ke;
@@ -1020,11 +1006,10 @@
kextIDs++;
}
- return sizeof(IOStatisticsKextIdentifier) * loadedKexts;
-}
-
-uint32_t
-IOStatistics::copyClassNames(IOStatisticsClassName *classNames)
+ return (sizeof(IOStatisticsKextIdentifier) * loadedKexts);
+}
+
+uint32_t IOStatistics::copyClassNames(IOStatisticsClassName *classNames)
{
KextNode *ke;
ClassNode *ce;
@@ -1035,12 +1020,11 @@
classNames++;
}
}
-
- return sizeof(IOStatisticsClassName) * registeredClasses;
-}
-
-uint32_t
-IOStatistics::copyWorkLoopStatistics(IOStatisticsWorkLoop *stats)
+
+ return (sizeof(IOStatisticsClassName) * registeredClasses);
+}
+
+uint32_t IOStatistics::copyWorkLoopStatistics(IOStatisticsWorkLoop *stats)
{
KextNode *ke;
IOWorkLoopCounter *wlc;
@@ -1057,9 +1041,9 @@
stats->dependentKextLoadTags[stats->dependentKexts] = dependentNode->loadTag;
stats->dependentKexts++;
}
-
+
size = sizeof(IOStatisticsWorkLoop) + (sizeof(uint32_t) * stats->dependentKexts);
-
+
accumulatedSize += size;
stats = (IOStatisticsWorkLoop*)((void*)((char*)stats + size));
}
@@ -1068,8 +1052,7 @@
return accumulatedSize;
}
-uint32_t
-IOStatistics::copyUserClientStatistics(IOStatisticsUserClientHeader *stats, uint32_t loadTag)
+uint32_t IOStatistics::copyUserClientStatistics(IOStatisticsUserClientHeader *stats, uint32_t loadTag)
{
KextNode *sought, *found = NULL;
uint32_t procs = 0;
@@ -1081,7 +1064,7 @@
break;
}
}
-
+
if (!found) {
return 0;
}
@@ -1097,9 +1080,8 @@
return sizeof(IOStatisticsUserClientCall) * stats->processes;
}
-void
-IOStatistics::storeUserClientCallInfo(IOUserClient *userClient, IOUserClientCounter *counter)
-{
+void IOStatistics::storeUserClientCallInfo(IOUserClient *userClient, IOUserClientCounter *counter)
+{
OSString *ossUserClientCreator = NULL;
int32_t pid = -1;
KextNode *parentKext;
@@ -1107,51 +1089,49 @@
uint32_t count = 0;
const char *ptr = NULL;
OSObject *obj;
-
+
/* TODO: see if this can be more efficient */
obj = userClient->copyProperty("IOUserClientCreator",
- gIOServicePlane,
- kIORegistryIterateRecursively | kIORegistryIterateParents);
-
- if (!obj) {
+ gIOServicePlane,
+ kIORegistryIterateRecursively | kIORegistryIterateParents);
+
+ if (!obj)
goto err_nounlock;
- }
ossUserClientCreator = OSDynamicCast(OSString, obj);
if (ossUserClientCreator) {
- uint32_t len, lenIter = 0;
-
+ uint32_t len, lenIter = 0;
+
ptr = ossUserClientCreator->getCStringNoCopy();
len = ossUserClientCreator->getLength();
-
+
while ((*ptr != ' ') && (lenIter < len)) {
ptr++;
lenIter++;
}
-
+
if (lenIter < len) {
ptr++; // Skip the space
lenIter++;
pid = 0;
- while ((*ptr != ',') && (lenIter < len)) {
- pid = pid * 10 + (*ptr - '0');
+ while ( (*ptr != ',') && (lenIter < len)) {
+ pid = pid*10 + (*ptr - '0');
ptr++;
lenIter++;
}
-
- if (lenIter == len) {
+
+ if(lenIter == len) {
pid = -1;
} else {
ptr += 2;
}
}
}
-
- if (-1 == pid) {
+
+ if (-1 == pid)
goto err_nounlock;
- }
-
+
IORWLockWrite(lock);
parentKext = counter->parentClass->parentKext;
@@ -1163,12 +1143,13 @@
if (count) {
TAILQ_REMOVE(&parentKext->userClientCallList, entry, link);
break;
- } else {
+ }
+ else {
/* At the head already, so increment and return */
goto err_unlock;
}
}
-
+
count++;
}
@@ -1177,11 +1158,13 @@
/* Max elements hit, so reuse the last */
entry = TAILQ_LAST(&parentKext->userClientCallList, ProcessEntryList);
TAILQ_REMOVE(&parentKext->userClientCallList, entry, link);
- } else {
+ }
+ else {
/* Otherwise, allocate a new entry */
- entry = kalloc_type(IOUserClientProcessEntry, Z_WAITOK);
+ entry = (IOUserClientProcessEntry*)kalloc(sizeof(IOUserClientProcessEntry));
if (!entry) {
- goto err_unlock;
+ IORWLockUnlock(lock);
+ return;
}
}
@@ -1189,50 +1172,43 @@
entry->pid = pid;
entry->calls = 1;
}
-
+
TAILQ_FOREACH(nextEntry, &parentKext->userClientCallList, link) {
- if (nextEntry->calls <= entry->calls) {
+ if (nextEntry->calls <= entry->calls)
break;
- }
-
+
prevEntry = nextEntry;
}
-
- if (!prevEntry) {
+
+ if (!prevEntry)
TAILQ_INSERT_HEAD(&parentKext->userClientCallList, entry, link);
- } else {
+ else
TAILQ_INSERT_AFTER(&parentKext->userClientCallList, prevEntry, entry, link);
- }
-
+
err_unlock:
IORWLockUnlock(lock);
-
+
err_nounlock:
- if (obj) {
+ if (obj)
obj->release();
- }
-}
-
-void
-IOStatistics::countUserClientCall(IOUserClient *client)
-{
+}
+
+void IOStatistics::countUserClientCall(IOUserClient *client) {
IOUserClient::ExpansionData *data;
IOUserClientCounter *counter;
-
+
/* Guard against an uninitialized client object - <rdar://problem/8577946> */
if (!(data = client->reserved)) {
return;
}
-
+
if ((counter = data->counter)) {
storeUserClientCallInfo(client, counter);
OSIncrementAtomic(&counter->clientCalls);
}
}
-KextNode *
-IOStatistics::getKextNodeFromBacktrace(boolean_t write)
-{
+KextNode *IOStatistics::getKextNodeFromBacktrace(boolean_t write) {
const uint32_t btMin = 3;
void *bt[16];
@@ -1246,7 +1222,7 @@
* overhead. OSBacktrace does many safety checks that
* are not needed in this situation.
*/
- btCount = backtrace((uintptr_t*)bt, btCount, NULL, NULL);
+ btCount = backtrace((uintptr_t*)bt, btCount);
if (write) {
IORWLockWrite(lock);
@@ -1262,10 +1238,11 @@
while (ke) {
if (*scanAddr < ke->address) {
ke = RB_LEFT(ke, addressLink);
- } else {
+ }
+ else {
if ((*scanAddr < ke->address_end) && (*scanAddr >= ke->address)) {
- if (!ke->kext->isKernelComponent()) {
- return ke;
+ if (!ke->kext->isKernelComponent()) {
+ return ke;
} else {
found = ke;
}
@@ -1278,33 +1255,26 @@
if (!found) {
IORWLockUnlock(lock);
}
-
+
return found;
}
-
-void
-IOStatistics::releaseKextNode(KextNode *node)
-{
+
+void IOStatistics::releaseKextNode(KextNode *node) {
#pragma unused(node)
IORWLockUnlock(lock);
}
/* IOLib allocations */
-void
-IOStatistics::countAlloc(uint32_t index, vm_size_t size)
-{
+void IOStatistics::countAlloc(uint32_t index, vm_size_t size) {
KextNode *ke;
-
+
if (!enabled) {
- return;
- }
- if (size > INT_MAX) {
return;
}
ke = getKextNodeFromBacktrace(FALSE);
if (ke) {
- OSAddAtomic((SInt32) size, &ke->memoryCounters[index]);
+ OSAddAtomic(size, &ke->memoryCounters[index]);
releaseKextNode(ke);
}
}