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