Skip to content

Commit b6c2472

Browse files
committed
Merge tag 'drm-misc-fixes-2021-11-11' of git://anongit.freedesktop.org/drm/drm-misc into drm-next
* dma-buf: name_lock fixes * prime: Keep object ref during mmap * nouveau: Fix a refcount issue; Fix device removal; Protect client list with dedicated mutex; Fix address CE0 address calculation * ttm: Fix race condition during BO eviction Signed-off-by: Dave Airlie <[email protected]> From: Thomas Zimmermann <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
2 parents 447212b + 7120a44 commit b6c2472

File tree

8 files changed

+57
-11
lines changed

8 files changed

+57
-11
lines changed

drivers/dma-buf/dma-buf.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,13 +1359,16 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
13591359
if (ret)
13601360
goto error_unlock;
13611361

1362+
1363+
spin_lock(&buf_obj->name_lock);
13621364
seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n",
13631365
buf_obj->size,
13641366
buf_obj->file->f_flags, buf_obj->file->f_mode,
13651367
file_count(buf_obj->file),
13661368
buf_obj->exp_name,
13671369
file_inode(buf_obj->file)->i_ino,
13681370
buf_obj->name ?: "");
1371+
spin_unlock(&buf_obj->name_lock);
13691372

13701373
dma_resv_for_each_fence(&cursor, buf_obj->resv, true, fence) {
13711374
seq_printf(s, "\t%s fence: %s %s %ssignalled\n",

drivers/gpu/drm/drm_prime.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -719,11 +719,13 @@ int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
719719
if (obj->funcs && obj->funcs->mmap) {
720720
vma->vm_ops = obj->funcs->vm_ops;
721721

722+
drm_gem_object_get(obj);
722723
ret = obj->funcs->mmap(obj, vma);
723-
if (ret)
724+
if (ret) {
725+
drm_gem_object_put(obj);
724726
return ret;
727+
}
725728
vma->vm_private_data = obj;
726-
drm_gem_object_get(obj);
727729
return 0;
728730
}
729731

drivers/gpu/drm/nouveau/nouveau_drm.c

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -562,6 +562,7 @@ nouveau_drm_device_init(struct drm_device *dev)
562562
nvkm_dbgopt(nouveau_debug, "DRM");
563563

564564
INIT_LIST_HEAD(&drm->clients);
565+
mutex_init(&drm->clients_lock);
565566
spin_lock_init(&drm->tile.lock);
566567

567568
/* workaround an odd issue on nvc1 by disabling the device's
@@ -632,6 +633,7 @@ nouveau_drm_device_init(struct drm_device *dev)
632633
static void
633634
nouveau_drm_device_fini(struct drm_device *dev)
634635
{
636+
struct nouveau_cli *cli, *temp_cli;
635637
struct nouveau_drm *drm = nouveau_drm(dev);
636638

637639
if (nouveau_pmops_runtime()) {
@@ -656,9 +658,28 @@ nouveau_drm_device_fini(struct drm_device *dev)
656658
nouveau_ttm_fini(drm);
657659
nouveau_vga_fini(drm);
658660

661+
/*
662+
* There may be existing clients from as-yet unclosed files. For now,
663+
* clean them up here rather than deferring until the file is closed,
664+
* but this likely not correct if we want to support hot-unplugging
665+
* properly.
666+
*/
667+
mutex_lock(&drm->clients_lock);
668+
list_for_each_entry_safe(cli, temp_cli, &drm->clients, head) {
669+
list_del(&cli->head);
670+
mutex_lock(&cli->mutex);
671+
if (cli->abi16)
672+
nouveau_abi16_fini(cli->abi16);
673+
mutex_unlock(&cli->mutex);
674+
nouveau_cli_fini(cli);
675+
kfree(cli);
676+
}
677+
mutex_unlock(&drm->clients_lock);
678+
659679
nouveau_cli_fini(&drm->client);
660680
nouveau_cli_fini(&drm->master);
661681
nvif_parent_dtor(&drm->parent);
682+
mutex_destroy(&drm->clients_lock);
662683
kfree(drm);
663684
}
664685

@@ -796,7 +817,7 @@ nouveau_drm_device_remove(struct drm_device *dev)
796817
struct nvkm_client *client;
797818
struct nvkm_device *device;
798819

799-
drm_dev_unregister(dev);
820+
drm_dev_unplug(dev);
800821

801822
client = nvxx_client(&drm->client.base);
802823
device = nvkm_device_find(client->device);
@@ -1090,9 +1111,9 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
10901111

10911112
fpriv->driver_priv = cli;
10921113

1093-
mutex_lock(&drm->client.mutex);
1114+
mutex_lock(&drm->clients_lock);
10941115
list_add(&cli->head, &drm->clients);
1095-
mutex_unlock(&drm->client.mutex);
1116+
mutex_unlock(&drm->clients_lock);
10961117

10971118
done:
10981119
if (ret && cli) {
@@ -1110,6 +1131,16 @@ nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
11101131
{
11111132
struct nouveau_cli *cli = nouveau_cli(fpriv);
11121133
struct nouveau_drm *drm = nouveau_drm(dev);
1134+
int dev_index;
1135+
1136+
/*
1137+
* The device is gone, and as it currently stands all clients are
1138+
* cleaned up in the removal codepath. In the future this may change
1139+
* so that we can support hot-unplugging, but for now we immediately
1140+
* return to avoid a double-free situation.
1141+
*/
1142+
if (!drm_dev_enter(dev, &dev_index))
1143+
return;
11131144

11141145
pm_runtime_get_sync(dev->dev);
11151146

@@ -1118,14 +1149,15 @@ nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
11181149
nouveau_abi16_fini(cli->abi16);
11191150
mutex_unlock(&cli->mutex);
11201151

1121-
mutex_lock(&drm->client.mutex);
1152+
mutex_lock(&drm->clients_lock);
11221153
list_del(&cli->head);
1123-
mutex_unlock(&drm->client.mutex);
1154+
mutex_unlock(&drm->clients_lock);
11241155

11251156
nouveau_cli_fini(cli);
11261157
kfree(cli);
11271158
pm_runtime_mark_last_busy(dev->dev);
11281159
pm_runtime_put_autosuspend(dev->dev);
1160+
drm_dev_exit(dev_index);
11291161
}
11301162

11311163
static const struct drm_ioctl_desc

drivers/gpu/drm/nouveau/nouveau_drv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ struct nouveau_drm {
139139

140140
struct list_head clients;
141141

142+
/**
143+
* @clients_lock: Protects access to the @clients list of &struct nouveau_cli.
144+
*/
145+
struct mutex clients_lock;
146+
142147
u8 old_pm_cap;
143148

144149
struct {

drivers/gpu/drm/nouveau/nouveau_svm.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,14 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
162162
*/
163163

164164
mm = get_task_mm(current);
165+
if (!mm) {
166+
return -EINVAL;
167+
}
165168
mmap_read_lock(mm);
166169

167170
if (!cli->svm.svmm) {
168171
mmap_read_unlock(mm);
172+
mmput(mm);
169173
return -EINVAL;
170174
}
171175

drivers/gpu/drm/nouveau/nvkm/engine/ce/gt215.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,6 @@ int
7878
gt215_ce_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
7979
struct nvkm_engine **pengine)
8080
{
81-
return nvkm_falcon_new_(&gt215_ce, device, type, inst,
81+
return nvkm_falcon_new_(&gt215_ce, device, type, -1,
8282
(device->chipset != 0xaf), 0x104000, pengine);
8383
}

drivers/gpu/drm/nouveau/nvkm/engine/device/base.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,8 +3147,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
31473147
WARN_ON(device->chip->ptr.inst & ~((1 << ARRAY_SIZE(device->ptr)) - 1)); \
31483148
for (j = 0; device->chip->ptr.inst && j < ARRAY_SIZE(device->ptr); j++) { \
31493149
if ((device->chip->ptr.inst & BIT(j)) && (subdev_mask & BIT_ULL(type))) { \
3150-
int inst = (device->chip->ptr.inst == 1) ? -1 : (j); \
3151-
ret = device->chip->ptr.ctor(device, (type), inst, &device->ptr[j]); \
3150+
ret = device->chip->ptr.ctor(device, (type), (j), &device->ptr[j]); \
31523151
subdev = nvkm_device_subdev(device, (type), (j)); \
31533152
if (ret) { \
31543153
nvkm_subdev_del(&subdev); \

drivers/gpu/drm/ttm/ttm_bo.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,8 @@ static bool ttm_bo_evict_swapout_allowable(struct ttm_buffer_object *bo,
619619
*busy = !ret;
620620
}
621621

622-
if (ret && place && !bo->bdev->funcs->eviction_valuable(bo, place)) {
622+
if (ret && place && (bo->resource->mem_type != place->mem_type ||
623+
!bo->bdev->funcs->eviction_valuable(bo, place))) {
623624
ret = false;
624625
if (*locked) {
625626
dma_resv_unlock(bo->base.resv);

0 commit comments

Comments
 (0)