Commit b6c24725 authored by Dave Airlie's avatar Dave Airlie
Browse files

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: default avatarDave Airlie <airlied@redhat.com>

From: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/YYzY6jeox9EeI15i@linux-uq9g.fritz.box
parents 447212bb 7120a447
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1359,6 +1359,8 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
		if (ret)
			goto error_unlock;


		spin_lock(&buf_obj->name_lock);
		seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n",
				buf_obj->size,
				buf_obj->file->f_flags, buf_obj->file->f_mode,
@@ -1366,6 +1368,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
				buf_obj->exp_name,
				file_inode(buf_obj->file)->i_ino,
				buf_obj->name ?: "");
		spin_unlock(&buf_obj->name_lock);

		dma_resv_for_each_fence(&cursor, buf_obj->resv, true, fence) {
			seq_printf(s, "\t%s fence: %s %s %ssignalled\n",
+4 −2
Original line number Diff line number Diff line
@@ -719,11 +719,13 @@ int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
	if (obj->funcs && obj->funcs->mmap) {
		vma->vm_ops = obj->funcs->vm_ops;

		drm_gem_object_get(obj);
		ret = obj->funcs->mmap(obj, vma);
		if (ret)
		if (ret) {
			drm_gem_object_put(obj);
			return ret;
		}
		vma->vm_private_data = obj;
		drm_gem_object_get(obj);
		return 0;
	}

+37 −5
Original line number Diff line number Diff line
@@ -562,6 +562,7 @@ nouveau_drm_device_init(struct drm_device *dev)
		nvkm_dbgopt(nouveau_debug, "DRM");

	INIT_LIST_HEAD(&drm->clients);
	mutex_init(&drm->clients_lock);
	spin_lock_init(&drm->tile.lock);

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

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

	/*
	 * There may be existing clients from as-yet unclosed files. For now,
	 * clean them up here rather than deferring until the file is closed,
	 * but this likely not correct if we want to support hot-unplugging
	 * properly.
	 */
	mutex_lock(&drm->clients_lock);
	list_for_each_entry_safe(cli, temp_cli, &drm->clients, head) {
		list_del(&cli->head);
		mutex_lock(&cli->mutex);
		if (cli->abi16)
			nouveau_abi16_fini(cli->abi16);
		mutex_unlock(&cli->mutex);
		nouveau_cli_fini(cli);
		kfree(cli);
	}
	mutex_unlock(&drm->clients_lock);

	nouveau_cli_fini(&drm->client);
	nouveau_cli_fini(&drm->master);
	nvif_parent_dtor(&drm->parent);
	mutex_destroy(&drm->clients_lock);
	kfree(drm);
}

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

	drm_dev_unregister(dev);
	drm_dev_unplug(dev);

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

	fpriv->driver_priv = cli;

	mutex_lock(&drm->client.mutex);
	mutex_lock(&drm->clients_lock);
	list_add(&cli->head, &drm->clients);
	mutex_unlock(&drm->client.mutex);
	mutex_unlock(&drm->clients_lock);

done:
	if (ret && cli) {
@@ -1110,6 +1131,16 @@ nouveau_drm_postclose(struct drm_device *dev, struct drm_file *fpriv)
{
	struct nouveau_cli *cli = nouveau_cli(fpriv);
	struct nouveau_drm *drm = nouveau_drm(dev);
	int dev_index;

	/*
	 * The device is gone, and as it currently stands all clients are
	 * cleaned up in the removal codepath. In the future this may change
	 * so that we can support hot-unplugging, but for now we immediately
	 * return to avoid a double-free situation.
	 */
	if (!drm_dev_enter(dev, &dev_index))
		return;

	pm_runtime_get_sync(dev->dev);

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

	mutex_lock(&drm->client.mutex);
	mutex_lock(&drm->clients_lock);
	list_del(&cli->head);
	mutex_unlock(&drm->client.mutex);
	mutex_unlock(&drm->clients_lock);

	nouveau_cli_fini(cli);
	kfree(cli);
	pm_runtime_mark_last_busy(dev->dev);
	pm_runtime_put_autosuspend(dev->dev);
	drm_dev_exit(dev_index);
}

static const struct drm_ioctl_desc
+5 −0
Original line number Diff line number Diff line
@@ -139,6 +139,11 @@ struct nouveau_drm {

	struct list_head clients;

	/**
	 * @clients_lock: Protects access to the @clients list of &struct nouveau_cli.
	 */
	struct mutex clients_lock;

	u8 old_pm_cap;

	struct {
+4 −0
Original line number Diff line number Diff line
@@ -162,10 +162,14 @@ nouveau_svmm_bind(struct drm_device *dev, void *data,
	 */

	mm = get_task_mm(current);
	if (!mm) {
		return -EINVAL;
	}
	mmap_read_lock(mm);

	if (!cli->svm.svmm) {
		mmap_read_unlock(mm);
		mmput(mm);
		return -EINVAL;
	}

Loading