From e55a5c9b5f5b80275a38293ac0fd38336dd2efdf Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 16 Oct 2018 10:04:08 +0200 Subject: drm/ttm: Rename ttm_bo_global_{init,release}() to ttm_bo_global_ref_{,}() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The functions ttm_bo_global_init() and ttm_bo_global_release() do not receive an argument of type struct ttm_bo_global. Both take a struct drm_global_reference that contains points to a struct ttm_bo_global_ref. Renaming them reflects this. Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers/gpu/drm/ttm/ttm_bo.c') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 26b889f86670..9c2bb880491e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1522,16 +1522,16 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) kfree(glob); } -void ttm_bo_global_release(struct drm_global_reference *ref) +void ttm_bo_global_ref_release(struct drm_global_reference *ref) { struct ttm_bo_global *glob = ref->object; kobject_del(&glob->kobj); kobject_put(&glob->kobj); } -EXPORT_SYMBOL(ttm_bo_global_release); +EXPORT_SYMBOL(ttm_bo_global_ref_release); -int ttm_bo_global_init(struct drm_global_reference *ref) +int ttm_bo_global_ref_init(struct drm_global_reference *ref) { struct ttm_bo_global_ref *bo_ref = container_of(ref, struct ttm_bo_global_ref, ref); @@ -1564,7 +1564,7 @@ out_no_drp: kfree(glob); return ret; } -EXPORT_SYMBOL(ttm_bo_global_init); +EXPORT_SYMBOL(ttm_bo_global_ref_init); int ttm_bo_device_release(struct ttm_bo_device *bdev) -- cgit v1.2.3 From 105f20706fb5df8b763e3d9a9bfbfa73386391c3 Mon Sep 17 00:00:00 2001 From: Thomas Zimmermann Date: Tue, 16 Oct 2018 10:04:09 +0200 Subject: drm/ttm: Provide ttm_bo_global_{init/release}() for struct ttm_bo_global MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit So far, struct ttm_bo_global_ref was the only way of initializing a struct ttm_bo_global. Providing separate initializer and release functions for struct ttm_bo_global gives drivers the option of implementing their own init and release callbacks for drm_global_references of type DRM_GLOBAL_TTM_BO. The original functions for initializing and releasing via struct ttm_bo_global_ref are wrappers around the new interfaces. Signed-off-by: Thomas Zimmermann Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) (limited to 'drivers/gpu/drm/ttm/ttm_bo.c') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 9c2bb880491e..9edece6510d3 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1522,26 +1522,22 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) kfree(glob); } -void ttm_bo_global_ref_release(struct drm_global_reference *ref) +void ttm_bo_global_release(struct ttm_bo_global *glob) { - struct ttm_bo_global *glob = ref->object; - kobject_del(&glob->kobj); kobject_put(&glob->kobj); } -EXPORT_SYMBOL(ttm_bo_global_ref_release); +EXPORT_SYMBOL(ttm_bo_global_release); -int ttm_bo_global_ref_init(struct drm_global_reference *ref) +int ttm_bo_global_init(struct ttm_bo_global *glob, + struct ttm_mem_global *mem_glob) { - struct ttm_bo_global_ref *bo_ref = - container_of(ref, struct ttm_bo_global_ref, ref); - struct ttm_bo_global *glob = ref->object; int ret; unsigned i; mutex_init(&glob->device_list_mutex); spin_lock_init(&glob->lru_lock); - glob->mem_glob = bo_ref->mem_glob; + glob->mem_glob = mem_glob; glob->mem_glob->bo_glob = glob; glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); @@ -1564,7 +1560,7 @@ out_no_drp: kfree(glob); return ret; } -EXPORT_SYMBOL(ttm_bo_global_ref_init); +EXPORT_SYMBOL(ttm_bo_global_init); int ttm_bo_device_release(struct ttm_bo_device *bdev) -- cgit v1.2.3 From 27eb1fa9130a98edd2b321d4dbce5c8b244ee7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 19 Oct 2018 13:49:05 +0200 Subject: drm/ttm: use a static ttm_mem_global instance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the name says we only need one global instance of ttm_mem_global. Drop all the driver initialization and just use a single exported instance which is initialized during BO global initialization. Signed-off-by: Christian König Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/gpu/drm/ttm/ttm_bo.c') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 9edece6510d3..3006050b1720 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1526,18 +1526,22 @@ void ttm_bo_global_release(struct ttm_bo_global *glob) { kobject_del(&glob->kobj); kobject_put(&glob->kobj); + ttm_mem_global_release(&ttm_mem_glob); } EXPORT_SYMBOL(ttm_bo_global_release); -int ttm_bo_global_init(struct ttm_bo_global *glob, - struct ttm_mem_global *mem_glob) +int ttm_bo_global_init(struct ttm_bo_global *glob) { int ret; unsigned i; + ret = ttm_mem_global_init(&ttm_mem_glob); + if (ret) + return ret; + mutex_init(&glob->device_list_mutex); spin_lock_init(&glob->lru_lock); - glob->mem_glob = mem_glob; + glob->mem_glob = &ttm_mem_glob; glob->mem_glob->bo_glob = glob; glob->dummy_read_page = alloc_page(__GFP_ZERO | GFP_DMA32); -- cgit v1.2.3 From 56b3d20413587fab6a790cfc8bc075ca94bc8ed9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 19 Oct 2018 14:09:24 +0200 Subject: drm/ttm: make the device list mutex static MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This way it can protect the whole BO global state. Signed-off-by: Christian König Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'drivers/gpu/drm/ttm/ttm_bo.c') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 3006050b1720..4ec368b2555a 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -45,6 +45,11 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj); +/** + * ttm_global_mutex - protecting the global BO state + */ +DEFINE_MUTEX(ttm_global_mutex); + static struct attribute ttm_bo_count = { .name = "bo_count", .mode = S_IRUGO @@ -1539,7 +1544,6 @@ int ttm_bo_global_init(struct ttm_bo_global *glob) if (ret) return ret; - mutex_init(&glob->device_list_mutex); spin_lock_init(&glob->lru_lock); glob->mem_glob = &ttm_mem_glob; glob->mem_glob->bo_glob = glob; @@ -1587,9 +1591,9 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) } } - mutex_lock(&glob->device_list_mutex); + mutex_lock(&ttm_global_mutex); list_del(&bdev->device_list); - mutex_unlock(&glob->device_list_mutex); + mutex_unlock(&ttm_global_mutex); cancel_delayed_work_sync(&bdev->wq); @@ -1636,9 +1640,9 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, bdev->dev_mapping = mapping; bdev->glob = glob; bdev->need_dma32 = need_dma32; - mutex_lock(&glob->device_list_mutex); + mutex_lock(&ttm_global_mutex); list_add_tail(&bdev->device_list, &glob->device_list); - mutex_unlock(&glob->device_list_mutex); + mutex_unlock(&ttm_global_mutex); return 0; out_no_sys: -- cgit v1.2.3 From 62b53b37e4b1500d4eb4624a44ad861cf8d3cd18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 19 Oct 2018 15:06:06 +0200 Subject: drm/ttm: use a static ttm_bo_global instance MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As the name says we only need one global instance of ttm_bo_global. Just use a single exported instance which is save to initialize multiple times. Signed-off-by: Christian König Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'drivers/gpu/drm/ttm/ttm_bo.c') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 4ec368b2555a..d89183f95570 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -49,6 +49,9 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj); * ttm_global_mutex - protecting the global BO state */ DEFINE_MUTEX(ttm_global_mutex); +struct ttm_bo_global ttm_bo_glob = { + .use_count = 0 +}; static struct attribute ttm_bo_count = { .name = "bo_count", @@ -1527,22 +1530,35 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) kfree(glob); } -void ttm_bo_global_release(struct ttm_bo_global *glob) +void ttm_bo_global_release(void) { + struct ttm_bo_global *glob = &ttm_bo_glob; + + mutex_lock(&ttm_global_mutex); + if (--glob->use_count > 0) + goto out; + kobject_del(&glob->kobj); kobject_put(&glob->kobj); ttm_mem_global_release(&ttm_mem_glob); +out: + mutex_unlock(&ttm_global_mutex); } EXPORT_SYMBOL(ttm_bo_global_release); -int ttm_bo_global_init(struct ttm_bo_global *glob) +int ttm_bo_global_init(void) { - int ret; + struct ttm_bo_global *glob = &ttm_bo_glob; + int ret = 0; unsigned i; + mutex_lock(&ttm_global_mutex); + if (++glob->use_count > 1) + goto out; + ret = ttm_mem_global_init(&ttm_mem_glob); if (ret) - return ret; + goto out; spin_lock_init(&glob->lru_lock); glob->mem_glob = &ttm_mem_glob; @@ -1551,7 +1567,7 @@ int ttm_bo_global_init(struct ttm_bo_global *glob) if (unlikely(glob->dummy_read_page == NULL)) { ret = -ENOMEM; - goto out_no_drp; + goto out; } for (i = 0; i < TTM_MAX_BO_PRIORITY; ++i) @@ -1563,9 +1579,8 @@ int ttm_bo_global_init(struct ttm_bo_global *glob) &glob->kobj, &ttm_bo_glob_kobj_type, ttm_get_kobj(), "buffer_objects"); if (unlikely(ret != 0)) kobject_put(&glob->kobj); - return ret; -out_no_drp: - kfree(glob); +out: + mutex_unlock(&ttm_global_mutex); return ret; } EXPORT_SYMBOL(ttm_bo_global_init); -- cgit v1.2.3 From a64f784bb14a56bfdfad2dc397dd67e4564e3a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Fri, 19 Oct 2018 16:55:26 +0200 Subject: drm/ttm: initialize globals during device init (v2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sure that the global BO state is always correctly initialized. This allows removing all the device code to initialize it. v2: fix up vbox (Alex) Signed-off-by: Christian König Reviewed-by: Junwei Zhang Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'drivers/gpu/drm/ttm/ttm_bo.c') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d89183f95570..df028805b7e2 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1530,7 +1530,7 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) kfree(glob); } -void ttm_bo_global_release(void) +static void ttm_bo_global_release(void) { struct ttm_bo_global *glob = &ttm_bo_glob; @@ -1544,9 +1544,8 @@ void ttm_bo_global_release(void) out: mutex_unlock(&ttm_global_mutex); } -EXPORT_SYMBOL(ttm_bo_global_release); -int ttm_bo_global_init(void) +static int ttm_bo_global_init(void) { struct ttm_bo_global *glob = &ttm_bo_glob; int ret = 0; @@ -1583,8 +1582,6 @@ out: mutex_unlock(&ttm_global_mutex); return ret; } -EXPORT_SYMBOL(ttm_bo_global_init); - int ttm_bo_device_release(struct ttm_bo_device *bdev) { @@ -1623,18 +1620,25 @@ int ttm_bo_device_release(struct ttm_bo_device *bdev) drm_vma_offset_manager_destroy(&bdev->vma_manager); + if (!ret) + ttm_bo_global_release(); + return ret; } EXPORT_SYMBOL(ttm_bo_device_release); int ttm_bo_device_init(struct ttm_bo_device *bdev, - struct ttm_bo_global *glob, struct ttm_bo_driver *driver, struct address_space *mapping, uint64_t file_page_offset, bool need_dma32) { - int ret = -EINVAL; + struct ttm_bo_global *glob = &ttm_bo_glob; + int ret; + + ret = ttm_bo_global_init(); + if (ret) + return ret; bdev->driver = driver; @@ -1661,6 +1665,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, return 0; out_no_sys: + ttm_bo_global_release(); return ret; } EXPORT_SYMBOL(ttm_bo_device_init); -- cgit v1.2.3 From 30f33126feca0fe16df9e9302ffc28a953e2eb37 Mon Sep 17 00:00:00 2001 From: Trigger Huang Date: Tue, 6 Nov 2018 19:37:58 +0800 Subject: drm/ttm: Fix bo_global and mem_global kfree error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ttm_bo_glob and ttm_mem_glob are defined as structure instance, while not allocated by kzalloc, so kfree should not be invoked to release them anymore. Otherwise, it will cause the following kernel BUG when unloading amdgpu module [ 48.419294] kernel BUG at /build/linux-5s7Xkn/linux-4.15.0/mm/slub.c:3894! [ 48.419352] invalid opcode: 0000 [#1] SMP PTI [ 48.419387] Modules linked in: amdgpu(OE-) amdchash(OE) amdttm(OE) amd_sched(OE) amdkcl(OE) amd_iommu_v2 drm_kms_helper drm i2c_algo_bit fb_sys_fops syscopyarea sysfillrect sysimgblt snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi pcbc snd_seq snd_seq_device snd_timer aesni_intel snd soundcore joydev aes_x86_64 crypto_simd glue_helper cryptd input_leds mac_hid serio_raw binfmt_misc nfsd auth_rpcgss nfs_acl lockd grace sunrpc sch_fq_codel parport_pc ppdev lp parport ip_tables x_tables autofs4 8139too psmouse i2c_piix4 8139cp mii floppy pata_acpi [ 48.419782] CPU: 1 PID: 1281 Comm: modprobe Tainted: G OE 4.15.0-20-generic #21-Ubuntu [ 48.419838] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014 [ 48.419901] RIP: 0010:kfree+0x137/0x180 [ 48.419934] RSP: 0018:ffffb02101273bf8 EFLAGS: 00010246 [ 48.419974] RAX: ffffeee1418ad7e0 RBX: ffffffffc075f100 RCX: ffff8fed7fca7ed0 [ 48.420025] RDX: 0000000000000000 RSI: 000000000003440e RDI: 0000000022400000 [ 48.420073] RBP: ffffb02101273c10 R08: 0000000000000010 R09: ffff8fed7ffd3680 [ 48.420121] R10: ffffeee1418ad7c0 R11: ffff8fed7ffd3000 R12: ffffffffc075e2c0 [ 48.420169] R13: ffffffffc074ec10 R14: ffff8fed73063900 R15: ffff8fed737428e8 [ 48.420216] FS: 00007fdc912ec540(0000) GS:ffff8fed7fc80000(0000) knlGS:0000000000000000 [ 48.420267] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 48.420308] CR2: 000055fa40c30060 CR3: 000000023470a006 CR4: 00000000003606e0 [ 48.420358] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 48.420405] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 48.420452] Call Trace: [ 48.420485] ttm_bo_global_kobj_release+0x20/0x30 [amdttm] [ 48.420528] kobject_release+0x6a/0x180 [ 48.420562] kobject_put+0x28/0x50 [ 48.420595] ttm_bo_global_release+0x36/0x50 [amdttm] [ 48.420636] amdttm_bo_device_release+0x119/0x180 [amdttm] [ 48.420678] ? amdttm_bo_clean_mm+0xa6/0xf0 [amdttm] [ 48.420760] amdgpu_ttm_fini+0xc9/0x180 [amdgpu] [ 48.420821] amdgpu_bo_fini+0x12/0x40 [amdgpu] [ 48.420889] gmc_v9_0_sw_fini+0x40/0x50 [amdgpu] [ 48.420947] amdgpu_device_fini+0x36f/0x4c0 [amdgpu] [ 48.421007] amdgpu_driver_unload_kms+0xb4/0x150 [amdgpu] [ 48.421058] drm_dev_unregister+0x46/0xf0 [drm] [ 48.421102] drm_dev_unplug+0x12/0x70 [drm] Signed-off-by: Trigger Huang Reviewed-by: Christian König Signed-off-by: Alex Deucher --- drivers/gpu/drm/ttm/ttm_bo.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/gpu/drm/ttm/ttm_bo.c') diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index df028805b7e2..01c6d14a005d 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1527,7 +1527,6 @@ static void ttm_bo_global_kobj_release(struct kobject *kobj) container_of(kobj, struct ttm_bo_global, kobj); __free_page(glob->dummy_read_page); - kfree(glob); } static void ttm_bo_global_release(void) -- cgit v1.2.3