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

Merge tag 'drm-xe-fixes-2024-08-15' of https://gitlab.freedesktop.org/drm/xe/kernel into drm-fixes



- Validate user fence during creation (Brost)
- Fix use after free when client stats are captured (Umesh)
- SRIOV fixes (Michal)
- Runtime PM fixes (Brost)

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

From: Rodrigo Vivi <rodrigo.vivi@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/Zr4KWF5nM1YvnT8H@intel.com
parents 75eac7e8 f0027022
Loading
Loading
Loading
Loading
+50 −9
Original line number Diff line number Diff line
@@ -87,9 +87,55 @@ static int xe_file_open(struct drm_device *dev, struct drm_file *file)
	spin_unlock(&xe->clients.lock);

	file->driver_priv = xef;
	kref_init(&xef->refcount);

	return 0;
}

static void xe_file_destroy(struct kref *ref)
{
	struct xe_file *xef = container_of(ref, struct xe_file, refcount);
	struct xe_device *xe = xef->xe;

	xa_destroy(&xef->exec_queue.xa);
	mutex_destroy(&xef->exec_queue.lock);
	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);
}

/**
 * xe_file_get() - Take a reference to the xe file object
 * @xef: Pointer to the xe file
 *
 * Anyone with a pointer to xef must take a reference to the xe file
 * object using this call.
 *
 * Return: xe file pointer
 */
struct xe_file *xe_file_get(struct xe_file *xef)
{
	kref_get(&xef->refcount);
	return xef;
}

/**
 * xe_file_put() - Drop a reference to the xe file object
 * @xef: Pointer to the xe file
 *
 * Used to drop reference to the xef object
 */
void xe_file_put(struct xe_file *xef)
{
	kref_put(&xef->refcount, xe_file_destroy);
}

static void xe_file_close(struct drm_device *dev, struct drm_file *file)
{
	struct xe_device *xe = to_xe_device(dev);
@@ -98,6 +144,8 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file)
	struct xe_exec_queue *q;
	unsigned long idx;

	xe_pm_runtime_get(xe);

	/*
	 * No need for exec_queue.lock here as there is no contention for it
	 * when FD is closing as IOCTLs presumably can't be modifying the
@@ -108,21 +156,14 @@ static void xe_file_close(struct drm_device *dev, struct drm_file *file)
		xe_exec_queue_kill(q);
		xe_exec_queue_put(q);
	}
	xa_destroy(&xef->exec_queue.xa);
	mutex_destroy(&xef->exec_queue.lock);
	mutex_lock(&xef->vm.lock);
	xa_for_each(&xef->vm.xa, idx, vm)
		xe_vm_close_and_put(vm);
	mutex_unlock(&xef->vm.lock);
	xa_destroy(&xef->vm.xa);
	mutex_destroy(&xef->vm.lock);

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

	xe_drm_client_put(xef->client);
	kfree(xef);
	xe_pm_runtime_put(xe);
}

static const struct drm_ioctl_desc xe_ioctls[] = {
+3 −0
Original line number Diff line number Diff line
@@ -170,4 +170,7 @@ static inline bool xe_device_wedged(struct xe_device *xe)

void xe_device_declare_wedged(struct xe_device *xe);

struct xe_file *xe_file_get(struct xe_file *xef);
void xe_file_put(struct xe_file *xef);

#endif
+3 −0
Original line number Diff line number Diff line
@@ -566,6 +566,9 @@ struct xe_file {

	/** @client: drm client */
	struct xe_drm_client *client;

	/** @refcount: ref count of this xe file */
	struct kref refcount;
};

#endif
+1 −4
Original line number Diff line number Diff line
@@ -251,11 +251,8 @@ static void show_run_ticks(struct drm_printer *p, struct drm_file *file)

	/* Accumulate all the exec queues from this client */
	mutex_lock(&xef->exec_queue.lock);
	xa_for_each(&xef->exec_queue.xa, i, q) {
	xa_for_each(&xef->exec_queue.xa, i, q)
		xe_exec_queue_update_run_ticks(q);
		xef->run_ticks[q->class] += q->run_ticks - q->old_run_ticks;
		q->old_run_ticks = q->run_ticks;
	}
	mutex_unlock(&xef->exec_queue.lock);

	/* Get the total GPU cycles */
+9 −1
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@ static void __xe_exec_queue_free(struct xe_exec_queue *q)
{
	if (q->vm)
		xe_vm_put(q->vm);

	if (q->xef)
		xe_file_put(q->xef);

	kfree(q);
}

@@ -649,6 +653,7 @@ int xe_exec_queue_create_ioctl(struct drm_device *dev, void *data,
		goto kill_exec_queue;

	args->exec_queue_id = id;
	q->xef = xe_file_get(xef);

	return 0;

@@ -762,6 +767,7 @@ bool xe_exec_queue_is_idle(struct xe_exec_queue *q)
 */
void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q)
{
	struct xe_file *xef;
	struct xe_lrc *lrc;
	u32 old_ts, new_ts;

@@ -773,6 +779,8 @@ void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q)
	if (!q->vm || !q->vm->xef)
		return;

	xef = q->vm->xef;

	/*
	 * Only sample the first LRC. For parallel submission, all of them are
	 * scheduled together and we compensate that below by multiplying by
@@ -783,7 +791,7 @@ void xe_exec_queue_update_run_ticks(struct xe_exec_queue *q)
	 */
	lrc = q->lrc[0];
	new_ts = xe_lrc_update_timestamp(lrc, &old_ts);
	q->run_ticks += (new_ts - old_ts) * q->width;
	xef->run_ticks[q->class] += (new_ts - old_ts) * q->width;
}

void xe_exec_queue_kill(struct xe_exec_queue *q)
Loading