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 	contigfree(memInfo->mAllocMemPtr, memInfo->mSize, 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