sys, dll: convert memory barriers to interlocked operations

This commit is contained in:
Bill Zissimopoulos 2022-01-19 10:55:46 +00:00
parent 362b9ceb7c
commit 29251dc2be
No known key found for this signature in database
GPG Key ID: 3D4F95D52C7B3EA3
10 changed files with 55 additions and 64 deletions

View File

@ -709,38 +709,38 @@ __int32 __iso_volatile_load32(const volatile __int32 *);
void __iso_volatile_store32(volatile __int32 *, __int32); void __iso_volatile_store32(volatile __int32 *, __int32);
__int64 __iso_volatile_load64(const volatile __int64 *); __int64 __iso_volatile_load64(const volatile __int64 *);
void __iso_volatile_store64(volatile __int64 *, __int64); void __iso_volatile_store64(volatile __int64 *, __int64);
#define FSP_ATOMIC_VOLATILE_LOAD32(p) __iso_volatile_load32(p) #define FSP_INTERLOCKED__LOAD32(p) __iso_volatile_load32(p)
#define FSP_ATOMIC_VOLATILE_STORE32(p,v)__iso_volatile_store32(p,v) #define FSP_INTERLOCKED__STORE32(p,v) __iso_volatile_store32(p,v)
#define FSP_ATOMIC_VOLATILE_LOAD64(p) __iso_volatile_load64(p) #define FSP_INTERLOCKED__LOAD64(p) __iso_volatile_load64(p)
#define FSP_ATOMIC_VOLATILE_STORE64(p,v)__iso_volatile_store64(p,v) #define FSP_INTERLOCKED__STORE64(p,v) __iso_volatile_store64(p,v)
#else #else
#define FSP_ATOMIC_VOLATILE_LOAD32(p) (*(p)) #define FSP_INTERLOCKED__LOAD32(p) (*(p))
#define FSP_ATOMIC_VOLATILE_STORE32(p,v)(*(p) = (v)) #define FSP_INTERLOCKED__STORE32(p,v) (*(p) = (v))
#define FSP_ATOMIC_VOLATILE_LOAD64(p) (*(p)) #define FSP_INTERLOCKED__LOAD64(p) (*(p))
#define FSP_ATOMIC_VOLATILE_STORE64(p,v)(*(p) = (v)) #define FSP_INTERLOCKED__STORE64(p,v) (*(p) = (v))
#endif #endif
static inline INT32 FspAtomicLoad32(INT32 volatile *p) static inline INT32 FspInterlockedLoad32(INT32 volatile *p)
{ {
#if defined(_M_ARM64) #if defined(_M_ARM64)
void __dmb(unsigned int); void __dmb(unsigned int);
INT32 v = FSP_ATOMIC_VOLATILE_LOAD32(p); INT32 v = FSP_INTERLOCKED__LOAD32(p);
__dmb(0xb); __dmb(0xb);
return v; return v;
#elif defined(_M_X64) || defined(_M_IX86) #elif defined(_M_X64) || defined(_M_IX86)
void _ReadWriteBarrier(void); void _ReadWriteBarrier(void);
INT32 v = FSP_ATOMIC_VOLATILE_LOAD32(p); INT32 v = FSP_INTERLOCKED__LOAD32(p);
_ReadWriteBarrier(); _ReadWriteBarrier();
return v; return v;
#endif #endif
} }
static inline VOID FspAtomicStore32(INT32 volatile *p, INT32 v) static inline VOID FspInterlockedStore32(INT32 volatile *p, INT32 v)
{ {
#if defined(_M_ARM64) #if defined(_M_ARM64)
void __dmb(unsigned int); void __dmb(unsigned int);
__dmb(0xb); __dmb(0xb);
FSP_ATOMIC_VOLATILE_STORE32(p, v); FSP_INTERLOCKED__STORE32(p, v);
__dmb(0xb); __dmb(0xb);
#elif defined(_M_X64) || defined(_M_IX86) #elif defined(_M_X64) || defined(_M_IX86)
@ -749,34 +749,34 @@ static inline VOID FspAtomicStore32(INT32 volatile *p, INT32 v)
#endif #endif
} }
static inline VOID *FspAtomicLoadPointer(VOID *volatile *p) static inline VOID *FspInterlockedLoadPointer(VOID *volatile *p)
{ {
#if defined(_M_ARM64) #if defined(_M_ARM64)
void __dmb(unsigned int); void __dmb(unsigned int);
VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD64((__int64 volatile *)(p)); VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p));
__dmb(0xb); __dmb(0xb);
return v; return v;
#elif defined(_M_X64) #elif defined(_M_X64)
void _ReadWriteBarrier(void); void _ReadWriteBarrier(void);
VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD64((__int64 volatile *)(p)); VOID *v = (VOID *)FSP_INTERLOCKED__LOAD64((__int64 volatile *)(p));
_ReadWriteBarrier(); _ReadWriteBarrier();
return v; return v;
#elif defined(_M_IX86) #elif defined(_M_IX86)
void _ReadWriteBarrier(void); void _ReadWriteBarrier(void);
VOID *v = (VOID *)FSP_ATOMIC_VOLATILE_LOAD32((__int32 volatile *)(p)); VOID *v = (VOID *)FSP_INTERLOCKED__LOAD32((__int32 volatile *)(p));
_ReadWriteBarrier(); _ReadWriteBarrier();
return v; return v;
#endif #endif
} }
static inline VOID FspAtomicStorePointer(VOID *volatile *p, VOID *v) static inline VOID FspInterlockedStorePointer(VOID *volatile *p, VOID *v)
{ {
#if defined(_M_ARM64) #if defined(_M_ARM64)
void __dmb(unsigned int); void __dmb(unsigned int);
__dmb(0xb); __dmb(0xb);
FSP_ATOMIC_VOLATILE_STORE64((__int64 volatile *)(p), (__int64)(v)); FSP_INTERLOCKED__STORE64((__int64 volatile *)(p), (__int64)(v));
__dmb(0xb); __dmb(0xb);
#elif defined(_M_X64) || defined(_M_IX86) #elif defined(_M_X64) || defined(_M_IX86)

View File

@ -1348,9 +1348,7 @@ static inline
VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem, VOID FspFileSystemGetDispatcherResult(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS *PDispatcherResult) NTSTATUS *PDispatcherResult)
{ {
/* 32-bit reads are atomic */ *PDispatcherResult = FspInterlockedLoad32((INT32 *)&FileSystem->DispatcherResult);
*PDispatcherResult = FileSystem->DispatcherResult;
MemoryBarrier();
} }
FSP_API VOID FspFileSystemGetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem, FSP_API VOID FspFileSystemGetDispatcherResultF(FSP_FILE_SYSTEM *FileSystem,
NTSTATUS *PDispatcherResult); NTSTATUS *PDispatcherResult);

View File

@ -227,8 +227,7 @@ static inline VOID FspFileSystemSortDirectoryBuffer(FSP_FILE_SYSTEM_DIRECTORY_BU
FSP_API BOOLEAN FspFileSystemAcquireDirectoryBuffer(PVOID *PDirBuffer, FSP_API BOOLEAN FspFileSystemAcquireDirectoryBuffer(PVOID *PDirBuffer,
BOOLEAN Reset, PNTSTATUS PResult) BOOLEAN Reset, PNTSTATUS PResult)
{ {
FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer);
MemoryBarrier();
if (0 == DirBuffer) if (0 == DirBuffer)
{ {
@ -243,10 +242,9 @@ FSP_API BOOLEAN FspFileSystemAcquireDirectoryBuffer(PVOID *PDirBuffer,
AcquireSRWLockExclusive(&NewDirBuffer->Lock); AcquireSRWLockExclusive(&NewDirBuffer->Lock);
AcquireSRWLockExclusive(&CreateLock); AcquireSRWLockExclusive(&CreateLock);
DirBuffer = *PDirBuffer; DirBuffer = FspInterlockedLoadPointer(PDirBuffer);
MemoryBarrier();
if (0 == DirBuffer) if (0 == DirBuffer)
*PDirBuffer = DirBuffer = NewDirBuffer; FspInterlockedStorePointer(PDirBuffer, DirBuffer = NewDirBuffer);
ReleaseSRWLockExclusive(&CreateLock); ReleaseSRWLockExclusive(&CreateLock);
if (DirBuffer == NewDirBuffer) if (DirBuffer == NewDirBuffer)
@ -274,7 +272,7 @@ FSP_API BOOLEAN FspFileSystemFillDirectoryBuffer(PVOID *PDirBuffer,
{ {
/* assume that FspFileSystemAcquireDirectoryBuffer has been called */ /* assume that FspFileSystemAcquireDirectoryBuffer has been called */
FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer);
ULONG Capacity, LoMark, HiMark; ULONG Capacity, LoMark, HiMark;
PUINT8 Buffer; PUINT8 Buffer;
@ -333,7 +331,7 @@ FSP_API VOID FspFileSystemReleaseDirectoryBuffer(PVOID *PDirBuffer)
{ {
/* assume that FspFileSystemAcquireDirectoryBuffer has been called */ /* assume that FspFileSystemAcquireDirectoryBuffer has been called */
FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer);
/* eliminate invalidated entries from the index */ /* eliminate invalidated entries from the index */
PULONG Index = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark); PULONG Index = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark);
@ -356,8 +354,7 @@ FSP_API VOID FspFileSystemReadDirectoryBuffer(PVOID *PDirBuffer,
PWSTR Marker, PWSTR Marker,
PVOID Buffer, ULONG Length, PULONG PBytesTransferred) PVOID Buffer, ULONG Length, PULONG PBytesTransferred)
{ {
FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer);
MemoryBarrier();
if (0 != DirBuffer) if (0 != DirBuffer)
{ {
@ -396,14 +393,13 @@ FSP_API VOID FspFileSystemReadDirectoryBuffer(PVOID *PDirBuffer,
FSP_API VOID FspFileSystemDeleteDirectoryBuffer(PVOID *PDirBuffer) FSP_API VOID FspFileSystemDeleteDirectoryBuffer(PVOID *PDirBuffer)
{ {
FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer);
MemoryBarrier();
if (0 != DirBuffer) if (0 != DirBuffer)
{ {
MemFree(DirBuffer->Buffer); MemFree(DirBuffer->Buffer);
MemFree(DirBuffer); MemFree(DirBuffer);
*PDirBuffer = 0; FspInterlockedStorePointer(PDirBuffer, 0);
} }
} }
@ -412,7 +408,7 @@ VOID FspFileSystemPeekInDirectoryBuffer(PVOID *PDirBuffer,
{ {
/* assume that FspFileSystemAcquireDirectoryBuffer has been called */ /* assume that FspFileSystemAcquireDirectoryBuffer has been called */
FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = *PDirBuffer; FSP_FILE_SYSTEM_DIRECTORY_BUFFER *DirBuffer = FspInterlockedLoadPointer(PDirBuffer);
*PBuffer = DirBuffer->Buffer; *PBuffer = DirBuffer->Buffer;
*PIndex = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark); *PIndex = (PULONG)(DirBuffer->Buffer + DirBuffer->HiMark);

View File

@ -275,8 +275,7 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
else else
{ {
ResetEvent(FspServiceConsoleModeEvent); ResetEvent(FspServiceConsoleModeEvent);
FspServiceConsoleCtrlHandlerDisabled = 0; FspInterlockedStore32((INT32 *)&FspServiceConsoleCtrlHandlerDisabled, 0);
MemoryBarrier();
} }
#endif #endif
@ -326,8 +325,7 @@ FSP_API NTSTATUS FspServiceLoop(FSP_SERVICE *Service)
* *
* What we do instead is disable our handler by setting a variable. * What we do instead is disable our handler by setting a variable.
*/ */
FspServiceConsoleCtrlHandlerDisabled = 1; FspInterlockedStore32((INT32 *)&FspServiceConsoleCtrlHandlerDisabled, 1);
MemoryBarrier();
} }
Result = STATUS_SUCCESS; Result = STATUS_SUCCESS;
@ -517,8 +515,7 @@ static DWORD WINAPI FspServiceConsoleModeThread(PVOID Context)
/* expose FspServiceConsoleCtrlHandler so it can be used from fsp_fuse_signal_handler */ /* expose FspServiceConsoleCtrlHandler so it can be used from fsp_fuse_signal_handler */
BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType) BOOL WINAPI FspServiceConsoleCtrlHandler(DWORD CtrlType)
{ {
UINT32 Disabled = FspServiceConsoleCtrlHandlerDisabled; UINT32 Disabled = FspInterlockedLoad32((INT32 *)&FspServiceConsoleCtrlHandlerDisabled);
MemoryBarrier();
if (Disabled) if (Disabled)
return FALSE; return FALSE;

View File

@ -753,8 +753,7 @@ static NTSTATUS FspFsvolNotifyChangeDirectory(
return STATUS_ACCESS_DENIED; return STATUS_ACCESS_DENIED;
/* stop now if the directory is pending deletion */ /* stop now if the directory is pending deletion */
DeletePending = 0 != FileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode);
MemoryBarrier();
if (DeletePending) if (DeletePending)
return STATUS_DELETE_PENDING; return STATUS_DELETE_PENDING;

View File

@ -1521,6 +1521,16 @@ VOID FspFileNodeDereference(FSP_FILE_NODE *FileNode)
if (0 == RefCount) if (0 == RefCount)
FspFileNodeDelete(FileNode); FspFileNodeDelete(FileNode);
} }
static inline
BOOLEAN FspFileNodeDeletePending(FSP_FILE_NODE *FileNode)
{
return 0 != FspInterlockedLoad32((INT32 *)&FileNode->DeletePending);
}
static inline
VOID FspFileNodeSetDeletePending(FSP_FILE_NODE *FileNode, BOOLEAN Delete)
{
FspInterlockedStore32((INT32 *)&FileNode->DeletePending, Delete);
}
VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags);
BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait); BOOLEAN FspFileNodeTryAcquireSharedF(FSP_FILE_NODE *FileNode, ULONG Flags, BOOLEAN Wait);
VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags); VOID FspFileNodeAcquireExclusiveF(FSP_FILE_NODE *FileNode, ULONG Flags);

View File

@ -618,8 +618,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
*/ */
if (0 != FileNode->MainFileNode) if (0 != FileNode->MainFileNode)
{ {
DeletePending = 0 != FileNode->MainFileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode->MainFileNode);
MemoryBarrier();
if (DeletePending) if (DeletePending)
{ {
Result = STATUS_DELETE_PENDING; Result = STATUS_DELETE_PENDING;
@ -669,8 +668,7 @@ NTSTATUS FspFileNodeOpen(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject,
ASSERT(OpenedFileNode != FileNode); ASSERT(OpenedFileNode != FileNode);
ASSERT(OpenedFileNode->MainFileNode == FileNode->MainFileNode); ASSERT(OpenedFileNode->MainFileNode == FileNode->MainFileNode);
DeletePending = 0 != OpenedFileNode->DeletePending; DeletePending = FspFileNodeDeletePending(OpenedFileNode);
MemoryBarrier();
if (DeletePending) if (DeletePending)
{ {
Result = STATUS_DELETE_PENDING; Result = STATUS_DELETE_PENDING;
@ -795,9 +793,8 @@ VOID FspFileNodeCleanup(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, PULONG
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
if (FileDesc->DeleteOnClose) if (FileDesc->DeleteOnClose)
FileNode->DeletePending = TRUE; FspFileNodeSetDeletePending(FileNode, TRUE);
DeletePending = 0 != FileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode);
MemoryBarrier();
SetAllocationSize = !DeletePending && FileNode->TruncateOnClose; SetAllocationSize = !DeletePending && FileNode->TruncateOnClose;
@ -841,8 +838,7 @@ VOID FspFileNodeCleanupFlush(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject)
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
DeletePending = 0 != FileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode);
MemoryBarrier();
SingleHandle = 1 == FileNode->HandleCount; SingleHandle = 1 == FileNode->HandleCount;
@ -965,8 +961,7 @@ VOID FspFileNodeCleanupComplete(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject
{ {
SingleHandle = TRUE; SingleHandle = TRUE;
DeletePending = 0 != FileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode);
MemoryBarrier();
if (DeletePending) if (DeletePending)
FileNode->Header.FileSize.QuadPart = 0; FileNode->Header.FileSize.QuadPart = 0;
@ -1179,7 +1174,7 @@ VOID FspFileNodeOverwriteStreams(FSP_FILE_NODE *FileNode)
DescendantFileNodeIndex++) DescendantFileNodeIndex++)
{ {
DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex]; DescendantFileNode = DescendantFileNodes[DescendantFileNodeIndex];
DescendantFileNode->DeletePending = TRUE; FspFileNodeSetDeletePending(DescendantFileNode, TRUE);
} }
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);

View File

@ -177,8 +177,7 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject,
return FspFsvolQueryNameInformation(FileObject, PBuffer, BufferEnd); return FspFsvolQueryNameInformation(FileObject, PBuffer, BufferEnd);
} }
DeletePending = 0 != FileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode);
MemoryBarrier();
Info->BasicInformation.CreationTime.QuadPart = FileInfo->CreationTime; Info->BasicInformation.CreationTime.QuadPart = FileInfo->CreationTime;
Info->BasicInformation.LastAccessTime.QuadPart = FileInfo->LastAccessTime; Info->BasicInformation.LastAccessTime.QuadPart = FileInfo->LastAccessTime;
@ -422,8 +421,7 @@ static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
DeletePending = 0 != FileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode);
MemoryBarrier();
Info->AllocationSize.QuadPart = FileInfo->AllocationSize; Info->AllocationSize.QuadPart = FileInfo->AllocationSize;
Info->EndOfFile.QuadPart = FileInfo->FileSize; Info->EndOfFile.QuadPart = FileInfo->FileSize;
@ -1626,7 +1624,7 @@ static NTSTATUS FspFsvolSetDispositionInformationSuccess(
UINT32 DispositionFlags = Request->Req.SetInformation.Info.DispositionEx.Flags; UINT32 DispositionFlags = Request->Req.SetInformation.Info.DispositionEx.Flags;
BOOLEAN Delete = BooleanFlagOn(DispositionFlags, FILE_DISPOSITION_DELETE); BOOLEAN Delete = BooleanFlagOn(DispositionFlags, FILE_DISPOSITION_DELETE);
FileNode->DeletePending = Delete; FspFileNodeSetDeletePending(FileNode, Delete);
FileObject->DeletePending = Delete; FileObject->DeletePending = Delete;
if (!Delete) if (!Delete)

View File

@ -503,8 +503,7 @@ static NTSTATUS FspFsvolFileSystemControlOplock(
{ {
BOOLEAN DeletePending; BOOLEAN DeletePending;
DeletePending = 0 != FileNode->DeletePending; DeletePending = FspFileNodeDeletePending(FileNode);
MemoryBarrier();
if (DeletePending) if (DeletePending)
{ {
Result = STATUS_DELETE_PENDING; Result = STATUS_DELETE_PENDING;

View File

@ -1298,8 +1298,7 @@ static NTSTATUS Overwrite(FSP_FILE_SYSTEM *FileSystem,
MemfsFileNodeMapEnumerateFn, &Context); MemfsFileNodeMapEnumerateFn, &Context);
for (Index = 0; Context.Count > Index; Index++) for (Index = 0; Context.Count > Index; Index++)
{ {
LONG RefCount = Context.FileNodes[Index]->RefCount; LONG RefCount = FspInterlockedLoad32((INT32 *)&Context.FileNodes[Index]->RefCount);
MemoryBarrier();
if (2 >= RefCount) if (2 >= RefCount)
MemfsFileNodeMapRemove(Memfs->FileNodeMap, Context.FileNodes[Index]); MemfsFileNodeMapRemove(Memfs->FileNodeMap, Context.FileNodes[Index]);
} }