mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
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: Andi Shyti <andi.shyti@linux.intel.com> Signed-off-by: Niranjana Vishwanathapura <niranjana.vishwanathapura@intel.com> Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
This commit is contained in:
parent
f3bc5bb4d5
commit
78e2701a26
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user