1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 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 <sys/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 chunk 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 *
qatUtilsMemAllocContiguousNUMA(uint32_t size,uint32_t node,uint32_t alignment)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
qatUtilsMemFreeNUMA(void * ptr)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
qatUtilsSleep(uint32_t milliseconds)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
qatUtilsYield(void)109 qatUtilsYield(void)
110 {
111 sched_relinquish(curthread);
112 }
113