1
0
mirror of https://github.com/veracrypt/VeraCrypt.git synced 2025-11-11 11:08:02 -06:00

Windows: Don't use API for Processor Groups support if there is only 1 CPU group in the system. This can fix slowness issue observed on some PCs with AMD CPUs.

This commit is contained in:
Mounir IDRASSI
2020-07-01 17:11:07 +02:00
parent 5f04e5abd0
commit 3f587a3629
4 changed files with 86 additions and 41 deletions

View File

@@ -20,6 +20,12 @@
#define TC_ENC_THREAD_POOL_MAX_THREAD_COUNT 256 //64 #define TC_ENC_THREAD_POOL_MAX_THREAD_COUNT 256 //64
#define TC_ENC_THREAD_POOL_QUEUE_SIZE (TC_ENC_THREAD_POOL_MAX_THREAD_COUNT * 2) #define TC_ENC_THREAD_POOL_QUEUE_SIZE (TC_ENC_THREAD_POOL_MAX_THREAD_COUNT * 2)
#define TC_ENC_THREAD_POOL_LEGACY_MAX_THREAD_COUNT 64
#define TC_ENC_THREAD_POOL_LEGACY_QUEUE_SIZE (TC_ENC_THREAD_POOL_LEGACY_MAX_THREAD_COUNT * 2)
static volatile size_t ThreadPoolCount = TC_ENC_THREAD_POOL_LEGACY_MAX_THREAD_COUNT;
static volatile int ThreadQueueSize = TC_ENC_THREAD_POOL_LEGACY_QUEUE_SIZE;
#ifdef DEVICE_DRIVER #ifdef DEVICE_DRIVER
#define TC_THREAD_HANDLE PKTHREAD #define TC_THREAD_HANDLE PKTHREAD
@@ -178,19 +184,22 @@ static void SetWorkItemState (EncryptionThreadPoolWorkItem *workItem, WorkItemSt
static TC_THREAD_PROC EncryptionThreadProc (void *threadArg) static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
{ {
EncryptionThreadPoolWorkItem *workItem; EncryptionThreadPoolWorkItem *workItem;
#ifdef DEVICE_DRIVER if (threadArg)
SetThreadCpuGroupAffinity ((USHORT) *(WORD*)(threadArg));
#else
SetThreadGroupAffinityFn SetThreadGroupAffinityPtr = (SetThreadGroupAffinityFn) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "SetThreadGroupAffinity");
if (SetThreadGroupAffinityPtr && threadArg)
{ {
GROUP_AFFINITY groupAffinity = {0}; #ifdef DEVICE_DRIVER
groupAffinity.Mask = ~0ULL; SetThreadCpuGroupAffinity ((USHORT) *(WORD*)(threadArg));
groupAffinity.Group = *(WORD*)(threadArg); #else
SetThreadGroupAffinityPtr(GetCurrentThread(), &groupAffinity, NULL); SetThreadGroupAffinityFn SetThreadGroupAffinityPtr = (SetThreadGroupAffinityFn) GetProcAddress (GetModuleHandle (L"kernel32.dll"), "SetThreadGroupAffinity");
} if (SetThreadGroupAffinityPtr && threadArg)
{
GROUP_AFFINITY groupAffinity = {0};
groupAffinity.Mask = ~0ULL;
groupAffinity.Group = *(WORD*)(threadArg);
SetThreadGroupAffinityPtr(GetCurrentThread(), &groupAffinity, NULL);
}
#endif #endif
}
while (!StopPending) while (!StopPending)
@@ -199,7 +208,7 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
workItem = &WorkItemQueue[DequeuePosition++]; workItem = &WorkItemQueue[DequeuePosition++];
if (DequeuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE) if (DequeuePosition >= ThreadQueueSize)
DequeuePosition = 0; DequeuePosition = 0;
while (!StopPending && GetWorkItemState (workItem) != WorkItemReady) while (!StopPending && GetWorkItemState (workItem) != WorkItemReady)
@@ -288,13 +297,11 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg)
#endif #endif
} }
#ifndef DEVICE_DRIVER
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount) size_t GetCpuCount (WORD* pGroupCount)
{ {
size_t cpuCount = 0, i = 0; size_t cpuCount = 0;
#ifdef DEVICE_DRIVER
cpuCount = GetCpuCount();
#else
SYSTEM_INFO sysInfo; SYSTEM_INFO sysInfo;
GetActiveProcessorGroupCountFn GetActiveProcessorGroupCountPtr = (GetActiveProcessorGroupCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorGroupCount"); GetActiveProcessorGroupCountFn GetActiveProcessorGroupCountPtr = (GetActiveProcessorGroupCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorGroupCount");
GetActiveProcessorCountFn GetActiveProcessorCountPtr = (GetActiveProcessorCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorCount"); GetActiveProcessorCountFn GetActiveProcessorCountPtr = (GetActiveProcessorCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorCount");
@@ -307,25 +314,47 @@ BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
totalProcessors += (size_t) GetActiveProcessorCountPtr(j); totalProcessors += (size_t) GetActiveProcessorCountPtr(j);
} }
cpuCount = totalProcessors; cpuCount = totalProcessors;
if (pGroupCount)
*pGroupCount = groupCount;
} }
else else
{ {
GetSystemInfo(&sysInfo); GetSystemInfo(&sysInfo);
cpuCount = sysInfo.dwNumberOfProcessors; cpuCount = (size_t) sysInfo.dwNumberOfProcessors;
if (pGroupCount)
*pGroupCount = 1;
} }
return cpuCount;
}
#endif #endif
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
{
size_t cpuCount = 0, i = 0;
WORD groupCount = 1;
cpuCount = GetCpuCount(&groupCount);
if (ThreadPoolRunning) if (ThreadPoolRunning)
return TRUE; return TRUE;
if (groupCount > 1)
{
ThreadPoolCount = TC_ENC_THREAD_POOL_MAX_THREAD_COUNT;
ThreadQueueSize = TC_ENC_THREAD_POOL_QUEUE_SIZE;
}
if (cpuCount > encryptionFreeCpuCount) if (cpuCount > encryptionFreeCpuCount)
cpuCount -= encryptionFreeCpuCount; cpuCount -= encryptionFreeCpuCount;
if (cpuCount < 2) if (cpuCount < 2)
return TRUE; return TRUE;
if (cpuCount > TC_ENC_THREAD_POOL_MAX_THREAD_COUNT) if (cpuCount > ThreadPoolCount)
cpuCount = TC_ENC_THREAD_POOL_MAX_THREAD_COUNT; cpuCount = ThreadPoolCount;
StopPending = FALSE; StopPending = FALSE;
DequeuePosition = 0; DequeuePosition = 0;
@@ -377,32 +406,38 @@ BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount)
for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount) for (ThreadCount = 0; ThreadCount < cpuCount; ++ThreadCount)
{ {
#ifdef DEVICE_DRIVER WORD* pThreadArg = NULL;
ThreadProcessorGroups[ThreadCount] = GetCpuGroup ((size_t) ThreadCount); if (groupCount > 1)
#else
// Determine which processor group to bind the thread to.
if (GetActiveProcessorGroupCountPtr && GetActiveProcessorCountPtr)
{ {
WORD j, groupCount = GetActiveProcessorGroupCountPtr(); #ifdef DEVICE_DRIVER
uint32 totalProcessors = 0U; ThreadProcessorGroups[ThreadCount] = GetCpuGroup ((size_t) ThreadCount);
for (j = 0U; j < groupCount; j++) #else
GetActiveProcessorCountFn GetActiveProcessorCountPtr = (GetActiveProcessorCountFn) GetProcAddress (GetModuleHandle (L"Kernel32.dll"), "GetActiveProcessorCount");
// Determine which processor group to bind the thread to.
if (GetActiveProcessorCountPtr)
{ {
totalProcessors += (uint32) GetActiveProcessorCountPtr(j); WORD j;
if (totalProcessors >= ThreadCount) uint32 totalProcessors = 0U;
for (j = 0U; j < groupCount; j++)
{ {
ThreadProcessorGroups[ThreadCount] = j; totalProcessors += (uint32) GetActiveProcessorCountPtr(j);
break; if (totalProcessors >= ThreadCount)
{
ThreadProcessorGroups[ThreadCount] = j;
break;
}
} }
} }
} else
else ThreadProcessorGroups[ThreadCount] = 0;
ThreadProcessorGroups[ThreadCount] = 0;
#endif #endif
pThreadArg = &ThreadProcessorGroups[ThreadCount];
}
#ifdef DEVICE_DRIVER #ifdef DEVICE_DRIVER
if (!NT_SUCCESS(TCStartThread(EncryptionThreadProc, (void*)(&ThreadProcessorGroups[ThreadCount]), &ThreadHandles[ThreadCount]))) if (!NT_SUCCESS(TCStartThread(EncryptionThreadProc, (void*) pThreadArg, &ThreadHandles[ThreadCount])))
#else #else
if (!(ThreadHandles[ThreadCount] = (HANDLE)_beginthreadex(NULL, 0, EncryptionThreadProc, (void*)(&ThreadProcessorGroups[ThreadCount]), 0, NULL))) if (!(ThreadHandles[ThreadCount] = (HANDLE)_beginthreadex(NULL, 0, EncryptionThreadProc, (void*) pThreadArg, 0, NULL)))
#endif #endif
{ {
@@ -465,7 +500,7 @@ void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT
TC_ACQUIRE_MUTEX (&EnqueueMutex); TC_ACQUIRE_MUTEX (&EnqueueMutex);
workItem = &WorkItemQueue[EnqueuePosition++]; workItem = &WorkItemQueue[EnqueuePosition++];
if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE) if (EnqueuePosition >= ThreadQueueSize)
EnqueuePosition = 0; EnqueuePosition = 0;
while (GetWorkItemState (workItem) != WorkItemFree) while (GetWorkItemState (workItem) != WorkItemFree)
@@ -564,7 +599,7 @@ void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data,
while (fragmentCount-- > 0) while (fragmentCount-- > 0)
{ {
workItem = &WorkItemQueue[EnqueuePosition++]; workItem = &WorkItemQueue[EnqueuePosition++];
if (EnqueuePosition >= TC_ENC_THREAD_POOL_QUEUE_SIZE) if (EnqueuePosition >= ThreadQueueSize)
EnqueuePosition = 0; EnqueuePosition = 0;
while (GetWorkItemState (workItem) != WorkItemFree) while (GetWorkItemState (workItem) != WorkItemFree)
@@ -606,7 +641,7 @@ size_t GetEncryptionThreadCount ()
size_t GetMaxEncryptionThreadCount () size_t GetMaxEncryptionThreadCount ()
{ {
return TC_ENC_THREAD_POOL_MAX_THREAD_COUNT; return ThreadPoolCount;
} }

View File

@@ -27,6 +27,10 @@ typedef enum
DeriveKeyWork DeriveKeyWork
} EncryptionThreadPoolWorkType; } EncryptionThreadPoolWorkType;
#ifndef DEVICE_DRIVER
size_t GetCpuCount (WORD* pGroupCount);
#endif
void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey); void EncryptionThreadPoolBeginKeyDerivation (TC_EVENT *completionEvent, TC_EVENT *noOutstandingWorkItemEvent, LONG *completionFlag, LONG *outstandingWorkItemCount, int pkcs5Prf, char *password, int passwordLength, char *salt, int iterationCount, char *derivedKey);
void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo); void EncryptionThreadPoolDoWork (EncryptionThreadPoolWorkType type, byte *data, const UINT64_STRUCT *startUnitNo, uint32 unitCount, PCRYPTO_INFO cryptoInfo);
BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount); BOOL EncryptionThreadPoolStart (size_t encryptionFreeCpuCount);

View File

@@ -4491,7 +4491,7 @@ NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information)
} }
size_t GetCpuCount () size_t GetCpuCount (WORD* pGroupCount)
{ {
size_t cpuCount = 0; size_t cpuCount = 0;
if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr) if (KeQueryActiveGroupCountPtr && KeQueryActiveProcessorCountExPtr)
@@ -4501,6 +4501,9 @@ size_t GetCpuCount ()
{ {
cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i); cpuCount += (size_t) KeQueryActiveProcessorCountExPtr (i);
} }
if (pGroupCount)
*pGroupCount = groupCount;
} }
else else
{ {
@@ -4514,6 +4517,9 @@ size_t GetCpuCount ()
activeCpuMap >>= 1; activeCpuMap >>= 1;
} }
if (pGroupCount)
*pGroupCount = 1;
} }
if (cpuCount == 0) if (cpuCount == 0)

View File

@@ -173,7 +173,7 @@ NTSTATUS TCCompleteIrp (PIRP irp, NTSTATUS status, ULONG_PTR information);
NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information); NTSTATUS TCCompleteDiskIrp (PIRP irp, NTSTATUS status, ULONG_PTR information);
NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize); NTSTATUS ProbeRealDriveSize (PDEVICE_OBJECT driveDeviceObject, LARGE_INTEGER *driveSize);
BOOL UserCanAccessDriveDevice (); BOOL UserCanAccessDriveDevice ();
size_t GetCpuCount (); size_t GetCpuCount (WORD* pGroupCount);
USHORT GetCpuGroup (size_t index); USHORT GetCpuGroup (size_t index);
void SetThreadCpuGroupAffinity (USHORT index); void SetThreadCpuGroupAffinity (USHORT index);
void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes); void EnsureNullTerminatedString (wchar_t *str, size_t maxSizeInBytes);