Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amdgpu: create fence slab once when amdgpu module init.

This avoids problems with multiple GPUs. For example,
if the first GPU failed before amdgpu_fence_init() was
called, amdgpu_fence_slab_ref is still 0 and it will
get decremented in amdgpu_fence_driver_fini(). This
will lead to a crash during init of the second GPU since
amdgpu_fence_slab_ref is not 0.

v2: add functions for init/exit instead of
moving the variables into the driver.

Signed-off-by: Rex Zhu <Rex.Zhu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Rex Zhu and committed by
Alex Deucher
d573de2d 8b41e7a0

+20 -12
+2
drivers/gpu/drm/amd/amdgpu/amdgpu.h
··· 602 602 void amdgpu_sync_free(struct amdgpu_sync *sync); 603 603 int amdgpu_sync_init(void); 604 604 void amdgpu_sync_fini(void); 605 + int amdgpu_fence_slab_init(void); 606 + void amdgpu_fence_slab_fini(void); 605 607 606 608 /* 607 609 * GART structures, functions & helpers
+4 -1
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
··· 565 565 .driver.pm = &amdgpu_pm_ops, 566 566 }; 567 567 568 + 569 + 568 570 static int __init amdgpu_init(void) 569 571 { 570 572 amdgpu_sync_init(); 573 + amdgpu_fence_slab_init(); 571 574 if (vgacon_text_force()) { 572 575 DRM_ERROR("VGACON disables amdgpu kernel modesetting.\n"); 573 576 return -EINVAL; ··· 581 578 driver->driver_features |= DRIVER_MODESET; 582 579 driver->num_ioctls = amdgpu_max_kms_ioctl; 583 580 amdgpu_register_atpx_handler(); 584 - 585 581 /* let modprobe override vga console setting */ 586 582 return drm_pci_init(driver, pdriver); 587 583 } ··· 591 589 drm_pci_exit(driver, pdriver); 592 590 amdgpu_unregister_atpx_handler(); 593 591 amdgpu_sync_fini(); 592 + amdgpu_fence_slab_fini(); 594 593 } 595 594 596 595 module_init(amdgpu_init);
+14 -11
drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c
··· 55 55 }; 56 56 57 57 static struct kmem_cache *amdgpu_fence_slab; 58 - static atomic_t amdgpu_fence_slab_ref = ATOMIC_INIT(0); 59 58 59 + int amdgpu_fence_slab_init(void) 60 + { 61 + amdgpu_fence_slab = kmem_cache_create( 62 + "amdgpu_fence", sizeof(struct amdgpu_fence), 0, 63 + SLAB_HWCACHE_ALIGN, NULL); 64 + if (!amdgpu_fence_slab) 65 + return -ENOMEM; 66 + return 0; 67 + } 68 + 69 + void amdgpu_fence_slab_fini(void) 70 + { 71 + kmem_cache_destroy(amdgpu_fence_slab); 72 + } 60 73 /* 61 74 * Cast helper 62 75 */ ··· 409 396 */ 410 397 int amdgpu_fence_driver_init(struct amdgpu_device *adev) 411 398 { 412 - if (atomic_inc_return(&amdgpu_fence_slab_ref) == 1) { 413 - amdgpu_fence_slab = kmem_cache_create( 414 - "amdgpu_fence", sizeof(struct amdgpu_fence), 0, 415 - SLAB_HWCACHE_ALIGN, NULL); 416 - if (!amdgpu_fence_slab) 417 - return -ENOMEM; 418 - } 419 399 if (amdgpu_debugfs_fence_init(adev)) 420 400 dev_err(adev->dev, "fence debugfs file creation failed\n"); 421 401 ··· 447 441 kfree(ring->fence_drv.fences); 448 442 ring->fence_drv.initialized = false; 449 443 } 450 - 451 - if (atomic_dec_and_test(&amdgpu_fence_slab_ref)) 452 - kmem_cache_destroy(amdgpu_fence_slab); 453 444 } 454 445 455 446 /**