xref: /aosp_15_r20/external/gmmlib/Source/GmmLib/ULT/GmmMultiAdapterULT.cpp (revision 35ffd701415c9e32e53136d61a677a8d0a8fc4a5)
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