1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 1993-2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 * SPDX-License-Identifier: MIT 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9 * and/or sell copies of the Software, and to permit persons to whom the 10 * Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice shall be included in 13 * all copies or substantial portions of the Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24 /****************************************************************************** 25 * 26 * Description: 27 * This is a device resource implementation. 28 * 29 ******************************************************************************/ 30 31 32 33 #include "resserv/resserv.h" 34 #include "resserv/rs_server.h" 35 #include "resserv/rs_client.h" 36 #include "resserv/rs_resource.h" 37 #include "gpu_mgr/gpu_mgr.h" 38 #include "gpu/device/device.h" 39 #include "gpu/subdevice/subdevice.h" 40 #include "platform/sli/sli.h" 41 42 #include "class/cl0080.h" 43 #include "core/locks.h" 44 #include "vgpu/rpc.h" 45 #include "mem_mgr/mem.h" 46 47 #include "rmapi/rs_utils.h" 48 #include "nvsecurityinfo.h" 49 50 #include "gpu/gr/kernel_sm_debugger_session.h" 51 #include "kernel/gpu/rc/kernel_rc.h" 52 #include "Nvcm.h" 53 #include "diagnostics/gpu_acct.h" 54 #include "gpu/perf/kern_cuda_limit.h" 55 #include "kernel/gpu/mig_mgr/kernel_mig_manager.h" 56 57 static NV_STATUS _deviceTeardown(Device *pDevice, CALL_CONTEXT *pCallContext); 58 static NV_STATUS _deviceTeardownRef(Device *pDevice, CALL_CONTEXT *pCallContext); 59 static NV_STATUS _deviceInit(Device *pDevice, CALL_CONTEXT *pCallContext, 60 NvHandle hClient, NvHandle hDevice, NvU32 deviceInst, 61 NvHandle hClientShare, NvHandle hTargetClient, NvHandle hTargetDevice, 62 NvU64 vaSize, NvU64 vaStartInternal, NvU64 vaLimitInternal, 63 NvU32 allocFlags, NvU32 vaMode, NvBool *pbIsFirstDevice); 64 65 NV_STATUS 66 deviceConstruct_IMPL 67 ( 68 Device *pDevice, 69 CALL_CONTEXT *pCallContext, 70 RS_RES_ALLOC_PARAMS_INTERNAL *pParams 71 ) 72 { 73 NV0080_ALLOC_PARAMETERS *pNv0080AllocParams = pParams->pAllocParams; 74 NvU32 deviceInst, flags, vaMode; 75 NvU32 deviceClass = pParams->externalClassId; 76 NvHandle hClientShare; 77 NvHandle hTargetClient = NV01_NULL_OBJECT; 78 NvHandle hTargetDevice = NV01_NULL_OBJECT; 79 NvU64 vaSize = 0; 80 NV_STATUS rmStatus = NV_OK; 81 OBJSYS *pSys = SYS_GET_INSTANCE(); 82 OBJOS *pOS = SYS_GET_OS(pSys); 83 OBJGPU *pGpu; 84 NvU64 vaStartInternal = 0; 85 NvU64 vaLimitInternal = 0; 86 NvU32 physicalAllocFlags; 87 NvBool bIsFirstDevice; 88 89 if (pNv0080AllocParams == NULL) 90 { 91 deviceInst = pParams->externalClassId - NV01_DEVICE_0; 92 hClientShare = NV01_NULL_OBJECT; 93 flags = 0; 94 vaSize = 0; 95 vaMode = 0; 96 } 97 else 98 { 99 deviceInst = pNv0080AllocParams->deviceId; 100 hClientShare = pNv0080AllocParams->hClientShare; 101 hTargetClient = pNv0080AllocParams->hTargetClient; 102 hTargetDevice = pNv0080AllocParams->hTargetDevice; 103 flags = pNv0080AllocParams->flags; 104 vaSize = pNv0080AllocParams->vaSpaceSize; 105 vaMode = pNv0080AllocParams->vaMode; 106 107 // valid only if NV_DEVICE_ALLOCATION_FLAGS_RESTRICT_RESERVED_VALIMITS is flagged. 108 if (flags & NV_DEVICE_ALLOCATION_FLAGS_RESTRICT_RESERVED_VALIMITS) 109 { 110 vaStartInternal = pNv0080AllocParams->vaStartInternal; 111 vaLimitInternal = pNv0080AllocParams->vaLimitInternal; 112 113 if ((vaLimitInternal < vaStartInternal) || (vaLimitInternal == 0)) 114 { 115 return NV_ERR_INVALID_ARGUMENT; 116 } 117 } 118 } 119 120 // validate device instance 121 if (gpumgrIsDeviceInstanceValid(deviceInst) != NV_OK) 122 { 123 return NV_ERR_INVALID_CLASS; 124 } 125 126 // Make sure this device has not been disabled 127 if (gpumgrIsDeviceEnabled(deviceInst) == NV_FALSE) 128 { 129 return NV_ERR_INVALID_ARGUMENT; 130 } 131 132 // add new device to client and set the device context 133 rmStatus = _deviceInit(pDevice, pCallContext, pParams->hClient, pParams->hResource, deviceInst, 134 hClientShare, hTargetClient, hTargetDevice, vaSize, vaStartInternal, vaLimitInternal, 135 flags, vaMode, &bIsFirstDevice); 136 if (rmStatus != NV_OK) 137 return rmStatus; 138 139 pGpu = GPU_RES_GET_GPU(pDevice); 140 141 if (pCallContext->secInfo.privLevel < RS_PRIV_LEVEL_KERNEL) 142 { 143 if (!osIsGpuAccessible(pGpu)) 144 { 145 // Delete the device from the client since we should not be allocating it 146 _deviceTeardownRef(pDevice, pCallContext); 147 _deviceTeardown(pDevice, pCallContext); 148 return NV_ERR_INSUFFICIENT_PERMISSIONS; 149 } 150 } 151 152 // 153 // Make sure this device is not in fullchip reset on OSes where it is 154 // restricted. 155 // 156 if (pOS->getProperty(pOS, PDB_PROP_OS_LIMIT_GPU_RESET) && 157 pGpu->getProperty(pGpu, PDB_PROP_GPU_IN_FULLCHIP_RESET)) 158 { 159 // Delete the device from the client since we should not be allocating it 160 _deviceTeardownRef(pDevice, pCallContext); 161 _deviceTeardown(pDevice, pCallContext); 162 return NV_ERR_GPU_IN_FULLCHIP_RESET; 163 } 164 165 { 166 // 167 // If using thwap to generate an allocation failure here, fail the alloc 168 // right away 169 // 170 KernelRc *pKernelRc = GPU_GET_KERNEL_RC(pGpu); 171 if (pKernelRc != NULL && 172 !krcTestAllowAlloc(pGpu, pKernelRc, 173 NV_ROBUST_CHANNEL_ALLOCFAIL_DEVICE)) 174 { 175 _deviceTeardownRef(pDevice, pCallContext); 176 _deviceTeardown(pDevice, pCallContext); 177 return NV_ERR_GENERIC; 178 } 179 } 180 181 if (IS_VIRTUAL(pGpu) || IS_GSP_CLIENT(pGpu)) 182 { 183 physicalAllocFlags = flags & ~(NV_DEVICE_ALLOCATION_FLAGS_PLUGIN_CONTEXT 184 | NV_DEVICE_ALLOCATION_FLAGS_HOST_VGPU_DEVICE); 185 186 NV_RM_RPC_ALLOC_SHARE_DEVICE(pGpu, pParams->hParent, pParams->hResource, pDevice->hClientShare, 187 hTargetClient, hTargetDevice, deviceClass, 188 physicalAllocFlags, vaSize, vaMode, bIsFirstDevice, rmStatus); 189 if (rmStatus != NV_OK) 190 { 191 return rmStatus; 192 } 193 } 194 195 return rmStatus; 196 } // end of deviceConstruct_IMPL 197 198 void 199 deviceDestruct_IMPL 200 ( 201 Device *pDevice 202 ) 203 { 204 CALL_CONTEXT *pCallContext; 205 RS_RES_FREE_PARAMS_INTERNAL *pParams; 206 NV_STATUS rmStatus = NV_OK; 207 NV_STATUS tmpStatus; 208 NvHandle hClient; 209 210 resGetFreeParams(staticCast(pDevice, RsResource), &pCallContext, &pParams); 211 212 hClient = pCallContext->pClient->hClient; 213 214 NV_PRINTF(LEVEL_INFO, " type: device\n"); 215 216 LOCK_METER_DATA(FREE_DEVICE, 0, 0, 0); 217 218 // free the device 219 if (_deviceTeardownRef(pDevice, pCallContext) != NV_OK || 220 _deviceTeardown(pDevice, pCallContext) != NV_OK) 221 { 222 tmpStatus = NV_ERR_INVALID_OBJECT_HANDLE; 223 if (tmpStatus != NV_OK && rmStatus == NV_OK) 224 rmStatus = tmpStatus; 225 } 226 227 // 228 // If the client was created, but never had any devices successfully 229 // attached, we'll get here. The client's device structure will have 230 // been created, but pGpu will be NULL if the device was later found 231 // to be non-existent 232 // 233 if (GPU_RES_GET_GPU(pDevice)) 234 { 235 OBJGPU *pGpu = GPU_RES_GET_GPU(pDevice); 236 // vGpu support 237 if (IS_VIRTUAL(pGpu) || IS_GSP_CLIENT(pGpu)) 238 { 239 RsResourceRef *pResourceRef = pCallContext->pResourceRef; 240 NvHandle hDevice = pResourceRef->hResource; 241 NvBool bClientInUse = NV_FALSE; 242 RsClient *pRsClient = pCallContext->pClient; 243 NvBool bNonOffloadVgpu = (IS_VIRTUAL(pGpu) && !IS_VGPU_GSP_PLUGIN_OFFLOAD_ENABLED(pGpu)); 244 RS_ITERATOR it; 245 246 if (rmStatus == NV_OK) 247 { 248 NV_RM_RPC_FREE(pGpu, hClient, hClient, hDevice, rmStatus); 249 } 250 251 if (rmStatus != NV_OK) 252 { 253 pParams->status = rmStatus; 254 return; 255 } 256 257 // check if there are any more devices in use. 258 it = clientRefIter(pRsClient, NULL, classId(Device), RS_ITERATE_CHILDREN, NV_TRUE); 259 260 while (clientRefIterNext(it.pClient, &it)) 261 { 262 Device *pDeviceTest = dynamicCast(it.pResourceRef->pResource, Device); 263 NvBool bSameGpu = (GPU_RES_GET_GPU(pDeviceTest) == pGpu); 264 265 if ((pDeviceTest != pDevice) && (bNonOffloadVgpu || bSameGpu)) 266 { 267 bClientInUse = NV_TRUE; 268 break; 269 } 270 } 271 272 // check if there are any more KernelSMDebuggerSession in use. 273 it = clientRefIter(pRsClient, NULL, classId(KernelSMDebuggerSession), RS_ITERATE_CHILDREN, NV_TRUE); 274 275 while (clientRefIterNext(it.pClient, &it)) 276 { 277 KernelSMDebuggerSession *pKernelSMDebuggerSession = dynamicCast(it.pResourceRef->pResource, KernelSMDebuggerSession); 278 279 if (pKernelSMDebuggerSession != NULL && 280 (!IS_VGPU_GSP_PLUGIN_OFFLOAD_ENABLED(pGpu) || GPU_RES_GET_GPU(pKernelSMDebuggerSession) == pGpu)) 281 { 282 bClientInUse = NV_TRUE; 283 break; 284 } 285 } 286 287 // If neither any devices nor KernelSMDebuggerSession are in use, free up the client on host. 288 if (!bClientInUse) 289 { 290 NV_RM_RPC_FREE(pGpu, hClient, NV01_NULL_OBJECT, hClient, rmStatus); 291 } 292 } 293 } 294 } // end of deviceDestruct_IMPL 295 296 NV_STATUS 297 deviceControl_IMPL 298 ( 299 Device *pDevice, 300 CALL_CONTEXT *pCallContext, 301 RS_RES_CONTROL_PARAMS_INTERNAL *pParams 302 ) 303 { 304 305 // 306 // Some assertions to make RMCTRL to NVOC migration smooth 307 // Those will be removed at the end of ctrl0080.def migration 308 // 309 NV_ASSERT_OR_RETURN(pParams->hClient == RES_GET_CLIENT_HANDLE(pDevice), NV_ERR_INVALID_STATE); 310 NV_ASSERT_OR_RETURN(pParams->hObject == RES_GET_HANDLE(pDevice), NV_ERR_INVALID_STATE); 311 NV_ASSERT_OR_RETURN(pParams->hParent == RES_GET_PARENT_HANDLE(pDevice), NV_ERR_INVALID_STATE); 312 313 pParams->pGpuGrp = GPU_RES_GET_GPUGRP(pDevice); 314 return gpuresControl_IMPL(staticCast(pDevice, GpuResource), 315 pCallContext, pParams); 316 } 317 318 NV_STATUS 319 deviceInternalControlForward_IMPL 320 ( 321 Device *pDevice, 322 NvU32 command, 323 void *pParams, 324 NvU32 size 325 ) 326 { 327 return gpuresInternalControlForward_IMPL(staticCast(pDevice, GpuResource), command, pParams, size); 328 } 329 330 // 331 // add a device with specified handle, instance num, within a specified client 332 // (hClientShare also specified) 333 // 334 static NV_STATUS 335 _deviceInit 336 ( 337 Device *pDevice, 338 CALL_CONTEXT *pCallContext, 339 NvHandle hClient, 340 NvHandle hDevice, 341 NvU32 deviceInst, 342 NvHandle hClientShare, 343 NvHandle hTargetClient, 344 NvHandle hTargetDevice, 345 NvU64 vaSize, 346 NvU64 vaStartInternal, 347 NvU64 vaLimitInternal, 348 NvU32 allocFlags, 349 NvU32 vaMode, 350 NvBool *pbIsFirstDevice 351 ) 352 { 353 OBJGPU *pGpu; 354 NV_STATUS status; 355 GpuResource *pGpuResource = staticCast(pDevice, GpuResource); 356 Device *pExistingDevice; 357 NvU32 gpuInst; 358 359 if (deviceInst >= NV_MAX_DEVICES) 360 return NV_ERR_INVALID_ARGUMENT; 361 362 // Look up GPU and GPU Group 363 gpuInst = gpumgrGetPrimaryForDevice(deviceInst); 364 365 if ((pGpu = gpumgrGetGpu(gpuInst)) == NULL) 366 { 367 return NV_ERR_INVALID_STATE; 368 } 369 370 // Check if device inst already allocated, fail if this call succeeds. 371 status = deviceGetByInstance(pCallContext->pClient, deviceInst, &pExistingDevice); 372 if (status == NV_OK) 373 { 374 // 375 // RS-TODO: Status code should be NV_ERR_STATE_IN_USE, however keeping 376 // existing code from CliAllocElement (for now) 377 // 378 // Allow many Device objects on the same deviceInst in MIG mode. 379 // 380 if (!IS_MIG_ENABLED(pGpu) || IS_VIRTUAL(pGpu)) 381 return NV_ERR_INSUFFICIENT_RESOURCES; 382 } 383 384 *pbIsFirstDevice = (status != NV_OK); 385 386 pDevice->hTargetClient = hTargetClient; 387 pDevice->hTargetDevice = hTargetDevice; 388 pDevice->pKernelHostVgpuDevice = NULL; 389 390 pDevice->deviceInst = deviceInst; 391 392 // Update VA Mode 393 pDevice->vaMode = vaMode; 394 395 gpuresSetGpu(pGpuResource, pGpu, NV_TRUE); 396 397 // 398 // In case of a SR-IOV enabled guest we create a default client inside 399 // the guest whose handle can be used for VAS sharing. Setting hClientShare 400 // to 0 on baremetal causes any VA alloc made under this device to use the 401 // global vaspace. We do not support use of the global vaspace inside guest. 402 // The legacy paravirtualization config also makes use of a default client. 403 // But, in the legacy case, the client is created by the plugin and not guest 404 // RM . On SR-IOV, vaspace management has been pushed inside the guest. So, 405 // having a vaspace only on the plugin side won't help since RmMapMemoryDma 406 // calls will no longer be RPCed to host RM. 407 // 408 if (IS_VIRTUAL_WITH_SRIOV(pGpu) && 409 gpuIsSplitVasManagementServerClientRmEnabled(pGpu)) 410 { 411 if (hClientShare == NV01_NULL_OBJECT) 412 { 413 hClientShare = pGpu->hDefaultClientShare; 414 } 415 } 416 417 status = deviceSetClientShare(pDevice, hClientShare, vaSize, 418 vaStartInternal, vaLimitInternal, allocFlags); 419 if (NV_OK != status) 420 goto done; 421 422 { 423 OBJSYS *pSys = SYS_GET_INSTANCE(); 424 GpuAccounting *pGpuAcct = SYS_GET_GPUACCT(pSys); 425 RsClient *pRsClient = pCallContext->pClient; 426 RmClient *pClient = dynamicCast(pCallContext->pClient, RmClient); 427 428 if (pGpu->getProperty(pGpu, PDB_PROP_GPU_ACCOUNTING_ON)) 429 { 430 // Try to start accounting for this procId/SubProcessId. 431 // If gpuacctStartGpuAccounting() fails, just assert and print error. 432 // gpuacctStartGpuAccounting() is not a major failure, we will continue with deviceInit() as normal. 433 if ((pRsClient->type == CLIENT_TYPE_USER) && (gpuacctStartGpuAccounting(pGpuAcct, 434 pGpu->gpuInstance, pClient->ProcID, pClient->SubProcessID) != NV_OK)) 435 { 436 NV_ASSERT(0); 437 NV_PRINTF(LEVEL_ERROR, 438 "gpuacctStartGpuAccounting() failed for procId : %d and SubProcessID : " 439 "%d. Ignoring the failure and continuing.\n", 440 pClient->ProcID, pClient->SubProcessID); 441 } 442 } 443 } 444 445 if (allocFlags & NV_DEVICE_ALLOCATION_FLAGS_PLUGIN_CONTEXT) 446 { 447 NV_ASSERT_OR_RETURN(allocFlags & NV_DEVICE_ALLOCATION_FLAGS_HOST_VGPU_DEVICE, 448 NV_ERR_INVALID_ARGUMENT); 449 } 450 451 done: 452 if (status != NV_OK) 453 { 454 deviceRemoveFromClientShare(pDevice); 455 } 456 457 return status; 458 } 459 460 // 461 // delete a device with a specified handle within a client 462 // 463 static NV_STATUS 464 _deviceTeardown 465 ( 466 Device *pDevice, 467 CALL_CONTEXT *pCallContext 468 ) 469 { 470 OBJGPU *pGpu = GPU_RES_GET_GPU(pDevice); 471 PORT_UNREFERENCED_VARIABLE(pGpu); 472 473 deviceRemoveFromClientShare(pDevice); 474 475 // DM-TODO: Force the client to move to Unicast... 476 NV_STATUS status = deviceKPerfCudaLimitCliDisable(pDevice, pGpu); 477 478 // Adding status check here, but not returning it as we do not want to 479 // introduce any change in functionality. 480 if (status != NV_OK) 481 { 482 NV_PRINTF(LEVEL_ERROR,"Disable of Cuda limit activation failed"); 483 DBG_BREAKPOINT(); 484 } 485 486 { 487 OBJSYS *pSys = SYS_GET_INSTANCE(); 488 GpuAccounting *pGpuAcct = SYS_GET_GPUACCT(pSys); 489 RsClient *pRsClient = pCallContext->pClient; 490 RmClient *pClient = dynamicCast(pCallContext->pClient, RmClient); 491 492 if ((pRsClient->type == CLIENT_TYPE_USER) && 493 pGpu->getProperty(pGpu, PDB_PROP_GPU_ACCOUNTING_ON)) 494 { 495 gpuacctStopGpuAccounting(pGpuAcct, 496 pGpu->gpuInstance, pClient->ProcID, pClient->SubProcessID); 497 } 498 } 499 500 return NV_OK; 501 } 502 503 static NV_STATUS _deviceTeardownRef 504 ( 505 Device *pDevice, 506 CALL_CONTEXT *pCallContext 507 ) 508 { 509 510 return NV_OK; 511 } 512 513 NV_STATUS 514 deviceGetByHandle_IMPL 515 ( 516 RsClient *pClient, 517 NvHandle hDevice, 518 Device **ppDevice 519 ) 520 { 521 RsResourceRef *pResourceRef; 522 NV_STATUS status; 523 524 *ppDevice = NULL; 525 526 status = clientGetResourceRef(pClient, hDevice, &pResourceRef); 527 if (status != NV_OK) 528 return status; 529 530 *ppDevice = dynamicCast(pResourceRef->pResource, Device); 531 532 return (*ppDevice) ? NV_OK : NV_ERR_INVALID_OBJECT_HANDLE; 533 } 534 535 NV_STATUS 536 deviceGetByInstance_IMPL 537 ( 538 RsClient *pClient, 539 NvU32 deviceInstance, 540 Device **ppDevice 541 ) 542 { 543 RS_ITERATOR it; 544 Device *pDevice; 545 546 *ppDevice = NULL; 547 548 it = clientRefIter(pClient, NULL, classId(Device), RS_ITERATE_CHILDREN, NV_TRUE); 549 550 while (clientRefIterNext(it.pClient, &it)) 551 { 552 pDevice = dynamicCast(it.pResourceRef->pResource, Device); 553 554 if ((pDevice != NULL) && (deviceInstance == pDevice->deviceInst)) 555 { 556 *ppDevice = pDevice; 557 return NV_OK; 558 } 559 } 560 561 return NV_ERR_OBJECT_NOT_FOUND; 562 } 563 564 NV_STATUS 565 deviceGetByGpu_IMPL 566 ( 567 RsClient *pClient, 568 OBJGPU *pGpu, 569 NvBool bAnyInGroup, 570 Device **ppDevice 571 ) 572 { 573 NvU32 deviceInstance = gpuGetDeviceInstance(pGpu); 574 NV_STATUS status; 575 576 status = deviceGetByInstance(pClient, deviceInstance, ppDevice); 577 if (status != NV_OK) 578 return status; 579 580 // If pGpu is not the primary GPU return failure 581 if (!bAnyInGroup && pGpu != GPU_RES_GET_GPU(*ppDevice)) 582 { 583 *ppDevice = NULL; 584 return NV_ERR_OBJECT_NOT_FOUND; 585 } 586 587 return NV_OK; 588 } 589 590 // **************************************************************************** 591 // Deprecated Functions 592 // **************************************************************************** 593 594 /** 595 * WARNING: This function is deprecated and use is *strongly* discouraged 596 * (especially for new code!) 597 * 598 * From the function name (CliSetGpuContext) it appears as a simple accessor but 599 * violates expectations by modifying the SLI BC threadstate (calls to 600 * GPU_RES_SET_THREAD_BC_STATE). This can be dangerous if not carefully managed 601 * by the caller. 602 * 603 * Instead of using this routine, please use deviceGetByHandle then call 604 * GPU_RES_GET_GPU, GPU_RES_GET_GPUGRP, GPU_RES_SET_THREAD_BC_STATE as needed. 605 * 606 * Note that GPU_RES_GET_GPU supports returning a pGpu for both pDevice, 607 * pSubdevice, the base pResource type, and any resource that inherits from 608 * GpuResource. That is, instead of using CliSetGpuContext or 609 * CliSetSubDeviceContext, please use following pattern to look up the pGpu: 610 * 611 * OBJGPU *pGpu = GPU_RES_GET_GPU(pResource or pResourceRef->pResource) 612 * 613 * To set the threadstate, please use: 614 * 615 * GPU_RES_SET_THREAD_BC_STATE(pResource or pResourceRef->pResource); 616 */ 617 NV_STATUS 618 CliSetGpuContext 619 ( 620 NvHandle hClient, 621 NvHandle hDevice, 622 OBJGPU **ppGpu, 623 OBJGPUGRP **ppGpuGrp 624 ) 625 { 626 Device *pDevice; 627 RsClient *pClient; 628 NV_STATUS status; 629 630 if (ppGpuGrp != NULL) 631 *ppGpuGrp = NULL; 632 633 if (ppGpu != NULL) 634 *ppGpu = NULL; 635 636 status = serverGetClientUnderLock(&g_resServ, hClient, &pClient); 637 if (status != NV_OK) 638 return status; 639 640 status = deviceGetByHandle(pClient, hDevice, &pDevice); 641 if (status != NV_OK) 642 return status; 643 644 if (ppGpu != NULL) 645 *ppGpu = GPU_RES_GET_GPU(pDevice); 646 647 if (ppGpuGrp != NULL) 648 *ppGpuGrp = GPU_RES_GET_GPUGRP(pDevice); 649 650 GPU_RES_SET_THREAD_BC_STATE(pDevice); 651 652 return NV_OK; 653 } 654 655 /** 656 * WARNING: This function is deprecated! Please use gpuGetByRef() 657 */ 658 POBJGPU 659 CliGetGpuFromContext 660 ( 661 RsResourceRef *pContextRef, 662 NvBool *pbBroadcast 663 ) 664 { 665 NV_STATUS status; 666 OBJGPU *pGpu; 667 668 status = gpuGetByRef(pContextRef, pbBroadcast, &pGpu); 669 670 return (status == NV_OK) ? pGpu : NULL; 671 } 672 673 /** 674 * WARNING: This function is deprecated! Please use gpuGetByHandle() 675 */ 676 POBJGPU 677 CliGetGpuFromHandle 678 ( 679 NvHandle hClient, 680 NvHandle hResource, 681 NvBool *pbBroadcast 682 ) 683 { 684 RsClient *pClient; 685 NV_STATUS status; 686 OBJGPU *pGpu; 687 688 status = serverGetClientUnderLock(&g_resServ, hClient, &pClient); 689 if (status != NV_OK) 690 return NULL; 691 692 status = gpuGetByHandle(pClient, hResource, pbBroadcast, &pGpu); 693 694 return (status == NV_OK) ? pGpu : NULL; 695 } 696