xref: /OK3568_Linux_fs/external/rockit/mpi/example/mod/test_mpi_mb.cpp (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /* Copyright 2020 Rockchip Electronics Co. LTD
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *      http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #undef DBG_MOD_ID
17 #define DBG_MOD_ID       RK_ID_MB
18 
19 #include <stdio.h>
20 #include <unistd.h>
21 #include <cstring>
22 #include <vector>
23 
24 #include "rk_debug.h"
25 #include "rk_mpi_mb.h"
26 #include "rk_mpi_sys.h"
27 
28 #include "test_comm_argparse.h"
29 
30 #define MB_POOL_COUNT           10
31 #define MB_POOL_MB_COUNT        10
32 #define MB_POOL_MB_SIZE         1280 * 720 * 2
33 
34 typedef struct _rkTestMbCtx {
35     RK_S32      s32MbCount;
36     RK_S32      s32MbSize;
37     RK_S32      s32PoolCount;
38     RK_S32      s32LoopCount;
39     RK_BOOL     bExternal;
40     RK_BOOL     bPreAlloc;
41     RK_S32      s32RemapMode;
42     RK_S32      s32AllocType;
43 } TEST_MB_CTX_S;
44 
unit_test_mpi_mb(const TEST_MB_CTX_S * pstCtx)45 RK_S32 unit_test_mpi_mb(const TEST_MB_CTX_S *pstCtx) {
46     MB_POOL_CONFIG_S pstMbPoolCfg;
47     std::vector<MB_BLK> vector;
48     std::vector<MB_BLK>::iterator iter;
49     RK_S32 s32Ret = RK_SUCCESS;
50     RK_S32 loopCount = pstCtx->s32LoopCount;
51     RK_S32 s32UniqueId = -1;
52     RK_S32 s32DupFd = -1;
53 
54     memset(&pstMbPoolCfg, 0, sizeof(MB_POOL_CONFIG_S));
55     pstMbPoolCfg.u64MBSize   = pstCtx->s32MbSize;
56     pstMbPoolCfg.u32MBCnt    = pstCtx->s32MbCount;
57     pstMbPoolCfg.bPreAlloc   = pstCtx->bPreAlloc;
58     pstMbPoolCfg.enRemapMode = (MB_REMAP_MODE_E)pstCtx->s32RemapMode;
59     pstMbPoolCfg.enAllocType = (MB_ALLOC_TYPE_E)pstCtx->s32AllocType;
60 
61     do {
62         for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
63             MB_POOL pool = RK_MPI_MB_CreatePool(&pstMbPoolCfg);
64             if (pool == MB_INVALID_POOLID) {
65                 s32Ret = RK_ERR_MB_2MPOOLS;
66                 goto __FAILED;
67             }
68             RK_LOGI("pool id %d", pool);
69         }
70 
71         for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
72             vector.clear();
73             for (RK_S32 j = 0; j < pstCtx->s32MbCount; j++) {
74                 MB_BLK mb = RK_MPI_MB_GetMB(i, pstMbPoolCfg.u64MBSize, RK_FALSE);
75                 if (mb == MB_INVALID_HANDLE) {
76                     s32Ret = RK_ERR_MB_NOBUF;
77                     goto __FAILED;
78                 }
79                 RK_U64 phyAddr = RK_MPI_MB_Handle2PhysAddr(mb);
80                 if (pstMbPoolCfg.enDmaType == MB_DMA_TYPE_CMA
81                       && pstMbPoolCfg.enAllocType == MB_ALLOC_TYPE_DMA
82                       && phyAddr == 0) {
83                     s32Ret = RK_ERR_MB_BUSY;
84                     RK_MPI_MB_ReleaseMB(mb);
85                     goto __FAILED;
86                 }
87                 MB_POOL poolId = RK_MPI_MB_Handle2PoolId(mb);
88                 if (poolId != i) {
89                     s32Ret = RK_ERR_MB_BUSY;
90                     RK_MPI_MB_ReleaseMB(mb);
91                     goto __FAILED;
92                 }
93                 RK_S32 refsCount = RK_MPI_MB_InquireUserCnt(mb);
94                 if (refsCount != 1) {
95                     s32Ret = RK_ERR_MB_BUSY;
96                     RK_MPI_MB_ReleaseMB(mb);
97                     goto __FAILED;
98                 }
99                 RK_VOID *virAddr = RK_MPI_MB_Handle2VirAddr(mb);
100                 if (virAddr == RK_NULL) {
101                     s32Ret = RK_ERR_MB_BUSY;
102                     RK_MPI_MB_ReleaseMB(mb);
103                     goto __FAILED;
104                 }
105                 RK_S32 fd = RK_MPI_MB_Handle2Fd(mb);
106                 if (pstMbPoolCfg.enAllocType == MB_ALLOC_TYPE_DMA
107                       && fd < 0) {
108                     s32Ret = RK_ERR_MB_BUSY;
109                     RK_MPI_MB_ReleaseMB(mb);
110                     goto __FAILED;
111                 }
112                 if (pstMbPoolCfg.enAllocType == MB_ALLOC_TYPE_DMA) {
113                     if (RK_MPI_MB_VirAddr2Handle(virAddr) != mb) {
114                         s32Ret = RK_ERR_MB_BUSY;
115                         RK_MPI_MB_ReleaseMB(mb);
116                         goto __FAILED;
117                     }
118                     s32UniqueId = RK_MPI_MB_Handle2UniqueId(mb);
119                     if (s32UniqueId < 0) {
120                         s32Ret = RK_ERR_MB_BUSY;
121                         RK_MPI_MB_ReleaseMB(mb);
122                         goto __FAILED;
123                     }
124                     s32DupFd = RK_MPI_MB_UniqueId2Fd(s32UniqueId);
125                 }
126 
127                 RK_LOGI("get poolId(%d) from mb(%p) refsCount(%d) phyAddr(%p) virAddr(%p) "
128                          "fd(%d) uniqueId(%d) dupFd(%d)",
129                          poolId, mb, refsCount, phyAddr, virAddr, fd, s32UniqueId, s32DupFd);
130                 if (s32DupFd >= 0) {
131                     close(s32DupFd);
132                     s32DupFd = -1;
133                 }
134                 vector.emplace_back(mb);
135             }
136             iter = vector.begin();
137             for (; iter != vector.end(); ++iter) {
138                 s32Ret = RK_MPI_MB_ReleaseMB(*iter);
139                 if (s32Ret != RK_SUCCESS) {
140                     goto __FAILED;
141                 }
142             }
143         }
144 
145         for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
146             s32Ret = RK_MPI_MB_DestroyPool(i);
147             if (s32Ret != RK_SUCCESS) {
148                 goto __FAILED;
149             }
150         }
151         loopCount--;
152         RK_LOGI("looping times %d", pstCtx->s32LoopCount - loopCount);
153     } while (loopCount > 0);
154 
155     return RK_SUCCESS;
156 __FAILED:
157     iter = vector.begin();
158     for (; iter != vector.end(); ++iter) {
159         RK_MPI_MB_ReleaseMB(*iter);
160     }
161     for (RK_S32 i = 0; i < pstCtx->s32PoolCount; i++) {
162         RK_MPI_MB_DestroyPool(i);
163     }
164     return s32Ret;
165 }
166 
167 static const char *const usages[] = {
168     "./rk_mpi_mb_test [-c MB_COUNT] [-s MB_SIZE]...",
169     NULL,
170 };
171 
main(RK_S32 argc,const char ** argv)172 RK_S32 main(RK_S32 argc, const char **argv) {
173     RK_S32 s32Ret = RK_SUCCESS;
174     TEST_MB_CTX_S stMbCtx;
175 
176     memset(&stMbCtx, 0, sizeof(TEST_MB_CTX_S));
177     stMbCtx.s32MbCount   = 1;
178     stMbCtx.s32MbSize    = 4 * 1024 * 1024;
179     stMbCtx.s32LoopCount = 1;
180     stMbCtx.s32PoolCount = 1;
181     stMbCtx.bPreAlloc    = RK_FALSE;
182     stMbCtx.s32RemapMode = MB_REMAP_MODE_CACHED;
183     stMbCtx.s32AllocType = MB_ALLOC_TYPE_DMA;
184 
185     struct argparse_option options[] = {
186         OPT_HELP(),
187         OPT_GROUP("basic options:"),
188         OPT_INTEGER('n', "loop", &(stMbCtx.s32LoopCount), "the count of looping. default(1).", NULL, 0, 0),
189         OPT_INTEGER('c', "mb_count", &(stMbCtx.s32MbCount), "the count of mb. default(1).", NULL, 0, 0),
190         OPT_INTEGER('s', "mb_size", &(stMbCtx.s32MbSize), "mb size. default(4MB).", NULL, 0, 0),
191         OPT_INTEGER('p', "pool_count", &(stMbCtx.s32PoolCount), "the count of pool. default(1).", NULL, 0, 0),
192         OPT_INTEGER('a', "pre_alloc", &(stMbCtx.bPreAlloc), "pre alloc or not. default(0). 0: no 1: yes.", NULL, 0, 0),
193         OPT_INTEGER('r', "remap_mode", &(stMbCtx.s32RemapMode),
194                     "remapping mode. default(2). 0: none, 256: no cache, 512: cached", NULL, 0, 0),
195         OPT_INTEGER('t', "alloc_type", &(stMbCtx.s32AllocType),
196                     "alloc type. default(0). 0: DMA, 1: malloc", NULL, 0, 0),
197         OPT_END(),
198     };
199 
200     struct argparse argparse;
201     argparse_init(&argparse, options, usages, 0);
202     argparse_describe(&argparse, "\nselect a test case to run.",
203                                  "\nuse --help for details.");
204 
205     argc = argparse_parse(&argparse, argc, argv);
206 
207     s32Ret = unit_test_mpi_mb(&stMbCtx);
208     if (s32Ret != RK_SUCCESS) {
209         goto __FAILED;
210     }
211 
212     RK_LOGI("test running ok.");
213     return RK_SUCCESS;
214 __FAILED:
215     RK_LOGE("test running failed!");
216     return RK_ERR_MB_BUSY;
217 }
218