1 /*========================== begin_copyright_notice ============================
2 Copyright(c) 2021 Intel Corporation
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files(the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and / or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included
12 in all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 OTHER DEALINGS IN THE SOFTWARE.
21 ============================= end_copyright_notice ===========================*/
22 #include "GmmMultiAdapterULT.h"
23 #ifndef _WIN32
24 #include <dlfcn.h>
25 #endif
26 #include <stdlib.h>
27
MACommonULT()28 MACommonULT::MACommonULT()
29 {
30 // Ideally this should be in the SetUp function for each test case, but since there are
31 // wrapper classes around this for the test suites and SetUp does not get called on this
32 // class, it needs to go in the constructor which gets created for each test case.
33
34 //reset all test info
35 memset(GmmTestInfo, 0, sizeof(GmmTestInfo));
36 memset(AdapterSaved, 0, sizeof(AdapterSaved));
37
38 hGmmLib = NULL;
39 pfnGmmDestroy = NULL;
40 pfnGmmInit = NULL;
41
42 //set a seed value so the test is always reproducible
43 srand(0);
44
45 // Save the random Generated bdf value in an array during intantiation itself
46 // These value remain live for each of the ULT lifetime.
47 for (int i = 0; i < MAX_NUM_ADAPTERS; i++)
48 {
49 AdapterSaved[i].Bus = rand() / 100;
50 AdapterSaved[i].Device = rand() / 100;
51 AdapterSaved[i].Function = rand() / 100;
52 AdapterSaved[i].Reserved = 0;
53 }
54
55 // Validate the generated BDfs are unique
56 // No two Adapter's BDF should be equal on a PCI bus.
57 for (int i = 0; i < MAX_NUM_ADAPTERS; i++)
58 {
59 for (int j = 0; j < MAX_NUM_ADAPTERS; j++)
60 {
61 if (i != j)
62 {
63 if (AdapterSaved[i].Bus == AdapterSaved[j].Bus)
64 {
65 if (AdapterSaved[i].Device == AdapterSaved[j].Device)
66 {
67 if (AdapterSaved[i].Function == AdapterSaved[j].Function)
68 {
69 // OOps! Generated BDFs are equal.
70 // Lets change any one field to make it unique
71 // Lets increment Bus.
72 AdapterSaved[j].Bus++;
73 }
74 }
75 }
76 }
77 }
78 }
79 }
80
~MACommonULT()81 MACommonULT::~MACommonULT()
82 {
83 }
84
CTestMA()85 CTestMA::CTestMA()
86 {
87 }
88
~CTestMA()89 CTestMA::~CTestMA()
90 {
91 }
92
SetUpTestCase()93 void CTestMA::SetUpTestCase()
94 {
95 }
96
TearDownTestCase()97 void CTestMA::TearDownTestCase()
98 {
99 }
100
SetUp()101 void CTestMA::SetUp()
102 {
103 LoadGmmDll();
104 }
105
TearDown()106 void CTestMA::TearDown()
107 {
108 UnLoadGmmDll();
109 }
110
LoadGmmDll()111 void MACommonULT::LoadGmmDll()
112 {
113 hGmmLib = dlopen(GMM_UMD_DLL, RTLD_LAZY);
114 ASSERT_TRUE(hGmmLib);
115
116 *(void **)(&pfnGmmInit) = dlsym(hGmmLib, "InitializeGmm");
117 *(void **)(&pfnGmmDestroy) = dlsym(hGmmLib, "GmmAdapterDestroy");
118
119 ASSERT_TRUE(pfnGmmInit);
120 ASSERT_TRUE(pfnGmmDestroy);
121 }
122
UnLoadGmmDll()123 void MACommonULT::UnLoadGmmDll()
124 {
125 if (hGmmLib)
126 {
127 dlclose(hGmmLib);
128
129 hGmmLib = NULL;
130 pfnGmmInit = NULL;
131 pfnGmmDestroy = NULL;
132 }
133 }
134
135 // Lets test with the recent GPUs till 32nd adapters and take IGFX_COFFEELAKE for 32+ adapters
136 // Only for our ULT to supply dummy ProductFamily
GetProductFamily(uint32_t AdapterIdx)137 PRODUCT_FAMILY MACommonULT::GetProductFamily(uint32_t AdapterIdx)
138 {
139 switch (AdapterIdx)
140 {
141 case 0:
142 return IGFX_DG1;
143 case 1:
144 return IGFX_ICELAKE;
145 case 2:
146 return IGFX_TIGERLAKE_LP;
147 case 3:
148 case 4:
149 case 5:
150 case 6:
151 case 7:
152 case 8:
153 case 9:
154 return IGFX_DG2;
155 case 11:
156 case 12:
157 case 13:
158 case 14:
159 case 15:
160 case 16:
161 return IGFX_XE_HP_SDV;
162 case 17:
163 case 18:
164 case 19:
165 case 20:
166 case 21:
167 case 22:
168 case 23:
169 case 24:
170 case 25:
171 case 26:
172 case 27:
173 case 28:
174 case 29:
175 return IGFX_PVC;
176 case 30:
177 case 31:
178 default:
179 break;
180 }
181 return IGFX_COFFEELAKE;
182 }
183
184 // Lets test with the recent GPUs till 32nd adpater and take IGFX_GEN9_CORE for 32+ adapters
185 // Only for our ULT to supply dummy GFXCORE_FAMILY
GetRenderCoreFamily(uint32_t AdapterIdx)186 GFXCORE_FAMILY MACommonULT::GetRenderCoreFamily(uint32_t AdapterIdx)
187 {
188 switch (AdapterIdx)
189 {
190 case 0:
191 return IGFX_XE_HP_CORE;
192 case 1:
193 return IGFX_GEN11LP_CORE;
194 case 2:
195 return IGFX_GEN12LP_CORE;
196 case 3:
197 case 4:
198 case 5:
199 case 6:
200 case 7:
201 case 8:
202 case 9:
203 return IGFX_XE_HPG_CORE;
204 case 11:
205 case 12:
206 case 13:
207 case 14:
208 case 15:
209 case 16:
210 return IGFX_XE_HP_CORE;
211 case 17:
212 case 18:
213 case 19:
214 case 20:
215 case 21:
216 case 22:
217 case 23:
218 case 24:
219 case 25:
220 case 26:
221 case 27:
222 case 28:
223 case 29:
224 return IGFX_XE_HPC_CORE;
225 case 30:
226 case 31:
227 default:
228 break;
229 }
230 return IGFX_GEN9_CORE;
231 }
232
233 // To simulate the UMDs/ClinentContexts per adapter i.e MAX_COUNT_PER_ADAPTER
234 // Increase MAX_COUNT_PER_ADAPTER value if there are more UMDs involved
GetClientType(uint32_t CountIdx)235 GMM_CLIENT MACommonULT::GetClientType(uint32_t CountIdx)
236 {
237 switch (CountIdx)
238 {
239 case 0:
240 return GMM_D3D9_VISTA;
241 case 1:
242 return GMM_D3D10_VISTA;
243 case 2:
244 return GMM_D3D12_VISTA;
245 case 3:
246 return GMM_EXCITE_VISTA;
247 case 4:
248 return GMM_OCL_VISTA;
249 default:
250 break;
251 }
252 return GMM_D3D9_VISTA;
253 }
254
255 // Returns the AdapterSaved array value, Adapter BDFs based on input AdapterIdx
GetAdapterBDF(uint32_t AdapterIdx)256 ADAPTER_BDF MACommonULT::GetAdapterBDF(uint32_t AdapterIdx)
257 {
258 ADAPTER_BDF AdapterBDF = {0, 2, 0, 0};
259
260 if (AdapterIdx < MAX_NUM_ADAPTERS)
261 {
262 AdapterBDF.Bus = AdapterSaved[AdapterIdx].Bus;
263 AdapterBDF.Device = AdapterSaved[AdapterIdx].Device;
264 AdapterBDF.Function = AdapterSaved[AdapterIdx].Function;
265 }
266 return AdapterBDF;
267 }
268
GmmInitModule(uint32_t AdapterIdx,uint32_t CountIdx)269 void MACommonULT::GmmInitModule(uint32_t AdapterIdx, uint32_t CountIdx)
270 {
271 ASSERT_TRUE(AdapterIdx < MAX_NUM_ADAPTERS);
272 GMM_STATUS Status = GMM_SUCCESS;
273 ADAPTER_BDF AdapterBDF = GetAdapterBDF(AdapterIdx);
274 GmmTestInfo[AdapterIdx][CountIdx].GfxPlatform.eProductFamily = GetProductFamily(AdapterIdx);
275 GmmTestInfo[AdapterIdx][CountIdx].GfxPlatform.eRenderCoreFamily = GetRenderCoreFamily(AdapterIdx);
276
277 if (!GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo)
278 {
279 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo = (ADAPTER_INFO *)malloc(sizeof(ADAPTER_INFO));
280 if (!GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo)
281 {
282 ASSERT_TRUE(false);
283 return;
284 }
285 memset(GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo, 0, sizeof(ADAPTER_INFO));
286
287 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrTileY = 1; // Legacy TileY
288
289 if (GmmTestInfo[AdapterIdx][CountIdx].GfxPlatform.eRenderCoreFamily >= IGFX_GEN12_CORE)
290 {
291
292 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrWddm2GpuMmu = 1;
293 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrUserModeTranslationTable = 1;
294 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrE2ECompression = 1;
295 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrLinearCCS = 1;
296 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrTileY = 1;
297 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrLLCBypass = 0;
298 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrWddm2Svm = 0; // keep this disabled for pagetablemgr testing
299 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrSVM = 1; // keep this enabled for pagetablemgr testing
300 //GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.WaUntypedBufferCompression = 1;
301 }
302
303 if (IGFX_DG1 == GmmTestInfo[AdapterIdx][CountIdx].GfxPlatform.eProductFamily)
304 {
305 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrLinearCCS = 1;
306 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrStandardMipTailFormat = 1;
307 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrTileY = 0;
308 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrLocalMemory = 1;
309 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable.FtrWddm2_1_64kbPages = 1;
310 }
311 }
312
313
314 GmmTestInfo[AdapterIdx][CountIdx].InArgs.ClientType = GetClientType(CountIdx);
315 GmmTestInfo[AdapterIdx][CountIdx].InArgs.pGtSysInfo = &GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SystemInfo;
316 GmmTestInfo[AdapterIdx][CountIdx].InArgs.pSkuTable = &GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->SkuTable;
317 GmmTestInfo[AdapterIdx][CountIdx].InArgs.pWaTable = &GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo->WaTable;
318 GmmTestInfo[AdapterIdx][CountIdx].InArgs.Platform = GmmTestInfo[AdapterIdx][CountIdx].GfxPlatform;
319 #if LHDM
320 GmmTestInfo[AdapterIdx][CountIdx].InArgs.stAdapterBDF = AdapterBDF;
321 GmmTestInfo[AdapterIdx][CountIdx].InArgs.DeviceRegistryPath = NULL;
322 #else
323 GmmTestInfo[AdapterIdx][CountIdx].InArgs.FileDescriptor = AdapterBDF.Data;
324 #endif
325
326 Status = pfnGmmInit(&GmmTestInfo[AdapterIdx][CountIdx].InArgs, &GmmTestInfo[AdapterIdx][CountIdx].OutArgs);
327 EXPECT_EQ(Status, GMM_SUCCESS);
328
329 GmmTestInfo[AdapterIdx][CountIdx].pGmmULTClientContext = GmmTestInfo[AdapterIdx][CountIdx].OutArgs.pGmmClientContext;
330 ASSERT_TRUE(GmmTestInfo[AdapterIdx][CountIdx].pGmmULTClientContext);
331
332 GmmTestInfo[AdapterIdx][CountIdx].pLibContext = GmmTestInfo[AdapterIdx][CountIdx].pGmmULTClientContext->GetLibContext();
333 ASSERT_TRUE(GmmTestInfo[AdapterIdx][CountIdx].pLibContext);
334 }
335
GmmDestroyModule(uint32_t AdapterIdx,uint32_t CountIdx)336 void MACommonULT::GmmDestroyModule(uint32_t AdapterIdx, uint32_t CountIdx)
337 {
338 GmmTestInfo[AdapterIdx][CountIdx].OutArgs.pGmmClientContext = GmmTestInfo[AdapterIdx][CountIdx].pGmmULTClientContext;
339 pfnGmmDestroy(&GmmTestInfo[AdapterIdx][CountIdx].OutArgs);
340 GmmTestInfo[AdapterIdx][CountIdx].pGmmULTClientContext = NULL;
341 GmmTestInfo[AdapterIdx][CountIdx].pLibContext = NULL;
342 if (GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo)
343 {
344 free(GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo);
345 GmmTestInfo[AdapterIdx][CountIdx].pGfxAdapterInfo = NULL;
346 }
347 }
348
349 // This member function creates MaxClientThreads number of threads
350 // MaxClientsThreads to represent total numbers of UMD Clients
351 // MaxClientsThreads = MAX_NUM_ADAPTERS for ULT TestMTLoadMultipleAdapters
352 // MaxClientsThreads = MAX_COUNT_PER_ADAPTER for ULT TestMTLoadAdaptersMultipleTimes
353 // MaxClientsThreads = MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER, for ULT TestMTLoadMultipleAdaptersMultipleTimes
CreateMAThread(uint32_t MaxClientThreads,ThreadInParams * InParams)354 static void CreateMAThread(uint32_t MaxClientThreads, ThreadInParams *InParams)
355 {
356 // Spawn all threads upto MaxClientThreads and wait for them all at once
357 uint32_t i = 0;
358 int Status; /* return value */
359 pthread_t thread_id[MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER]; /* thread's ID (just an integer) */
360
361 /* MaxClientsThreads to represent MAX_NUM_ADAPTERS *MAX_COUNT_PER_ADAPTER Clients */
362 for (i = 0; i < (MaxClientThreads); i++)
363 {
364 Status = pthread_create(&thread_id[i], NULL, MAULTThreadEntryFunc, (void *)&InParams[i]);
365 ASSERT_TRUE((!Status));
366 }
367
368 /* wait for threads to terminate */
369 for (i = 0; i < (MaxClientThreads); i++)
370 {
371 Status = pthread_join(thread_id[i], NULL);
372 ASSERT_TRUE((!Status));
373 }
374 }
375
MAULTThreadEntryFunc(void * lpParam)376 void *MAULTThreadEntryFunc(void *lpParam)
377 {
378 ThreadInParams *pInParams = (ThreadInParams *)(lpParam);
379
380 pInParams->MATestObj->GmmInitModule(pInParams->AdapterIdx, pInParams->CountIdx);
381 pInParams->MATestObj->GmmDestroyModule(pInParams->AdapterIdx, pInParams->CountIdx);
382
383 pthread_exit(NULL);
384 }
385
386
387 #if GMM_LIB_DLL_MA
388 /*
389 To simulate the real time scenario between the Gmmlib and the UMD clients
390 Folowing ULTs assume:
391 MAX_NUM_ADAPTERS = Number of GPU Adapters (BDFs) available on a system at a given point of time.
392 MAX_COUNT_PER_ADAPTER = Number of UMD clients that can be simulated per Adapter
393 So Total clients simulated = MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER
394 Where,
395 The LibContext for an Adapter is equal across all Clients for that adapter
396 The ClientConetxt is unique(Not equal) across all Clients for that adapter
397 */
398
399 // Load multiple Adapters in the same process with the Limit up to MAX_NUM_ADAPTERS
400 // Increase MAX_NUM_ADAPTERS > 32 if needed
TEST_F(CTestMA,TestLoadMultipleAdapters)401 TEST_F(CTestMA, TestLoadMultipleAdapters)
402 {
403 uint32_t AdapterCount = 0;
404 uint32_t i = 0;
405
406 // Initilize the dll for all available adapters
407 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
408 {
409 GmmInitModule(AdapterCount, 0);
410 }
411
412 // Check the Libcontext for each of the adapter is different or not
413 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
414 {
415 for (i = 0; i < MAX_NUM_ADAPTERS; i++)
416 {
417 if (AdapterCount != i)
418 {
419 EXPECT_NE(GmmTestInfo[AdapterCount][0].pLibContext, GmmTestInfo[i][0].pLibContext);
420 }
421 }
422 }
423
424 // Un-Initilize the dll for all loaded adapters
425 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
426 {
427 GmmDestroyModule(AdapterCount, 0);
428 }
429 }
430
431 /// Load all adapters(MAX_NUM_ADAPTERS) multiple times up to MAX_COUNT_PER_ADAPTER in same process
TEST_F(CTestMA,TestLoadAdapterMultipleTimes)432 TEST_F(CTestMA, TestLoadAdapterMultipleTimes)
433 {
434 uint32_t AdapterCount = 0, RefCount = 0;
435
436 // Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
437 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
438 {
439 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
440 {
441 GmmInitModule(AdapterCount, RefCount);
442 }
443 }
444 // For each adapter upto MAX_NUM_ADAPTERS Check the LibContext for all instances upto
445 // MAX_COUNT_PER_ADAPTER to be equal
446 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
447 {
448 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER - 1; RefCount++)
449 {
450 EXPECT_EQ(GmmTestInfo[AdapterCount][RefCount].pLibContext, GmmTestInfo[AdapterCount][RefCount + 1].pLibContext);
451 }
452 }
453
454 // Un-Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
455 // The destroy/unload can be out of order
456 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
457 {
458 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
459 {
460 GmmDestroyModule(AdapterCount, RefCount);
461 }
462 }
463 }
464
465 /// Test Init-Destroy multiple times Upto MAX_COUNT_PER_ADAPTER before Unloading DLL, on Same Adapter upto MAX_NUM_ADAPTERS
TEST_F(CTestMA,TestInitDestroyMultipleTimesOnSameAdapter)466 TEST_F(CTestMA, TestInitDestroyMultipleTimesOnSameAdapter)
467 {
468 uint32_t AdapterCount = 0, RefCount = 0;
469
470 // Initilize and destroy module upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
471 // For each adapter(AdapterCount < MAX_NUM_ADAPTERS) Check the LibContext for all instances to be equal
472 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
473 {
474 // Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each adapter
475 // In reality the init and destroy can occurs any number of time on a particular adapter, so for simplcity treating that UMD
476 // will load already loaded lib again for MAX_COUNT_PER_ADAPTER times.
477 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
478 {
479 GmmInitModule(AdapterCount, RefCount);
480 }
481
482 // Check the LibContext for all instances on a same adapter to be equal
483 // It might also seems that LibContext pointer value on next adapters is same as previous pointer value returned in previous adapter init.
484 // This is the OS Memory Manager's role to avoid fragmentation in the process VA space
485 // Also our ULT is a Light-Weight process due to which the freed memory not assigned to other processes may get assigned again.
486 // But mind that this is possible only when the previous libcontext intialized is compulsorily inactive and destroyed.
487 // otherwise the same secnario as in TestLoadMultipleAdapters occurs .i.e different pointer value is returned on new adpater bdf.
488 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER - 1; RefCount++)
489 {
490 EXPECT_EQ(GmmTestInfo[AdapterCount][RefCount].pLibContext, GmmTestInfo[AdapterCount][RefCount + 1].pLibContext);
491 }
492
493 // Un-Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each adapter
494 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
495 {
496 GmmDestroyModule(AdapterCount, RefCount);
497 }
498 }
499 }
500
501 /// Test Init-Destroy multiple times before Unloading DLL, on Multiple Adapters
TEST_F(CTestMA,TestInitDestroyMultipleTimesOnMultiAdapter)502 TEST_F(CTestMA, TestInitDestroyMultipleTimesOnMultiAdapter)
503 {
504 uint32_t AdapterCount = 0, RefCount = 0;
505
506 // Initilize and destroy the dll upto MAX_COUNT_PER_ADAPTER times for each of MAX_NUM_ADAPTERS adapters
507 // For each adapter(AdapterCount < MAX_NUM_ADAPTERS) Check the LibContext for all instances to is unique
508 // This is similar to TestInitDestroyMultipleTimesOnSameAdapter ULT apart from the order of adapter initialization.
509 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
510 {
511 // Initilize the dll upto MAX_COUNT_PER_ADAPTER times for each adapter
512 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
513 {
514 GmmInitModule(AdapterCount, RefCount);
515 }
516 // Check the LibContext for each of the adpater(upto MAX_NUM_ADAPTERS) to be unique
517 // whereas LibContext for all instances on a same adapter is to be equal
518 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS - 1; AdapterCount++)
519 {
520 EXPECT_NE(GmmTestInfo[AdapterCount][RefCount].pLibContext, GmmTestInfo[AdapterCount + 1][RefCount].pLibContext);
521 }
522
523 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
524 {
525 GmmDestroyModule(AdapterCount, RefCount);
526 }
527 }
528 }
529
530 /*
531 Following ULT's Exhibit the multitasking behaviour of UMDs considering that all UMDs loads and unloads dll
532 in parallel and in random order.
533 */
534
535 // Load Multiple Adapters upto MAX_NUM_ADAPTERS on multiple threads in same process at the same time
536 // Here the number of client per adapter is 1 .i.e 0th count Index
TEST_F(CTestMA,TestMTLoadMultipleAdapters)537 TEST_F(CTestMA, TestMTLoadMultipleAdapters)
538 {
539 uint32_t AdapterCount = 0;
540 ThreadInParams InParams[MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER];
541
542 memset(InParams, 0, sizeof(InParams));
543
544 //Populate the Inparams array with the MAX_NUM_ADAPTERS indices
545 for (AdapterCount = 0; AdapterCount < MAX_NUM_ADAPTERS; AdapterCount++)
546 {
547 InParams[AdapterCount].AdapterIdx = AdapterCount;
548 InParams[AdapterCount].CountIdx = 0;
549 InParams[AdapterCount].MATestObj = this;
550 }
551
552 // Create threads to load all Adapters upto MAX_NUM_ADAPTERS for a single client each
553 CreateMAThread(MAX_NUM_ADAPTERS, InParams);
554 }
555
556 // Load a Single Adapter multiple times upto MAX_COUNT_PER_ADAPTER on multiple threads in same process
TEST_F(CTestMA,TestMTLoadAdaptersMultipleTimes)557 TEST_F(CTestMA, TestMTLoadAdaptersMultipleTimes)
558 {
559 uint32_t RefCount = 0;
560 ThreadInParams InParams[MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER];
561
562 memset(InParams, 0, sizeof(InParams));
563
564 //Populate the Inparams array with MAX_COUNT_PER_ADAPTER indices
565 for (RefCount = 0; RefCount < MAX_COUNT_PER_ADAPTER; RefCount++)
566 {
567 InParams[RefCount].AdapterIdx = 0;
568 InParams[RefCount].CountIdx = RefCount;
569 InParams[RefCount].MATestObj = this;
570 }
571 // Create threads to load all clients i.e MAX_COUNT_PER_ADAPTER on single adpater
572 CreateMAThread(MAX_COUNT_PER_ADAPTER, InParams);
573 }
574
575 // Load Multiple Adapters upto MAX_NUM_ADAPTERS, multiple times upto MAX_COUNT_PER_ADAPTER on multiple threads in same process
TEST_F(CTestMA,TestMTLoadMultipleAdaptersMultipleTimes)576 TEST_F(CTestMA, TestMTLoadMultipleAdaptersMultipleTimes)
577 {
578 uint32_t i = 0, j = 0, k = 0;
579 uint32_t AdapterCount = 0, RefCount = 0;
580 ThreadInParams InParams[MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER];
581
582 memset(InParams, 0, sizeof(InParams));
583
584 //Populate the Inparams array with the MAX_NUM_ADAPTERS*MAX_COUNT_PER_ADAPTER indices
585 //Such that Each Adapter corresponds to its max mumber of clients in a sequential order
586 for (i = 0; i < (MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER); i++)
587 {
588 for (j = 0; j < MAX_NUM_ADAPTERS; j++)
589 {
590 for (k = 0; k < MAX_COUNT_PER_ADAPTER; k++)
591 {
592 InParams[i].AdapterIdx = AdapterCount;
593 InParams[i].CountIdx = RefCount++;
594 InParams[i].MATestObj = this;
595 i++;
596 }
597 RefCount = 0;
598 AdapterCount++;
599 }
600 }
601
602 // Create threads to load MAX_NUM_ADAPTERS, MAX_COUNT_PER_ADAPTER times
603 // Thread Count = MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER
604 CreateMAThread(MAX_NUM_ADAPTERS * MAX_COUNT_PER_ADAPTER, InParams);
605 }
606
607 #endif // GMM_LIB_DLL_MA
608
609