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

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
...@@ -73,6 +73,10 @@ static int xe_file_open(struct drm_device *dev, struct drm_file *file) ...@@ -73,6 +73,10 @@ static int xe_file_open(struct drm_device *dev, struct drm_file *file)
mutex_init(&xef->exec_queue.lock); mutex_init(&xef->exec_queue.lock);
xa_init_flags(&xef->exec_queue.xa, XA_FLAGS_ALLOC1); 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; file->driver_priv = xef;
return 0; return 0;
} }
...@@ -105,6 +109,10 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file) ...@@ -105,6 +109,10 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file)
xa_destroy(&xef->vm.xa); xa_destroy(&xef->vm.xa);
mutex_destroy(&xef->vm.lock); mutex_destroy(&xef->vm.lock);
spin_lock(&xe->clients.lock);
xe->clients.count--;
spin_unlock(&xe->clients.lock);
xe_drm_client_put(xef->client); xe_drm_client_put(xef->client);
kfree(xef); kfree(xef);
} }
...@@ -225,6 +233,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev, ...@@ -225,6 +233,7 @@ struct xe_device *xe_device_create(struct pci_dev *pdev,
xe->info.force_execlist = xe_modparam.force_execlist; xe->info.force_execlist = xe_modparam.force_execlist;
spin_lock_init(&xe->irq.lock); spin_lock_init(&xe->irq.lock);
spin_lock_init(&xe->clients.lock);
init_waitqueue_head(&xe->ufence_wq); init_waitqueue_head(&xe->ufence_wq);
......
...@@ -310,6 +310,15 @@ struct xe_device { ...@@ -310,6 +310,15 @@ struct xe_device {
enum xe_sriov_mode __mode; enum xe_sriov_mode __mode;
} sriov; } 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 */ /** @usm: unified memory state */
struct { struct {
/** @asid: convert a ASID to VM */ /** @asid: convert a ASID to VM */
......
...@@ -105,6 +105,7 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr, ...@@ -105,6 +105,7 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr,
const char *buff, size_t count) const char *buff, size_t count)
{ {
struct xe_gt *gt = kobj_to_gt(&kdev->kobj); struct xe_gt *gt = kobj_to_gt(&kdev->kobj);
struct xe_device *xe = gt_to_xe(gt);
u32 num_engines, num_slices; u32 num_engines, num_slices;
int ret; int ret;
...@@ -123,12 +124,21 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr, ...@@ -123,12 +124,21 @@ ccs_mode_store(struct device *kdev, struct device_attribute *attr,
return -EINVAL; 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) { if (gt->ccs_mode != num_engines) {
xe_gt_info(gt, "Setting compute mode to %d\n", num_engines); xe_gt_info(gt, "Setting compute mode to %d\n", num_engines);
gt->ccs_mode = num_engines; gt->ccs_mode = num_engines;
xe_gt_reset_async(gt); xe_gt_reset_async(gt);
} }
spin_unlock(&xe->clients.lock);
return count; return count;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment