Commit 78e2701a authored by Niranjana Vishwanathapura's avatar Niranjana Vishwanathapura Committed by Rodrigo Vivi
Browse files

drm/xe: Avoid any races around ccs_mode update



Ensure that there are no drm clients when changing CCS mode.
Allow exec_queue creation only with enabled CCS engines.

v2: Rebase

Reviewed-by: default avatarAndi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: default avatarNiranjana Vishwanathapura <niranjana.vishwanathapura@intel.com>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
parent f3bc5bb4
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -73,6 +73,10 @@ static int xe_file_open(struct drm_device *dev, struct drm_file *file)
	mutex_init(&xef->exec_queue.lock);
	xa_init_flags(&xef->exec_queue.xa, XA_FLAGS_ALLOC1);

	spin_lock(&xe->clients.lock);
	xe->clients.count++;
	spin_unlock(&xe->clients.lock);

	file->driver_priv = xef;
	return 0;
}
@@ -105,6 +109,10 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file)
	xa_destroy(&xef->vm.xa);
	mutex_destroy(&xef->vm.lock);

	spin_lock(&xe->clients.lock);
	xe->clients.count--;
	spin_unlock(&xe->clients.lock);

	xe_drm_client_put(xef->client);
	kfree(xef);
}
@@ -225,6 +233,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
	xe->info.force_execlist = xe_modparam.force_execlist;

	spin_lock_init(&xe->irq.lock);
	spin_lock_init(&xe->clients.lock);

	init_waitqueue_head(&xe->ufence_wq);

+9 −0
Original line number Diff line number Diff line
@@ -310,6 +310,15 @@ struct xe_device {
		enum xe_sriov_mode __mode;
	} sriov;

	/** @clients: drm clients info */
	struct {
		/** @lock: Protects drm clients info */
		spinlock_t lock;

		/** @count: number of drm clients */
		u64 count;
	} clients;

	/** @usm: unified memory state */
	struct {
		/** @asid: convert a ASID to VM */
+10 −0
Original line number Diff line number Diff line
@@ -105,6 +105,7 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr,
	       const char *buff, size_t count)
{
	struct xe_gt *gt = kobj_to_gt(&kdev->kobj);
	struct xe_device *xe = gt_to_xe(gt);
	u32 num_engines, num_slices;
	int ret;

@@ -123,12 +124,21 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr,
		return -EINVAL;
	}

	/* CCS mode can only be updated when there are no drm clients */
	spin_lock(&xe->clients.lock);
	if (xe->clients.count) {
		spin_unlock(&xe->clients.lock);
		return -EBUSY;
	}

	if (gt->ccs_mode != num_engines) {
		xe_gt_info(gt, "Setting compute mode to %d\n", num_engines);
		gt->ccs_mode = num_engines;
		xe_gt_reset_async(gt);
	}

	spin_unlock(&xe->clients.lock);

	return count;
}