PSHV_GLOBAL_DATA ShvVpAllocateGlobalData ( VOID ) { PHYSICAL_ADDRESS lowest, highest; PSHV_GLOBAL_DATA data; ULONG cpuCount, size; // // The entire address range is OK for this allocation // lowest.QuadPart = 0; highest.QuadPart = lowest.QuadPart - 1; // // Query the number of logical processors, including those potentially in // groups other than 0. This allows us to support >64 processors. // cpuCount = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); // // Each processor will receive its own slice of per-virtual processor data. // size = FIELD_OFFSET(SHV_GLOBAL_DATA, VpData) + cpuCount * sizeof(SHV_VP_DATA); // // Allocate a contiguous chunk of RAM to back this allocation and make sure // that it is RW only, instead of RWX, by using the new Windows 8 API. // #if TARGETVERSION > 7 data = (PSHV_GLOBAL_DATA)MmAllocateContiguousNodeMemory(size, lowest, highest, lowest, PAGE_READWRITE, MM_ANY_NODE_OK); #else data = (PSHV_GLOBAL_DATA)MmAllocateContiguousMemory(size, highest); #endif // TARGETVERSION > 7 if (data != NULL) { // // Zero out the entire data region // __stosq((PULONGLONG)data, 0, size / sizeof(ULONGLONG)); } // // Return what is hopefully a valid pointer, otherwise NULL. // return data; }
KAFFINITY restrictCurrentThreadToSecondaryCores() throw () { // // Set thread affinity mask to restrict scheduling of the current thread // on any processor but CPU0. // KAFFINITY callerAffinity; NT_ASSERTMSG("IRQL unexpected", KeGetCurrentIrql() < DISPATCH_LEVEL); ULONG numCpus = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); ULONG noCpu0AffinityMask = (~(ULONG(~0x0) << numCpus) & ULONG(~0x1)); callerAffinity = KeSetSystemAffinityThreadEx(KAFFINITY(noCpu0AffinityMask)); NT_ASSERTMSG("Thread affinity not set as requested", KeGetCurrentProcessorNumberEx(NULL) != 0); return callerAffinity; }
VOID * OvsAllocateMemoryPerCpu(size_t size, ULONG tag) { VOID *ptr = NULL; ULONG count = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); ASSERT(KeQueryActiveGroupCount() == 1); ptr = OvsAllocateMemoryWithTag(count * size, tag); if (ptr) { RtlZeroMemory(ptr, count * size); } return ptr; }
static BOOLEAN AllocateCPUMappingArray(NDIS_HANDLE NdisHandle, PPARANDIS_SCALING_SETTINGS RSSScalingSettings) { ULONG i; ULONG CPUNumber = KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); PCHAR NewCPUMappingArray = (PCHAR) NdisAllocateMemoryWithTagPriority( NdisHandle, sizeof(CCHAR) * CPUNumber, PARANDIS_MEMORY_TAG, NormalPoolPriority); if(!NewCPUMappingArray) return FALSE; RSSScalingSettings->CPUIndexMapping = NewCPUMappingArray; RSSScalingSettings->CPUIndexMappingSize = CPUNumber; for(i = 0; i < CPUNumber; i++) { RSSScalingSettings->CPUIndexMapping[i] = PARANDIS_RECEIVE_QUEUE_UNCLASSIFIED; } return TRUE; }
// CreateMemoryPool: Create memory pool bool CreateMemoryPool() { bool ret = false; uint32 cnt = 0; if (NULL == g_pSessionPool) { g_pPoolBufferCnt = POOL_BASE_SIZE + KeQueryActiveProcessorCountEx(ALL_PROCESSOR_GROUPS); g_pSessionPool = (MemoryPool*)ExAllocatePoolWithTag(NonPagedPool, g_pPoolBufferCnt * sizeof(MemoryPool), 'PLM'); if (NULL != g_pSessionPool) { for (cnt = 0; cnt < g_pPoolBufferCnt; cnt++) { MemoryPool* pPool = g_pSessionPool + cnt; if (NULL != pPool) { uint8* pMem = (uint8*)ExAllocatePoolWithTag(NonPagedPool, DATA_PAGE_BUFFER_SIZE, 'PLB'); if (NULL != pMem) { pPool->m_pBase = pMem; pPool->m_offset = 0; pPool->m_size = DATA_PAGE_BUFFER_SIZE; ret = true; } } } } } return ret; }