MLIR-AIE
memory_allocator_ion.cpp
Go to the documentation of this file.
1//===- memory_allocator.h ---------------------------------------*- C++ -*-===//
2//
3// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7// (c) Copyright 2020 Xilinx Inc.
8// (c) Copyright 2023 Advanced Micro Devices, Inc.
9//
10//===----------------------------------------------------------------------===//
11
12// This code is heavily based on aienginev2_v3_0/src/io_backend/ext/xaie_linux.c
13// Current version of this library no longer implements memory allocation, so we
14// have to do it ourselves.
15
16/***************************** Include Files *********************************/
17#include <errno.h>
18#include <fcntl.h>
19#include <limits.h>
20#include <linux/dma-buf.h>
21#include <pthread.h>
22#include <stdint.h>
23#include <stdlib.h>
24#include <string.h>
25#include <sys/ioctl.h>
26#include <sys/mman.h>
27#include <sys/stat.h>
28#include <sys/types.h>
29#include <unistd.h>
30
31#include "ion.h"
32#include "memory_allocator.h"
33
34/***************************** Macro Definitions *****************************/
35#define XAIE_128BIT_ALIGN_MASK 0xFF
36
37// Allocate memory for the AIE device
39 int size) {
40 int RC;
41 int Fd, Ret;
42 uint32_t HeapNum;
43 void *VAddr;
44 struct ion_allocation_data AllocArgs;
45 struct ion_heap_query Query;
46 struct ion_heap_data *Heaps;
47 u64 DevAddr = 0;
48
49 Fd = open("/dev/ion", O_RDONLY);
50 if (Fd < 0) {
51 XAIE_ERROR("Failed to open ion.\n");
52 return NULL;
53 }
54
55 memset(&Query, 0, sizeof(Query));
56 Ret = ioctl(Fd, ION_IOC_HEAP_QUERY, &Query);
57 if (Ret != 0) {
58 XAIE_ERROR("Failed to enquire ion heaps.\n");
59 goto error_ion;
60 }
61
62 Heaps = (struct ion_heap_data *)calloc(Query.cnt, sizeof(*Heaps));
63 if (Heaps == NULL) {
64 XAIE_ERROR("Failed to allocate memory for heap details\n");
65 goto error_ion;
66 }
67
68 Query.heaps = (uint64_t)Heaps;
69 Ret = ioctl(Fd, ION_IOC_HEAP_QUERY, &Query);
70 if (Ret != 0) {
71 XAIE_ERROR("Failed to enquire ion heap details.\n");
72 free(Heaps);
73 goto error_ion;
74 }
75
76 HeapNum = UINT_MAX;
77 for (uint32_t i = 0; i < Query.cnt; i++) {
78 XAIE_DBG("Heap id: %u, Heap name: %s, Heap type: %u\n", Heaps[i].heap_id,
79 Heaps[i].name, Heaps[i].type);
80 if (Heaps[i].type == ION_HEAP_TYPE_SYSTEM_CONTIG) {
81 HeapNum = i;
82 break;
83 }
84 }
85
86 if (HeapNum == UINT_MAX) {
87 XAIE_ERROR("Failed to find contiguous heap\n");
88 free(Heaps);
89 goto error_ion;
90 }
91
92 memset(&AllocArgs, 0, sizeof(AllocArgs));
93 AllocArgs.len = size;
94 AllocArgs.heap_id_mask = 1 << Heaps[HeapNum].heap_id;
95 free(Heaps);
96 // if(Cache == XAIE_MEM_CACHEABLE) {
97 // AllocArgs.flags = ION_FLAG_CACHED;
98 // }
99
100 Ret = ioctl(Fd, ION_IOC_ALLOC, &AllocArgs);
101 if (Ret != 0) {
102 XAIE_ERROR("Failed to allocate memory of %lu bytes\n");
103 goto error_ion;
104 }
105
106 VAddr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, AllocArgs.fd, 0);
107 if (VAddr == NULL) {
108 XAIE_ERROR("Failed to mmap\n");
109 goto error_alloc_fd;
110 }
111
112 handle.fd = AllocArgs.fd;
113 handle.virtualAddr = VAddr;
114 handle.size = size;
115
116 // Map the memory
117 if (XAie_MemAttach(ctx->XAieDevInst, &(handle.MemInst), DevAddr, (u64)VAddr,
118 size, XAIE_MEM_NONCACHEABLE, handle.fd) != XAIE_OK) {
119 XAIE_ERROR("dmabuf map failed\n");
120 goto error_map;
121 }
122
123 close(Fd);
124 return (int *)VAddr;
125
126error_map:
127 munmap(VAddr, size);
128error_alloc_fd:
129 close(handle.fd);
130error_ion:
131 close(Fd);
132 return NULL;
133}
134
135// /*****************************************************************************/
136// /**
137// *
138// * This is function to attach the allocated memory descriptor to kernel
139// driver
140// *
141// * @param IOInst: Linux IO instance pointer
142// * @param MemInst: Linux Memory instance pointer.
143// *
144// * @return XAIE_OK on success, Error code on failure.
145// *
146// * @note Internal only.
147// *
148// *******************************************************************************/
149// static int _XAie_LinuxMemDetach(XAie_LinuxIO *IOInst, XAie_LinuxMem *MemInst)
150// {
151// int Ret;
152
153// Ret = ioctl(IOInst->PartitionFd, AIE_DETACH_DMABUF_IOCTL,
154// MemInst->BufferFd);
155// if(Ret != 0) {
156// XAIE_ERROR("Failed to detach dmabuf\n");
157// return XAIE_ERR;
158// }
159
160// return XAIE_OK;
161// }
162
163// /*****************************************************************************/
164// /**
165// *
166// * This is the memory function to free the memory
167// *
168// * @param MemInst: Memory instance pointer.
169// *
170// * @return XAIE_OK on success, Error code on failure.
171// *
172// * @note Internal only.
173// *
174// *******************************************************************************/
175// static int XAie_LinuxMemFree(XAie_MemInst *MemInst)
176// {
177// int RC;
178// XAie_LinuxMem *LinuxMemInst =
179// (XAie_LinuxMem *)MemInst->BackendHandle;
180
181// RC = _XAie_LinuxMemDetach((XAie_LinuxIO *)MemInst->DevInst->IOInst,
182// LinuxMemInst);
183// if(RC != XAIE_OK) {
184// return RC;
185// }
186
187// munmap(MemInst->VAddr, MemInst->Size);
188// close(LinuxMemInst->BufferFd);
189// free(LinuxMemInst);
190// free(MemInst);
191
192// return XAIE_OK;
193// }
194
195// Sync the memory for CPU
197 struct dma_buf_sync Sync;
198 int Ret;
199
200 memset(&Sync, 0, sizeof(Sync));
201 Sync.flags = DMA_BUF_SYNC_RW | DMA_BUF_SYNC_START;
202 Ret = ioctl(handle.fd, DMA_BUF_IOCTL_SYNC, &Sync);
203 if (Ret != 0) {
204 XAIE_ERROR("Failed to sync, %s.\n", strerror(errno));
205 // return XAIE_ERR;
206 }
207
208 // return XAIE_OK;
209}
210
211// Sync the memory for Device
213 struct dma_buf_sync Sync;
214 int Ret;
215
216 memset(&Sync, 0, sizeof(Sync));
217 Sync.flags = DMA_BUF_SYNC_RW | DMA_BUF_SYNC_END;
218 Ret = ioctl(handle.fd, DMA_BUF_IOCTL_SYNC, &Sync);
219 if (Ret != 0) {
220 XAIE_ERROR("Failed to sync, %s.\n", strerror(errno));
221 // return;
222 // return XAIE_ERR;
223 }
224
225 // return XAIE_OK;
226}
227
228u64 mlir_aie_get_device_address(struct aie_libxaie_ctx_t *_xaie, void *VA) {
229 return (u64)VA; // LibXAIE will take care of converting this for us.
230}
231
232/** @} */
#define ION_IOC_ALLOC
DOC: ION_IOC_ALLOC - allocate memory.
Definition ion.h:93
#define ION_IOC_HEAP_QUERY
DOC: ION_IOC_HEAP_QUERY - information about available heaps.
Definition ion.h:101
@ ION_HEAP_TYPE_SYSTEM_CONTIG
memory allocated via kmalloc
Definition ion.h:17
int * mlir_aie_mem_alloc(struct aie_libxaie_ctx_t *ctx, ext_mem_model_t &handle, int size)
Allocate a buffer in device memory.
void mlir_aie_sync_mem_dev(ext_mem_model_t &handle)
Synchronize the buffer from the host CPU to the device.
void mlir_aie_sync_mem_cpu(ext_mem_model_t &handle)
Synchronize the buffer from the device to the host CPU.
u64 mlir_aie_get_device_address(struct aie_libxaie_ctx_t *_xaie, void *VA)
Return a device address corresponding to the given host address.
XAie_DevInst * XAieDevInst
Definition target.h:33
XAie_MemInst MemInst
Definition target.h:28
size_t size
Definition target.h:26
void * virtualAddr
Definition target.h:24
DOC: Ion Userspace API.
Definition ion.h:52
__u32 heap_id_mask
mask of heap ids to allocate from
Definition ion.h:54
__u32 fd
file descriptor for this allocation
Definition ion.h:56
__u64 len
size of the allocation
Definition ion.h:53
struct ion_heap_data - data about a heap
Definition ion.h:65
__u32 type
heap type
Definition ion.h:67
char name[MAX_HEAP_NAME]
first 32 characters of the heap name
Definition ion.h:66
__u32 heap_id
heap id for the heap
Definition ion.h:68
struct ion_heap_query - collection of data about all heaps
Definition ion.h:77
__u64 heaps
buffer to be populated
Definition ion.h:80
__u32 cnt
Total number of heaps to be copied.
Definition ion.h:78