1 /* SPDX-License-Identifier: BSD-3-Clause */ 2 /* Copyright(c) 2007-2022 Intel Corporation */ 3 #include "qat_utils.h" 4 5 #include <sys/param.h> 6 #include <sys/types.h> 7 #include <sys/systm.h> 8 #include <sys/kernel.h> 9 #include <sys/malloc.h> 10 #include <sys/proc.h> 11 #include <sys/sched.h> 12 #include <sys/time.h> 13 #include <machine/stdarg.h> 14 #include <vm/vm.h> 15 #include <vm/pmap.h> 16 17 /** 18 * 19 * @brief Private data structure 20 * 21 * Data struct to store the information on the 22 * memory allocated. This structure is stored at the beginning of 23 * the allocated chunck of memory 24 * size is the no of byte passed to the memory allocation functions 25 * mSize is the real size of the memory required to the OS 26 * 27 * +----------------------------+--------------------------------+ 28 * | QatUtilsMemAllocInfoStruct | memory returned to user (size) | 29 * +----------------------------+--------------------------------+ 30 * ^ ^ 31 * mAllocMemPtr Ptr returned to the caller of MemAlloc* 32 * 33 */ 34 35 typedef struct _QatUtilsMemAllocInfoStruct { 36 void *mAllocMemPtr; /* memory addr returned by the kernel */ 37 uint32_t mSize; /* allocated size */ 38 } QatUtilsMemAllocInfoStruct; 39 40 /************************************** 41 * Memory functions 42 *************************************/ 43 void * 44 qatUtilsMemAllocContiguousNUMA(uint32_t size, uint32_t node, uint32_t alignment) 45 { 46 void *ptr = NULL; 47 void *pRet = NULL; 48 uint32_t alignment_offset = 0; 49 50 QatUtilsMemAllocInfoStruct memInfo = { 0 }; 51 if (size == 0 || alignment < 1) { 52 QAT_UTILS_LOG( 53 "QatUtilsMemAllocNUMA: size or alignment are zero.\n"); 54 return NULL; 55 } 56 if (alignment & (alignment - 1)) { 57 QAT_UTILS_LOG( 58 "QatUtilsMemAllocNUMA: Expecting alignment of a power.\n"); 59 return NULL; 60 } 61 62 memInfo.mSize = size + alignment + sizeof(QatUtilsMemAllocInfoStruct); 63 ptr = contigmalloc(memInfo.mSize, M_QAT, M_WAITOK, 0, ~1UL, 64, 0); 64 65 memInfo.mAllocMemPtr = ptr; 66 pRet = 67 (char *)memInfo.mAllocMemPtr + sizeof(QatUtilsMemAllocInfoStruct); 68 #ifdef __x86_64__ 69 alignment_offset = (uint64_t)pRet % alignment; 70 #else 71 alignment_offset = (uint32_t)pRet % alignment; 72 #endif 73 pRet = (char *)pRet + (alignment - alignment_offset); 74 memcpy(((char *)pRet) - sizeof(QatUtilsMemAllocInfoStruct), 75 &memInfo, 76 sizeof(QatUtilsMemAllocInfoStruct)); 77 78 return pRet; 79 } 80 81 void 82 qatUtilsMemFreeNUMA(void *ptr) 83 { 84 QatUtilsMemAllocInfoStruct *memInfo = NULL; 85 86 memInfo = 87 (QatUtilsMemAllocInfoStruct *)((int8_t *)ptr - 88 sizeof(QatUtilsMemAllocInfoStruct)); 89 if (memInfo->mSize == 0 || memInfo->mAllocMemPtr == NULL) { 90 QAT_UTILS_LOG( 91 "QatUtilsMemAlignedFree: Detected corrupted data: memory leak!\n"); 92 return; 93 } 94 free(memInfo->mAllocMemPtr, M_QAT); 95 } 96 97 CpaStatus 98 qatUtilsSleep(uint32_t milliseconds) 99 { 100 if (milliseconds != 0) { 101 pause("qatUtils sleep", milliseconds * hz / (1000)); 102 } else { 103 sched_relinquish(curthread); 104 } 105 return CPA_STATUS_SUCCESS; 106 } 107 108 void 109 qatUtilsYield(void) 110 { 111 sched_relinquish(curthread); 112 } 113