From: VMware, Inc <> Date: Thu, 17 Jun 2010 21:11:54 +0000 (-0700) Subject: lib/lock: press for a harder MX/MXUser separation X-Git-Tag: 2010.06.16-268169~160 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=62a8a5d9ea475453cdaf12841f29b5a893e3101d;p=thirdparty%2Fopen-vm-tools.git lib/lock: press for a harder MX/MXUser separation Since there is a function for MX to register hook functions with MXUser, enhance it to provide additional function that allow removing even more MX references throughout MXUser. This change makes it possible to expose the bind MX to MXUser functionality to userland - we can use that functionality outside the VMX now. The mutex.h and userlock.h include files are tweaked so that things work properly if either of them comes first and the userlock.h file is able to stand on its own inside and outside the VMX. Signed-off-by: Marcelo Vanzin --- diff --git a/open-vm-tools/lib/include/userlock.h b/open-vm-tools/lib/include/userlock.h index 5b8a1edb8..20e9acb87 100644 --- a/open-vm-tools/lib/include/userlock.h +++ b/open-vm-tools/lib/include/userlock.h @@ -131,23 +131,20 @@ void MXUser_DestroyCondVar(MXUserCondVar *condVar); #define MXUSER_DEFAULT_HISTO_MIN_VALUE_NS 1000 // 1 usec #define MXUSER_DEFAULT_HISTO_DECADES 7 // 1 usec to 10 seconds -#if defined(VMX86_VMX) -#include "mutex.h" - -MXUserRecLock *MXUser_BindMXMutexRec(MX_MutexRec *mutex); -MX_MutexRec *MXUser_GetRecLockVmm(const MXUserRecLock *lock); -MX_Rank MXUser_GetRecLockRank(const MXUserRecLock *lock); +struct MX_MutexRec; -MXUserRecLock *MXUser_InitFromMXRec(const char *name, MX_MutexRec *mutex, - MX_Rank rank, Bool isBelowBull); +#if defined(VMX86_VMX) +MXUserRecLock *MXUser_InitFromMXRec(const char *name, + struct MX_MutexRec *mutex, + MX_Rank rank, + Bool isBelowBull); #if defined(__i386__) || defined(__x86_64__) -#if defined(VMX86_STATS) +#if defined(VMX86_STATS) #define MXUSER_STATS // stats "only inside the VMX" when requested #endif #endif // X86 and X86-64 - -#endif // VMX86_VMX +#endif #if defined(VMX86_DEBUG) #define MXUSER_DEBUG // debugging "everywhere" when requested @@ -164,7 +161,10 @@ void MXUser_StatisticsControl(double contentionRatio, void MXUser_LogStats(unsigned epoch); #endif -extern void MXUser_SetInPanic(void); -extern Bool MXUser_InPanic(void); +void MXUser_SetInPanic(void); +Bool MXUser_InPanic(void); +MXUserRecLock *MXUser_BindMXMutexRec(struct MX_MutexRec *mutex); +struct MX_MutexRec *MXUser_GetRecLockVmm(const MXUserRecLock *lock); +MX_Rank MXUser_GetRecLockRank(const MXUserRecLock *lock); #endif // _USERLOCK_H_ diff --git a/open-vm-tools/lib/lock/ul.c b/open-vm-tools/lib/lock/ul.c index eb8606b98..30c322069 100644 --- a/open-vm-tools/lib/lock/ul.c +++ b/open-vm-tools/lib/lock/ul.c @@ -21,6 +21,7 @@ #include "util.h" #include "userlock.h" #include "ulInt.h" +#include "ulIntShared.h" #include "hashTable.h" @@ -30,6 +31,10 @@ Bool (*MXUserTryAcquireForceFail)() = NULL; static MX_Rank (*MXUserMxCheckRank)(void) = NULL; static void (*MXUserMxLockLister)(void) = NULL; +void (*MXUserMX_LockRec)(struct MX_MutexRec *lock) = NULL; +void (*MXUserMX_UnlockRec)(struct MX_MutexRec *lock) = NULL; +Bool (*MXUserMX_TryLockRec)(struct MX_MutexRec *lock) = NULL; +Bool (*MXUserMX_IsLockedByCurThreadRec)(const struct MX_MutexRec *lock) = NULL; #if defined(MXUSER_DEBUG) || defined(MXUSER_STATS) @@ -561,8 +566,12 @@ MXUser_InPanic(void) */ void -MXUserInstallMxHooks(void (*theMxLockLister)(void), // IN: MX list function - MX_Rank (*theMxRankFunc)(void)) // IN: MX rank function +MXUserInstallMxHooks(void (*theLockListFunc)(void), + MX_Rank (*theRankFunc)(void), + void (*theLockFunc)(struct MX_MutexRec *lock), + void (*theUnlockFunc)(struct MX_MutexRec *lock), + Bool (*theTryLockFunc)(struct MX_MutexRec *lock), + Bool (*theIsLockedFunc)(const struct MX_MutexRec *lock)) { /* * This function can be called more than once but the second and later @@ -571,12 +580,24 @@ MXUserInstallMxHooks(void (*theMxLockLister)(void), // IN: MX list function */ if ((MXUserMxLockLister == NULL) && - (MXUserMxCheckRank == NULL)) { - MXUserMxLockLister = theMxLockLister; - MXUserMxCheckRank = theMxRankFunc; + (MXUserMxCheckRank == NULL) && + (MXUserMX_LockRec == NULL) && + (MXUserMX_UnlockRec == NULL) && + (MXUserMX_TryLockRec == NULL) && + (MXUserMX_IsLockedByCurThreadRec == NULL)) { + MXUserMxLockLister = theLockListFunc; + MXUserMxCheckRank = theRankFunc; + MXUserMX_LockRec = theLockFunc; + MXUserMX_UnlockRec = theUnlockFunc; + MXUserMX_TryLockRec = theTryLockFunc; + MXUserMX_IsLockedByCurThreadRec = theIsLockedFunc; } else { - ASSERT((MXUserMxLockLister == theMxLockLister) && - (MXUserMxCheckRank == theMxRankFunc) + ASSERT((MXUserMxLockLister == theLockListFunc) && + (MXUserMxCheckRank == theRankFunc) && + (MXUserMX_LockRec == theLockFunc) && + (MXUserMX_UnlockRec == theUnlockFunc) && + (MXUserMX_TryLockRec == theTryLockFunc) && + (MXUserMX_IsLockedByCurThreadRec == theIsLockedFunc) ); } } diff --git a/open-vm-tools/lib/lock/ulInt.h b/open-vm-tools/lib/lock/ulInt.h index bfc4c7863..e0df7d4e8 100644 --- a/open-vm-tools/lib/lock/ulInt.h +++ b/open-vm-tools/lib/lock/ulInt.h @@ -38,7 +38,6 @@ typedef pthread_t MXThreadID; #include "vm_basic_types.h" #include "vthreadBase.h" -#include "ulIntShared.h" #if defined(MXUSER_STATS) #include "circList.h" @@ -556,4 +555,9 @@ void MXUserForceHisto(Atomic_Ptr *histoPtr, uint32 decades); #endif +extern void (*MXUserMX_LockRec)(struct MX_MutexRec *lock); +extern void (*MXUserMX_UnlockRec)(struct MX_MutexRec *lock); +extern Bool (*MXUserMX_TryLockRec)(struct MX_MutexRec *lock); +extern Bool (*MXUserMX_IsLockedByCurThreadRec)(const struct MX_MutexRec *lock); + #endif diff --git a/open-vm-tools/lib/lock/ulIntShared.h b/open-vm-tools/lib/lock/ulIntShared.h index 330332388..9e2d439c4 100644 --- a/open-vm-tools/lib/lock/ulIntShared.h +++ b/open-vm-tools/lib/lock/ulIntShared.h @@ -22,6 +22,10 @@ extern void MXUserListLocks(void); extern void MXUserInstallMxHooks(void (*theLockListFunc)(void), - MX_Rank (*theRankFunc)(void)); + MX_Rank (*theRankFunc)(void), + void (*theLockFunc)(struct MX_MutexRec *lock), + void (*theUnlockFunc)(struct MX_MutexRec *lock), + Bool (*theTryLockFunc)(struct MX_MutexRec *lock), + Bool (*theIsLockedFunc)(const struct MX_MutexRec *lock)); #endif diff --git a/open-vm-tools/lib/lock/ulRec.c b/open-vm-tools/lib/lock/ulRec.c index 99ad0d243..f19075ea2 100644 --- a/open-vm-tools/lib/lock/ulRec.c +++ b/open-vm-tools/lib/lock/ulRec.c @@ -22,37 +22,6 @@ #include "userlock.h" #include "ulInt.h" -#if defined(VMX86_VMX) -#include "mutexInt.h" -#include "mutexRank.h" -#else -typedef struct MX_MutexRec MX_MutexRec; - -static INLINE void -MX_LockRec(MX_MutexRec *lock) // IN: -{ - NOT_IMPLEMENTED(); -} - -static INLINE void -MX_UnlockRec(MX_MutexRec *lock) // IN: -{ - NOT_IMPLEMENTED(); -} - -static INLINE Bool -MX_TryLockRec(MX_MutexRec *lock) // IN: -{ - NOT_IMPLEMENTED(); -} - -static INLINE Bool -MX_IsLockedByCurThreadRec(MX_MutexRec *lock) // IN: -{ - NOT_IMPLEMENTED(); -} -#endif - struct MXUserRecLock { MXUserHeader header; @@ -79,7 +48,7 @@ struct MXUserRecLock * MXUser_BindMXMutexRec was used to create the lock */ - MX_MutexRec *vmmLock; + struct MX_MutexRec *vmmLock; }; #if defined(MXUSER_STATS) @@ -279,7 +248,7 @@ MXUser_DestroyRecLock(MXUserRecLock *lock) // IN: if (lock != NULL) { ASSERT(lock->header.lockSignature == USERLOCK_SIGNATURE); - if (!lock->vmmLock) { + if (lock->vmmLock == NULL) { if (MXRecLockCount(&lock->recursiveLock) > 0) { MXUserDumpAndPanic(&lock->header, "%s: Destroy of an acquired recursive lock\n", @@ -327,7 +296,8 @@ MXUser_AcquireRecLock(MXUserRecLock *lock) // IN/OUT: ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); if (lock->vmmLock) { - MX_LockRec(lock->vmmLock); + ASSERT(MXUserMX_LockRec); + (*MXUserMX_LockRec)(lock->vmmLock); } else { #if defined(MXUSER_STATS) Bool contended; @@ -386,7 +356,8 @@ MXUser_ReleaseRecLock(MXUserRecLock *lock) // IN/OUT: ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); if (lock->vmmLock) { - MX_UnlockRec(lock->vmmLock); + ASSERT(MXUserMX_UnlockRec); + (*MXUserMX_UnlockRec)(lock->vmmLock); } else { #if defined(MXUSER_STATS) if (MXRecLockCount(&lock->recursiveLock) == 1) { @@ -448,7 +419,8 @@ MXUser_TryAcquireRecLock(MXUserRecLock *lock) // IN/OUT: ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); if (lock->vmmLock) { - success = MX_TryLockRec(lock->vmmLock); + ASSERT(MXUserMX_TryLockRec); + success = (*MXUserMX_TryLockRec)(lock->vmmLock); } else { #if defined(MXUSER_STATS) uint64 begin; @@ -500,10 +472,17 @@ MXUser_TryAcquireRecLock(MXUserRecLock *lock) // IN/OUT: Bool MXUser_IsCurThreadHoldingRecLock(const MXUserRecLock *lock) // IN: { + Bool result; ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); - return (lock->vmmLock) ? MX_IsLockedByCurThreadRec(lock->vmmLock) : - MXRecLockIsOwner(&lock->recursiveLock); + if (lock->vmmLock) { + ASSERT(MXUserMX_IsLockedByCurThreadRec); + result = (*MXUserMX_IsLockedByCurThreadRec)(lock->vmmLock); + } else { + result = MXRecLockIsOwner(&lock->recursiveLock); + } + + return result; } @@ -532,6 +511,7 @@ MXUser_ControlRecLock(MXUserRecLock *lock, // IN/OUT: Bool result; ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); + ASSERT(lock->vmmLock == NULL); // only unbound locks switch (command) { #if defined(MXUSER_STATS) @@ -646,6 +626,7 @@ MXUserCondVar * MXUser_CreateCondVarRecLock(MXUserRecLock *lock) { ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); + ASSERT(lock->vmmLock == NULL); // only unbound locks return MXUserCreateCondVar(&lock->header, &lock->recursiveLock); } @@ -674,12 +655,12 @@ MXUser_WaitCondVarRecLock(MXUserRecLock *lock, // IN: MXUserCondVar *condVar) // IN: { ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); + ASSERT(lock->vmmLock == NULL); // only unbound locks MXUserWaitCondVar(&lock->header, &lock->recursiveLock, condVar); } -#if defined(VMX86_VMX) /* *----------------------------------------------------------------------------- * @@ -696,7 +677,7 @@ MXUser_WaitCondVarRecLock(MXUserRecLock *lock, // IN: *----------------------------------------------------------------------------- */ -MX_MutexRec * +struct MX_MutexRec * MXUser_GetRecLockVmm(const MXUserRecLock *lock) // IN: { ASSERT(lock && (lock->header.lockSignature == USERLOCK_SIGNATURE)); @@ -749,12 +730,24 @@ MXUser_GetRecLockRank(const MXUserRecLock *lock) // IN: */ MXUserRecLock * -MXUser_BindMXMutexRec(MX_MutexRec *mutex) // IN: +MXUser_BindMXMutexRec(struct MX_MutexRec *mutex) // IN: { MXUserRecLock *lock; ASSERT(mutex); + /* + * Cannot perform a binding unless MX_Init has been called. As a side + * effect it registers these hook functions. + */ + + if ((MXUserMX_LockRec == NULL) || + (MXUserMX_UnlockRec == NULL) || + (MXUserMX_TryLockRec == NULL) || + (MXUserMX_IsLockedByCurThreadRec == NULL)) { + return NULL; + } + /* * Initialize the header (so it looks correct in memory) but don't connect * this lock to the MXUser statistics or debugging tracking - the MX lock @@ -763,11 +756,10 @@ MXUser_BindMXMutexRec(MX_MutexRec *mutex) // IN: lock = Util_SafeCalloc(1, sizeof(*lock)); - lock->header.lockName = Str_SafeAsprintf(NULL, "MX_LockID%d", - mutex->lck.lid); + lock->header.lockName = Str_SafeAsprintf(NULL, "MX_%p", mutex); lock->header.lockSignature = USERLOCK_SIGNATURE; - lock->header.lockRank = mutex->lck.rank; + lock->header.lockRank = RANK_UNRANKED; // unused lock->header.lockDumper = NULL; #if defined(MXUSER_STATS) @@ -781,6 +773,9 @@ MXUser_BindMXMutexRec(MX_MutexRec *mutex) // IN: } +#if defined(VMX86_VMX) +#include "mutex.h" + /* *---------------------------------------------------------------------------- *