diff --git a/src/rm_allocator.c b/src/rm_allocator.c
index 230e646e4be562b90ac312941f31740ac27e3c3b..0e74966c6ff6aabc5be411b2f543da058517a518 100644 (file)
--- a/src/rm_allocator.c
+++ b/src/rm_allocator.c
static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_Allocator *allocators = rmInst->u.server.allocators;
+ Rm_Allocator *allocators = rmAllocatorGetAllocatorList(rmHandle);
Rm_Allocator *newAllocator = NULL;
- newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));
+ newAllocator = Rm_osalMalloc(sizeof(*allocators));
if (newAllocator) {
- memset((void *)newAllocator, 0, sizeof(Rm_Allocator));
+ memset((void *)newAllocator, 0, sizeof(*newAllocator));
strncpy(newAllocator->resourceName, resourceName, RM_NAME_MAX_CHARS);
newAllocator->allocatorRootEntry = NULL;
newAllocator->nextAllocator = NULL;
@@ -88,102 +88,33 @@ static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
allocators = allocators->nextAllocator;
}
allocators->nextAllocator = newAllocator;
+ RM_SS_OBJ_WB(allocators, Rm_Allocator);
}
else {
- rmInst->u.server.allocators = newAllocator;
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ rmInst->u.server.allocators = newAllocator;
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ rmInst->u.cd.allocators = newAllocator;
+ }
}
}
return (newAllocator);
}
-/* FUNCTION PURPOSE: Deletes a resource allocator
- ***********************************************************************
- * DESCRIPTION: Deletes a resource allocator based on the given
- * resource name. The resource allocator will be
- * removed from the RM instance allocator list.
- */
-static int32_t allocatorDelete(Rm_Handle rmHandle, char *resourceName)
-{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- Rm_Allocator *allocator = rmInst->u.server.allocators;
- Rm_Allocator *prevAllocator = NULL;
- int32_t retVal = RM_OK;
-
- while (allocator) {
- if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
- break;
- }
- prevAllocator = allocator;
- allocator = allocator->nextAllocator;
- }
-
- if (allocator) {
- if (prevAllocator == NULL) {
- rmInst->u.server.allocators = allocator->nextAllocator;
- }
- else {
- prevAllocator->nextAllocator = allocator->nextAllocator;
- }
- Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));
- }
- else {
- retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
- }
- return (retVal);
-}
-
-/* FUNCTION PURPOSE: Creates a new resource tree
- ***********************************************************************
- * DESCRIPTION: Creates and populates a new resource tree allocator
- * using the provided resource name and value range. The
- * name and value originate from the GRL.
- */
-static int32_t allocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range)
-{
- Rm_Allocator *allocator = NULL;
- Rm_ResourceTree *treeRootEntry = NULL;
- Rm_ResourceNode *treeNode = NULL;
- Rm_ResourceNode *collidingNode = NULL;
-
- allocator = allocatorAdd(rmHandle, resourceName);
- treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));
- RB_INIT(treeRootEntry);
-
- while (range != NULL) {
- treeNode = rmResourceNodeNew(range->base, range->length);
- collidingNode = RB_INSERT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
-
- if (collidingNode) {
- Rm_ResourceNode *nextNode = NULL;
-
- /* Node that was inserted collides with existing node. Destroy tree and return error */
- for (treeNode = RB_MIN(_Rm_AllocatorResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode) {
- nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRootEntry, treeNode);
- RB_REMOVE(_Rm_AllocatorResourceTree, treeRootEntry, nextNode);
- rmResourceNodeFree(treeNode);
- }
- Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));
- allocatorDelete(rmHandle, allocator->resourceName);
- return (RM_ERROR_GRL_RES_SPECIFIED_MORE_THAN_ONCE);
- }
- range = range->nextRange;
- }
-
- allocator->allocatorRootEntry = treeRootEntry;
- return(RM_OK);
-}
-
/* FUNCTION PURPOSE: Adds an owner to an allocator resource
***********************************************************************
* DESCRIPTION: Adds a RM instance node to a resource node's
* list of owners.
*/
-static void allocatorResNodeOwnerAdd(Rm_ResourceNode *node, void *serviceInstNode)
+static void allocatorResNodeOwnerAdd(Rm_Handle rmHandle, Rm_ResourceNode *node, void *serviceInstNode)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *ownerList = node->ownerList;
Rm_Owner *newOwner = NULL;
- newOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+ newOwner = Rm_osalMalloc(sizeof(*newOwner));
if (newOwner) {
newOwner->instNameNode = serviceInstNode;
@@ -191,10 +122,13 @@ static void allocatorResNodeOwnerAdd(Rm_ResourceNode *node, void *serviceInstNod
/* Add owner entry to end of list */
if (ownerList) {
+ RM_SS_OBJ_INV(ownerList, Rm_Owner);
while (ownerList->nextOwner) {
ownerList = ownerList->nextOwner;
+ RM_SS_OBJ_INV(ownerList, Rm_Owner);
}
ownerList->nextOwner = newOwner;
+ RM_SS_OBJ_WB(ownerList, Rm_Owner);
}
else {
node->ownerList = newOwner;
@@ -202,22 +136,59 @@ static void allocatorResNodeOwnerAdd(Rm_ResourceNode *node, void *serviceInstNod
node->allocationCount++;
newOwner->instNameNode->allocRefCount++;
+ RM_SS_OBJ_WB(newOwner, Rm_Owner);
+ RM_SS_OBJ_WB(newOwner->instNameNode, Rm_PolicyValidInstNode);
}
}
+/* FUNCTION PURPOSE: Compares two resource node's boundaries
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the resource nodes are neighbors from
+ * a base+length perspective. Otherwise, returns FALSE.
+ */
+static int allocatorResNodeBoundaryCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+{
+ uint32_t node1End = node1->base + node1->length - 1;
+ uint32_t node2End = node2->base + node2->length - 1;
+
+ if (node1 && node2) {
+ if (node1->base < node2->base) {
+ if (node1End == (node2->base - 1)) {
+ return(RM_TRUE);
+ }
+ }
+ else if (node2->base < node1->base) {
+ if (node2End == (node1->base - 1)) {
+ return(RM_TRUE);
+ }
+ }
+ }
+ return(RM_FALSE);
+}
+
/* FUNCTION PURPOSE: Compares two resource node's owners
***********************************************************************
* DESCRIPTION: Returns TRUE if the owners of two resource nodes
* are equivalent. Otherwise, returns FALSE.
*/
-static int allocatorResNodeOwnerCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+static int allocatorResNodeOwnerCompare(Rm_Handle rmHandle, Rm_ResourceNode *node1, Rm_ResourceNode *node2)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *node1Owners = node1->ownerList;
Rm_Owner *node2Owners = node2->ownerList;
int matchedInst;
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ while(node2Owners) {
+ Rm_osalBeginMemAccess((void *)node2Owners, sizeof(*node2Owners));
+ node2Owners = node2Owners->nextOwner;
+ }
+ node2Owners = node2->ownerList;
+ }
+
if (node1->allocationCount == node2->allocationCount) {
while (node1Owners) {
+ RM_SS_OBJ_INV(node1Owners, Rm_Owner);
matchedInst = RM_FALSE;
while (node2Owners) {
if (node1Owners->instNameNode == node2Owners->instNameNode) {
@@ -248,12 +219,14 @@ static int allocatorResNodeOwnerCompare(Rm_ResourceNode *node1, Rm_ResourceNode
* DESCRIPTION: Removes a RM instance node from a resource node's
* list of owners.
*/
-static void allocatorResNodeOwnerDelete(Rm_ResourceNode *node, void *serviceInstNode)
+static void allocatorResNodeOwnerDelete(Rm_Handle rmHandle, Rm_ResourceNode *node, void *serviceInstNode)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
Rm_Owner *prevOwner = NULL;
while (owner) {
+ RM_SS_OBJ_INV(owner, Rm_Owner);
if (owner->instNameNode == serviceInstNode) {
break;
}
@@ -261,42 +234,55 @@ static void allocatorResNodeOwnerDelete(Rm_ResourceNode *node, void *serviceInst
owner = owner->nextOwner;
}
- if (prevOwner == NULL) {
- node->ownerList = owner->nextOwner;
- }
- else {
- prevOwner->nextOwner = owner->nextOwner;
+ if (owner) {
+ if (prevOwner == NULL) {
+ node->ownerList = owner->nextOwner;
+ }
+ else {
+ prevOwner->nextOwner = owner->nextOwner;
+ RM_SS_OBJ_WB(prevOwner, Rm_Owner);
+ }
+
+ node->allocationCount--;
+ owner->instNameNode->allocRefCount--;
+ RM_SS_OBJ_WB(owner->instNameNode, Rm_PolicyValidInstNode);
+ Rm_osalFree((void *)owner, sizeof(*owner));
}
-
- node->allocationCount--;
- owner->instNameNode->allocRefCount--;
- Rm_osalFree((void *)owner, sizeof(Rm_Owner));
}
/* FUNCTION PURPOSE: Copies the owners of a resource node
***********************************************************************
* DESCRIPTION: Creates a list of resource owners for the destination
- * resource node that is equivalent to the the
- * source resource node's owners
+ * resource node that is equivalent to the source resource
+ * node's owners
+ *
+ * dstNode must be a newly created node without any owners.
*/
-static void allocatorResNodeOwnerCopy(Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
+static void allocatorResNodeOwnerCopy(Rm_Handle rmHandle, Rm_ResourceNode *dstNode, Rm_ResourceNode *srcNode)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *srcOwnerList = srcNode->ownerList;
Rm_Owner *dstNewOwner;
Rm_Owner *dstPrevOwner;
+ if (dstNode->ownerList != NULL) {
+ return;
+ }
dstNode->allocationCount = srcNode->allocationCount;
while (srcOwnerList) {
- dstNewOwner = Rm_osalMalloc(sizeof(Rm_Owner));
+ RM_SS_OBJ_INV(srcOwnerList, Rm_Owner);
+ dstNewOwner = Rm_osalMalloc(sizeof(*dstNewOwner));
dstNewOwner->instNameNode = srcOwnerList->instNameNode;
dstNewOwner->nextOwner = NULL;
+ RM_SS_OBJ_WB(dstNewOwner, Rm_Owner);
if (dstNode->ownerList == NULL) {
dstNode->ownerList = dstNewOwner;
}
else {
dstPrevOwner->nextOwner = dstNewOwner;
+ RM_SS_OBJ_WB(dstPrevOwner, Rm_Owner);
}
dstPrevOwner = dstNewOwner;
srcOwnerList = srcOwnerList->nextOwner;
@@ -308,16 +294,19 @@ static void allocatorResNodeOwnerCopy(Rm_ResourceNode *dstNode, Rm_ResourceNode
* DESCRIPTION: Deletes all owners from the owners list of a
* resource node.
*/
-static void allocatorResNodeOwnerClear(Rm_ResourceNode *node)
+static void allocatorResNodeOwnerClear(Rm_Handle rmHandle, Rm_ResourceNode *node)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
Rm_Owner *nextOwner;
while (owner) {
+ RM_SS_OBJ_INV(owner, Rm_Owner);
nextOwner = owner->nextOwner;
node->allocationCount--;
owner->instNameNode->allocRefCount--;
- Rm_osalFree((void *)owner, sizeof(Rm_Owner));
+ RM_SS_OBJ_WB(owner->instNameNode, Rm_PolicyValidInstNode);
+ Rm_osalFree((void *)owner, sizeof(*owner));
owner = nextOwner;
}
}
* in the list of resource node owners. Otherwise,
* returns FALSE.
*/
-static int allocatorResNodeIsOwnedBy(Rm_ResourceNode *node, void *serviceInstNode)
+static int allocatorResNodeIsOwnedBy(Rm_Handle rmHandle, Rm_ResourceNode *node, void *serviceInstNode)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_Owner *owner = node->ownerList;
while (owner) {
+ RM_SS_OBJ_INV(owner, Rm_Owner);
if (owner->instNameNode == serviceInstNode) {
return(RM_TRUE);
}
@@ -341,6 +332,45 @@ static int allocatorResNodeIsOwnedBy(Rm_ResourceNode *node, void *serviceInstNod
return(RM_FALSE);
}
+/* FUNCTION PURPOSE: Get the status for an allocator resource
+ ***********************************************************************
+ * DESCRIPTION: Called when a resource status request is made. The
+ * resource's allocator is searched for the resource base
+ * and length specified in the transaction. The
+ * resource's owner reference count is returned if the
+ * resource range is found.
+ */
+static int32_t allocatorStatus(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
+{
+ Rm_ResourceNode findNode;
+ Rm_ResourceNode *matchingNode = NULL;
+ uint32_t matchingEnd;
+ uint32_t findEnd;
+ int32_t retVal;
+
+ memset((void *)&findNode, 0, sizeof(findNode));
+ findNode.base = opInfo->resourceInfo->base;
+ findNode.length = opInfo->resourceInfo->length;
+ matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+ if (matchingNode) {
+ matchingEnd = matchingNode->base + matchingNode->length - 1;
+ findEnd = findNode.base + findNode.length - 1;
+ if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
+ opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+ retVal = RM_SERVICE_APPROVED;
+ }
+ else {
+ retVal = RM_SERVICE_DENIED_PARTIAL_STATUS;
+ }
+ }
+ else {
+ retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
+ }
+
+ return(retVal);
+}
+
/* FUNCTION PURPOSE: Preallocates an allocator resource
***********************************************************************
* DESCRIPTION: Called when an allocate request is made but the base
@@ -352,22 +382,43 @@ static int allocatorResNodeIsOwnedBy(Rm_ResourceNode *node, void *serviceInstNod
*/
static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, int32_t resourcePolicy,
Rm_AllocatorOpInfo *opInfo)
-{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_ResourceNode findNode;
Rm_ResourceNode *matchingNode = NULL;
+ Rm_ResourceNode *nextNode;
uint32_t matchingEnd;
+ uint32_t findEnd;
uint32_t rangeIndex;
int resourceFound = RM_FALSE;
Rm_PolicyCheckType policyCheckType;
Rm_PolicyCheckCfg policyCheckCfg;
int nodePassesPolicy;
- int32_t retVal = RM_SERVICE_PROCESSING;
+ int32_t retVal = RM_OK;
- opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode,
- resourcePolicy, opInfo->allocType,
- &retVal);
- if (retVal != RM_SERVICE_PROCESSING) {
+ if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) {
+ policyCheckType = Rm_policyCheck_INIT;
+ }
+ else if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE) {
+ policyCheckType = Rm_policyCheck_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ return (retVal);
+ }
+
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ /* Set base to first node's base since CD will not have all resources like Server */
+ matchingNode = RB_MIN(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry);
+ opInfo->resourceInfo->base = matchingNode->base;
+ }
+ else {
+ opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode,
+ resourcePolicy, policyCheckType,
+ &retVal);
+ }
+
+ if (retVal != RM_OK) {
return (retVal);
}
@@ -380,18 +431,12 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
opInfo->resourceInfo->alignment = 1;
}
- memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+ memset((void *)&findNode, 0, sizeof(findNode));
findNode.base = opInfo->resourceInfo->base;
findNode.length = opInfo->resourceInfo->length;
/* Configure policy checking structure */
- memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
- if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
- policyCheckType = Rm_policyCheck_INIT;
- }
- else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
- policyCheckType = Rm_policyCheck_USE;
- }
+ memset((void *)&policyCheckCfg, 0, sizeof(policyCheckCfg));
policyCheckCfg.policyDtb = opInfo->policy;
policyCheckCfg.resourceOffset = resourcePolicy;
@@ -399,8 +444,12 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
if (matchingNode) {
- if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
- /* Attempt to preallocate from node only if not owned by instance requesting the allocation */
+ matchingEnd = matchingNode->base + matchingNode->length - 1;
+ findEnd = findNode.base + findNode.length - 1;
+ if ((matchingNode->allocationCount == 0) &&
+ (findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
+ /* Attempt to preallocate from node only if not owned by anyone and sits
+ * within a matching node. */
nodePassesPolicy = RM_FALSE;
policyCheckCfg.type = policyCheckType;
policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
@@ -411,7 +460,7 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
if (nodePassesPolicy && (matchingNode->allocationCount > 0)) {
policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
- if (allocatorResNodeIsOwnedBy(matchingNode, rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree))) {
+ if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, rmPolicyGetLinuxInstNode(rmHandle))) {
/* Check if instance requesting resource has privileges to share
* a resource already reserved by Linux */
policyCheckCfg.type = Rm_policyCheck_SHARED_LINUX;
@@ -433,13 +482,12 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
nodePassesPolicy = !rmPolicyCheckPrivilege(&policyCheckCfg, &retVal);
}
- if (retVal != RM_SERVICE_PROCESSING) {
+ if (retVal != RM_OK) {
break;
}
if (nodePassesPolicy) {
- matchingEnd = matchingNode->base + matchingNode->length - 1;
- /* Initialize indexer to be first resource value that alignment */
+ /* Initialize indexer to be first resource value that alignment satisfies */
rangeIndex = findNode.base;
if (rangeIndex % opInfo->resourceInfo->alignment) {
rangeIndex += (opInfo->resourceInfo->alignment -
@@ -451,13 +499,24 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
* allocate requirements */
opInfo->resourceInfo->base = rangeIndex;
resourceFound = RM_TRUE;
+ retVal = RM_SERVICE_PROCESSING;
}
}
}
if (!resourceFound) {
/* Check next resource node for available resources */
- findNode.base = matchingNode->base + matchingNode->length;
+ if (findNode.base < matchingNode->base) {
+ findNode.base = matchingNode->base;
+ }
+ else {
+ if (nextNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode)) {
+ findNode.base = nextNode->base;
+ }
+ else {
+ retVal = RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET;
+ }
+ }
}
}
else {
@@ -483,7 +542,6 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, int32_t resourcePolicy,
Rm_AllocatorOpInfo *opInfo)
{
- Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
Rm_ResourceNode findNode;
Rm_ResourceNode *matchingNode = NULL;
Rm_ResourceNode *leftNode = NULL;
@@ -495,28 +553,33 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
int combineRight = RM_FALSE;
uint32_t findEnd;
uint32_t matchingEnd;
- int32_t retVal = RM_SERVICE_PROCESSING;
+ int32_t retVal;
- memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+ if (opInfo->operation == Rm_allocatorOp_ALLOCATE_INIT) {
+ policyCheckType = Rm_policyCheck_INIT;
+ }
+ else if (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE) {
+ policyCheckType = Rm_policyCheck_USE;
+ }
+ else {
+ retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+ return (retVal);
+ }
+
+ memset((void *)&findNode, 0, sizeof(findNode));
findNode.base = opInfo->resourceInfo->base;
findNode.length = opInfo->resourceInfo->length;
matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
/* Prepare privilege checks */
- memset((void *)&policyCheckCfg, 0, sizeof(Rm_PolicyCheckCfg));
- if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_INIT_SHIFT)) {
- policyCheckType = Rm_policyCheck_INIT;
- }
- else if (RM_policy_GET_PERM(opInfo->allocType, RM_POLICY_PERM_USE_SHIFT)) {
- policyCheckType = Rm_policyCheck_USE;
- }
+ memset((void *)&policyCheckCfg, 0, sizeof(policyCheckCfg));
if (matchingNode) {
findEnd = findNode.base + findNode.length - 1;
matchingEnd = matchingNode->base + matchingNode->length - 1;
if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
- if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree)) {
+ if (opInfo->serviceSrcInstNode == rmPolicyGetLinuxInstNode(rmHandle)) {
/* Bypass policy checks since Linux Kernel has full privileges */
allocPassesPolicy = RM_TRUE;
}
@@ -537,9 +600,9 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
}
}
- if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+ if (!allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceSrcInstNode)) {
if (allocPassesPolicy && (matchingNode->allocationCount > 0)) {
- if (allocatorResNodeIsOwnedBy(matchingNode, rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree))) {
+ if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, rmPolicyGetLinuxInstNode(rmHandle))) {
/* Check if instance requesting resource has privileges to share
* a resource already reserved by Linux */
policyCheckCfg.type = Rm_policyCheck_SHARED_LINUX;
@@ -573,7 +636,7 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
}
if (allocPassesPolicy) {
- if (!allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+ if (!allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceSrcInstNode)) {
/* Handle any possible node combinations if requesting instance is
* not already in resource's owner list. Automatic approval if requesting
* instance is already in owner list. */
@@ -586,13 +649,15 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
- allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
- if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+ if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
combineLeft = RM_TRUE;
}
- if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+ if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
combineRight = RM_TRUE;
}
@@ -602,9 +667,9 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
matchingNode->base = leftNode->base;
matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
- allocatorResNodeOwnerClear(leftNode);
+ allocatorResNodeOwnerClear(rmHandle, leftNode);
rmResourceNodeFree(leftNode);
- allocatorResNodeOwnerClear(rightNode);
+ allocatorResNodeOwnerClear(rmHandle, rightNode);
rmResourceNodeFree(rightNode);
}
else if (combineLeft) {
@@ -612,26 +677,37 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
matchingNode->base = leftNode->base;
matchingNode->length += leftNode->length;
- allocatorResNodeOwnerClear(leftNode);
+ allocatorResNodeOwnerClear(rmHandle, leftNode);
rmResourceNodeFree(leftNode);
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ if (rightNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ }
}
else if (combineRight) {
/* Combine right and matching nodes. Reinsert left. */
matchingNode->length += rightNode->length;
- allocatorResNodeOwnerClear(rightNode);
+ allocatorResNodeOwnerClear(rmHandle, rightNode);
rmResourceNodeFree(rightNode);
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+ if (leftNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+ }
}
else {
/* No combine. */
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ if (leftNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+ }
+ if (rightNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ }
}
/* Always reinsert matchingNode */
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+
+ /* Matching node contains new reference count after alloc. Return new owner count. */
+ opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
}
else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
/* findNode range is subset of matchingNode range and neither boundary is
@@ -642,18 +718,21 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
*/
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
- allocatorResNodeOwnerCopy(leftNode, matchingNode);
+ allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
- allocatorResNodeOwnerCopy(rightNode, matchingNode);
+ allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
matchingNode->base = findNode.base;
matchingNode->length = findNode.length;
- allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
/* Insert all the nodes */
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+
+ /* Matching node contains new reference count after alloc. Return new owner count. */
+ opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
}
else {
if (findNode.base == matchingNode->base) {
@@ -666,16 +745,17 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
/* Add allocating instance to owner list for compare with leftNode */
- allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
- if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+ if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
/* Combine leftNode and findNode */
leftNode->length += findNode.length;
}
else {
leftNode = rmResourceNodeNew(findNode.base, findNode.length);
- allocatorResNodeOwnerCopy(leftNode, matchingNode);
+ allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
}
/* Account for leftNode in matchingNode */
@@ -683,6 +763,8 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
matchingNode->length = matchingEnd - findEnd;
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+ /* Left node contains new reference count after alloc. Return new owner count. */
+ opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
}
else if (findEnd == matchingEnd) {
/* findNode end and matchingNode end are equivalent. May be combine
@@ -694,9 +776,10 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
/* Add allocating instance to owner list for compare with rightNode */
- allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
- if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+ if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
/* Combine rightNode and findNode */
rightNode->base = findNode.base;
@@ -704,16 +787,18 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
}
else {
rightNode = rmResourceNodeNew(findNode.base, findNode.length);
- allocatorResNodeOwnerCopy(rightNode, matchingNode);
+ allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
}
/* Account for rightNode in matchingNode */
matchingNode->length -= findNode.length;
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ /* Right node contains new reference count after alloc. Return new owner count. */
+ opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
}
/* Remove allocating instance from leftover matchingNode */
- allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
}
}
@@ -743,7 +828,7 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
* become equivalent (in terms of ownership) after the
* allocation.
*/
-static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
+static int32_t allocatorFree(Rm_Handle rmHandle, Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
{
Rm_ResourceNode findNode;
Rm_ResourceNode *matchingNode = NULL;
@@ -755,7 +840,7 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
uint32_t matchingEnd;
int32_t retVal;
- memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));
+ memset((void *)&findNode, 0, sizeof(findNode));
findNode.base = opInfo->resourceInfo->base;
findNode.length = opInfo->resourceInfo->length;
matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
@@ -766,7 +851,7 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
if (matchingNode->allocationCount) {
- if (allocatorResNodeIsOwnedBy(matchingNode, opInfo->serviceSrcInstNode)) {
+ if (allocatorResNodeIsOwnedBy(rmHandle, matchingNode, opInfo->serviceSrcInstNode)) {
if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))
{
/* Case 1: Free range equals allocated matched node exactly. Attempt to combine
@@ -778,13 +863,15 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
- allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
- if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+ if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
combineLeft = RM_TRUE;
}
- if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+ if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
combineRight = RM_TRUE;
}
@@ -794,9 +881,9 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
matchingNode->base = leftNode->base;
matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;
- allocatorResNodeOwnerClear(leftNode);
+ allocatorResNodeOwnerClear(rmHandle, leftNode);
rmResourceNodeFree(leftNode);
- allocatorResNodeOwnerClear(rightNode);
+ allocatorResNodeOwnerClear(rmHandle, rightNode);
rmResourceNodeFree(rightNode);
}
else if (combineLeft) {
@@ -804,26 +891,37 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
matchingNode->base = leftNode->base;
matchingNode->length += leftNode->length;
- allocatorResNodeOwnerClear(leftNode);
+ allocatorResNodeOwnerClear(rmHandle, leftNode);
rmResourceNodeFree(leftNode);
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ if (rightNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ }
}
else if (combineRight) {
/* Combine right and matching nodes. Reinsert left. */
matchingNode->length += rightNode->length;
- allocatorResNodeOwnerClear(rightNode);
+ allocatorResNodeOwnerClear(rmHandle, rightNode);
rmResourceNodeFree(rightNode);
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+ if (leftNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+ }
}
else {
/* No combine. */
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ if (leftNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+ }
+ if (rightNode) {
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+ }
}
/* Always reinsert matchingNode */
- RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+ RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+
+ /* Matching node is what remains after free. Return remaining owner count. */
+ opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
}
else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {
/* Case 2: Free range is less than range in matched node. Split
@@ -836,21 +934,24 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
* proper accounting of allocations in validInstance list
*/
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
- allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
leftNode = rmResourceNodeNew(matchingNode->base, findNode.base - matchingNode->base);
- allocatorResNodeOwnerCopy(leftNode, matchingNode);
- allocatorResNodeOwnerAdd(leftNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
+ allocatorResNodeOwnerAdd(rmHandle, leftNode, opInfo->serviceSrcInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
rightNode = rmResourceNodeNew(findNode.base + findNode.length, matchingEnd - findEnd);
- allocatorResNodeOwnerCopy(rightNode, matchingNode);
- allocatorResNodeOwnerAdd(rightNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
+ allocatorResNodeOwnerAdd(rmHandle, rightNode, opInfo->serviceSrcInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
matchingNode->base = findNode.base;
matchingNode->length = findNode.length;
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+
+ /* Matching node is what remains after free. Return remaining owner count. */
+ opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
}
else {
if (findNode.base == matchingNode->base) {
@@ -864,22 +965,26 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
leftNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
/* Remove freeing instance from owner list for compare with leftNode */
- allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
- if (leftNode && allocatorResNodeOwnerCompare(leftNode, matchingNode)) {
+ if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
/* Combine leftNode and findNode */
leftNode->length += findNode.length;
}
else {
leftNode = rmResourceNodeNew(findNode.base, findNode.length);
- allocatorResNodeOwnerCopy(leftNode, matchingNode);
+ allocatorResNodeOwnerCopy(rmHandle, leftNode, matchingNode);
}
/* Remove leftNode range from matchingNode */
matchingNode->base = findNode.base + findNode.length;
matchingNode->length = matchingEnd - findEnd;
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
+
+ /* Left node is what remains after free. Return remaining owner count. */
+ opInfo->resourceInfo->ownerCount = leftNode->allocationCount;
}
else if (findEnd == matchingEnd) {
/* Case 4: Free range is on right boundary of matched node. Try to
@@ -892,9 +997,10 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
rightNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
/* Remove freeing instance from owner list for compare with rightNode */
- allocatorResNodeOwnerDelete(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
- if (rightNode && allocatorResNodeOwnerCompare(rightNode, matchingNode)) {
+ if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+ allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
/* Combine rightNode and findNode */
rightNode->base = findNode.base;
@@ -902,26 +1008,32 @@ static int32_t allocatorFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo
}
else {
rightNode = rmResourceNodeNew(findNode.base, findNode.length);
- allocatorResNodeOwnerCopy(rightNode, matchingNode);
+ allocatorResNodeOwnerCopy(rmHandle, rightNode, matchingNode);
}
/* Remove rightNode range from matchingNode */
matchingNode->length -= findNode.length;
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
+
+ /* Right node is what remains after free. Return remaining owner count. */
+ opInfo->resourceInfo->ownerCount = rightNode->allocationCount;
}
/* Add freeing instance back into matchingNode allocations */
- allocatorResNodeOwnerAdd(matchingNode, opInfo->serviceSrcInstNode);
+ allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
}
-
retVal = RM_SERVICE_APPROVED;
}
else {
+ /* Return owner count. In case it's a reference count check in application */
+ opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
retVal = RM_SERVICE_DENIED_RES_NOT_ALLOCD_TO_INST;
}
}
else {
+ /* Return owner count. In case it's a reference count check in application */
+ opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
retVal = RM_SERVICE_DENIED_RES_ALREADY_FREE;
}
}
@@ -1000,20 +1112,20 @@ static int32_t allocatorFindLinuxResource(Rm_Handle rmHandle, const char *resour
int32_t propOffset;
int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
int32_t prevDepth = RM_DTB_UTIL_STARTING_DEPTH;
- int32_t depth;
+ int32_t depth = RM_DTB_UTIL_STARTING_DEPTH;
int32_t propertyLen;
const char *propertyName;
const void *propertyData;
Rm_LinuxValueRange *linuxValueRange;
int32_t retVal = RM_OK;
- memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));
- memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));
+ memset((void *)&opInfo, 0, sizeof(opInfo));
+ memset((void *)&resourceInfo, 0, sizeof(resourceInfo));
strncpy(resourceInfo.name, resourceName, RM_NAME_MAX_CHARS);
opInfo.policy = rmInst->u.server.globalPolicy;
- opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmInst->u.server.globalValidInstTree);
- opInfo.operation = Rm_allocatorOp_ALLOCATE;
+ opInfo.serviceSrcInstNode = rmPolicyGetLinuxInstNode(rmHandle);
+ opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
opInfo.resourceInfo = &resourceInfo;
while(linuxAlias) {
@@ -1108,7 +1220,7 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
range = rangeBasePtr = rmDtbUtilResExtractRange(resourceProperties->rangeData,
resourceProperties->rangeLen);
- if ((retVal = allocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
+ if ((retVal = rmAllocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen) {
if (linuxDtb) {
linuxAlias = rmDtbUtilResExtractLinuxAlias(resourceProperties->linuxAliasData,
@@ -1117,9 +1229,6 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
retVal = allocatorFindLinuxResource(rmHandle, resourceName, linuxDtb, linuxAlias);
}
}
- else {
- retVal = RM_ERROR_GRL_LINUX_ALIAS_BUT_NO_DTB;
- }
}
}
}
@@ -1130,8 +1239,11 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
resourceProperties->nsAssignLen, &retVal);
if (nsAssignments) {
nsAssignmentBasePtr = nsAssignments;
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeInv(rmInst->u.server.nameServer);
+ }
while (nsAssignments) {
- memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+ memset((void *)&nameServerObjCfg, 0, sizeof(nameServerObjCfg));
nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
nameServerObjCfg.nodeCfg.objName = nsAssignments->nsName;
nameServerObjCfg.nodeCfg.resourceName = (char *)resourceName;
@@ -1140,10 +1252,16 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
rmNameServerAddObject(&nameServerObjCfg);
nsAssignments = nsAssignments->nextNsAssignment;
}
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmNameServerTreeWb(rmInst->u.server.nameServer);
+ }
rmDtbUtilResFreeNsAssignmentList(nsAssignmentBasePtr);
}
}
}
+ else {
+ rmAllocatorDelete(rmHandle, resourceName);
+ }
rmDtbUtilResFreeRange(rangeBasePtr);
if (linuxAlias) {
@@ -1156,14 +1274,69 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
********************** Internal Functions ****************************
**********************************************************************/
+/* FUNCTION PURPOSE: Creates a new resource tree
+ ***********************************************************************
+ * DESCRIPTION: Creates and populates a new resource tree allocator
+ * using the provided resource name and value range. The
+ * name and value originate from the GRL.
+ */
+int32_t rmAllocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Allocator *allocator = NULL;
+ Rm_ResourceTree *treeRoot = NULL;
+ Rm_ResourceNode *treeNode = NULL;
+
+ allocator = allocatorAdd(rmHandle, resourceName);
+ treeRoot = Rm_osalMalloc(sizeof(*treeRoot));
+ RB_INIT(treeRoot);
+
+ while (range != NULL) {
+ treeNode = rmResourceNodeNew(range->base, range->length);
+ RB_INSERT(_Rm_AllocatorResourceTree, treeRoot, treeNode);
+ range = range->nextRange;
+ }
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmResourceTreeWb(treeRoot);
+ }
+
+ allocator->allocatorRootEntry = treeRoot;
+ RM_SS_OBJ_WB(allocator, Rm_Allocator);
+ return(RM_OK);
+}
+
+/* FUNCTION PURPOSE: Returns a pointer to the allocator list
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the instance's allocator list
+ * based on the instance type
+ */
+Rm_Allocator *rmAllocatorGetAllocatorList(Rm_Handle rmHandle)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Allocator *list = NULL;
+
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ list = rmInst->u.server.allocators;
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ list = rmInst->u.cd.allocators;
+ }
+ return(list);
+}
+
/* FUNCTION PURPOSE: Finds an allocator
***********************************************************************
* DESCRIPTION: Returns a pointer to an allocator that matches the
* provided resource name.
*/
-Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)
+Rm_Allocator *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Allocator *allocatorList = rmAllocatorGetAllocatorList(rmHandle);
+
while (allocatorList) {
+ RM_SS_OBJ_INV(allocatorList, Rm_Allocator);
if (strncmp(allocatorList->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
break;
}
@@ -1173,6 +1346,75 @@ Rm_Allocator *rmAllocatorFind(Rm_Allocator *allocatorList, char *resourceName)
return (allocatorList);
}
+/* FUNCTION PURPOSE: Checks if a resource node is localized
+ ***********************************************************************
+ * DESCRIPTION: Checks if a resource node is localized. A localized
+ * node is one that is free and has no neighboring nodes
+ * or neighboring nodes that do not have resource values
+ * contiguous with the node being checked. The function
+ * will return RM_TRUE is the node is localized.
+ * Otherwise, the function returns RM_FALSE
+ */
+int rmAllocatorGetNodeLocalization(Rm_Handle rmHandle, char *resourceName,
+ int32_t *resBase, uint32_t *resLen)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ void * policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+ int32_t resOffsetInPolicy = rmPolicyGetResourceOffset(policy, resourceName);
+ uint32_t allocSize = rmPolicyGetResourceCdAllocSize(policy, resOffsetInPolicy);
+ Rm_Allocator *allocator = rmAllocatorFind(rmHandle, resourceName);
+ Rm_ResourceNode findNode;
+ Rm_ResourceNode *matchingNode = NULL;
+ Rm_ResourceNode *neighborNode = NULL;
+ int nodeIsLocalized;
+
+ memset((void *)&findNode, 0, sizeof(findNode));
+ findNode.base = *resBase;
+ findNode.length = *resLen;
+ matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+ if (matchingNode) {
+ /* Node can be freed back to Server from CD if:
+ * - allocationCount == 0
+ * - node's resource range is multiple of policy allocation size
+ * - node's resource range boundaries are not contiguous with surrounding nodes */
+ if (matchingNode->allocationCount) {
+ nodeIsLocalized = RM_FALSE;
+ goto exitLocalization;
+ }
+
+ if (matchingNode->length % allocSize) {
+ nodeIsLocalized = RM_FALSE;
+ goto exitLocalization;
+ }
+
+ /* Check left neighbor */
+ neighborNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+ if (neighborNode && allocatorResNodeBoundaryCompare(neighborNode, matchingNode)) {
+ nodeIsLocalized = RM_FALSE;
+ goto exitLocalization;
+ }
+
+ /* Check right neighbor */
+ neighborNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+ if (neighborNode && allocatorResNodeBoundaryCompare(neighborNode, matchingNode)) {
+ nodeIsLocalized = RM_FALSE;
+ goto exitLocalization;
+ }
+
+ /* All localization checks passed. Return the base and length of localized node. */
+ nodeIsLocalized = RM_TRUE;
+ *resBase = matchingNode->base;
+ *resLen = matchingNode->length;
+ }
+ else {
+ nodeIsLocalized = RM_FALSE;
+ }
+
+exitLocalization:
+ return (nodeIsLocalized);
+}
+
/* FUNCTION PURPOSE: Issues an allocator operation
***********************************************************************
* DESCRIPTION: Issues an allocator preallocate, allocate, or free
@@ -1186,18 +1428,33 @@ int32_t rmAllocatorOperation(Rm_Handle rmHandle, Rm_AllocatorOpInfo *opInfo)
int32_t retVal;
resourceOffsetInPolicy = rmPolicyGetResourceOffset(opInfo->policy, opInfo->resourceInfo->name);
- allocator = rmAllocatorFind(rmInst->u.server.allocators, opInfo->resourceInfo->name);
+ allocator = rmAllocatorFind(rmHandle, opInfo->resourceInfo->name);
if ((resourceOffsetInPolicy > 0) && allocator) {
- if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmResourceTreeInv(allocator->allocatorRootEntry);
+ }
+
+ if (opInfo->operation == Rm_allocatorOp_GET_STATUS) {
+ retVal = allocatorStatus(allocator, opInfo);
+ }
+ else if ((opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) ||
+ (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_USE)) {
retVal = allocatorPreAllocate(rmHandle, allocator, resourceOffsetInPolicy, opInfo);
}
- else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {
+ else if ((opInfo->operation == Rm_allocatorOp_ALLOCATE_INIT) ||
+ (opInfo->operation == Rm_allocatorOp_ALLOCATE_USE)) {
retVal = allocatorAllocate(rmHandle, allocator, resourceOffsetInPolicy, opInfo);
}
else if (opInfo->operation == Rm_allocatorOp_FREE) {
- retVal = allocatorFree(allocator, opInfo);
- }
+ retVal = allocatorFree(rmHandle, allocator, opInfo);
+ }
+
+ if ((rmInst->instType == Rm_instType_SHARED_SERVER) &&
+ (opInfo->operation != Rm_allocatorOp_GET_STATUS) &&
+ (retVal == RM_SERVICE_APPROVED)) {
+ rmResourceTreeWb(allocator->allocatorRootEntry);
+ }
}
else {
/* Resource could not be found in policy and/or allocator */
@@ -1226,7 +1483,7 @@ int32_t rmAllocatorInitializeResources(Rm_Handle rmHandle, void *globalResourceD
/* Parse the Global Resource List, creating an allocator for each specified resource node */
while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (nodeDepth >= RM_DTB_UTIL_STARTING_DEPTH)) {
- memset((void *)&resProperties, 0, sizeof(Rm_ResourceProperties));
+ memset((void *)&resProperties, 0, sizeof(resProperties));
/* Get properties of resource node */
propOffset = fdt_first_property_offset(globalResourceDtb, nodeOffset);
while (propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) {
return(retVal);
}
+/* FUNCTION PURPOSE: Deletes a resource allocator resource node
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator's node based on the given
+ * resource name, base and length.
+ */
+void rmAllocatorDeleteNode(Rm_Handle rmHandle, const char *resName, int32_t resBase, uint32_t resLen)
+{
+ Rm_Allocator *allocator = rmAllocatorFind(rmHandle, resName);
+ Rm_ResourceNode findNode;
+ Rm_ResourceNode *matchingNode;
+
+ memset((void *)&findNode, 0, sizeof(findNode));
+ findNode.base = resBase;
+ findNode.length = resLen;
+ matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+ if (matchingNode) {
+ RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+ rmResourceNodeFree(matchingNode);
+ }
+}
+
+/* FUNCTION PURPOSE: Deletes a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator based on the given
+ * resource name. The resource allocator will be
+ * removed from the RM instance allocator list.
+ */
+int32_t rmAllocatorDelete(Rm_Handle rmHandle, const char *resourceName)
+{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Allocator *allocator = rmAllocatorGetAllocatorList(rmHandle);
+ Rm_Allocator *prevAllocator = NULL;
+ Rm_ResourceTree *treeRoot;
+ Rm_ResourceNode *node = NULL;
+ Rm_ResourceNode *nextNode = NULL;
+ int32_t retVal = RM_OK;
+
+ while (allocator) {
+ if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+ break;
+ }
+ prevAllocator = allocator;
+ allocator = allocator->nextAllocator;
+ }
+
+ if (allocator) {
+ if (prevAllocator == NULL) {
+ if ((rmInst->instType == Rm_instType_SERVER) ||
+ (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+ rmInst->u.server.allocators = allocator->nextAllocator;
+ }
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+ rmInst->u.cd.allocators = allocator->nextAllocator;
+ }
+ }
+ else {
+ prevAllocator->nextAllocator = allocator->nextAllocator;
+ RM_SS_OBJ_WB(prevAllocator, Rm_Allocator);
+ }
+
+ /* Destroy tree and return error */
+ treeRoot = allocator->allocatorRootEntry;
+ for (node = RB_MIN(_Rm_AllocatorResourceTree, treeRoot); node != NULL; node = nextNode) {
+ nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRoot, node);
+ RB_REMOVE(_Rm_AllocatorResourceTree, treeRoot, nextNode);
+ rmResourceNodeFree(node);
+ }
+ Rm_osalFree((void *)treeRoot, sizeof(*treeRoot));
+ Rm_osalFree((void *)allocator, sizeof(*allocator));
+ }
+ else {
+ retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
+ }
+ return (retVal);
+}
+
/* FUNCTION PURPOSE: Deletes server allocators
***********************************************************************
* DESCRIPTION: Removes all resource nodes for each
* itself. Used to free all memory consumed
* by the allocators.
*/
-void rmAllocatorDeleteResources(Rm_Allocator *allocatorList)
+void rmAllocatorDeleteResources(Rm_Handle rmHandle)
{
+ Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
+ Rm_Allocator *allocatorList = rmAllocatorGetAllocatorList(rmHandle);
Rm_Allocator *nextAllocator;
Rm_ResourceTree *resTree;
Rm_ResourceNode *resNode;
Rm_ResourceNode *nextResNode;
while (allocatorList) {
+ RM_SS_OBJ_INV(allocatorList, Rm_Allocator);
nextAllocator = allocatorList->nextAllocator;
resTree = allocatorList->allocatorRootEntry;
+ if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+ rmResourceTreeInv(resTree);
+ }
/* Delete each resource node in the allocator */
for (resNode = RB_MIN(_Rm_AllocatorResourceTree, resTree); resNode != NULL; resNode = nextResNode) {
nextResNode = RB_NEXT(_Rm_AllocatorResourceTree, resTree, resNode);
RB_REMOVE(_Rm_AllocatorResourceTree, resTree, resNode);
if (resNode->allocationCount) {
/* Delete all the owners in the resource's owner list */
- allocatorResNodeOwnerClear(resNode);
+ allocatorResNodeOwnerClear(rmHandle, resNode);
}
rmResourceNodeFree(resNode);
}
- if (RB_MIN(_Rm_AllocatorResourceTree, resTree) == NULL) {
- /* No more resource nodes in allocator */
- Rm_osalFree((void *)resTree, sizeof(Rm_ResourceTree));
- }
- Rm_osalFree((void *)allocatorList, sizeof(Rm_Allocator));
+
+ Rm_osalFree((void *)resTree, sizeof(*resTree));
+ Rm_osalFree((void *)allocatorList, sizeof(*allocatorList));
allocatorList = nextAllocator;
}
}