Commit 8d286e2f authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-intel-next-fixes-2020-06-04' of...

Merge tag 'drm-intel-next-fixes-2020-06-04' of git://anongit.freedesktop.org/drm/drm-intel

 into drm-next

- Includes gvt-next-fixes-2020-05-28
- Use after free fix for display global state.
- Whitelisting context-local timestamp on Gen9
  and two scheduler fixes with deps (Cc: stable)
- Removal of write flag from sysfs files where
  ineffective

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20200604150454.GA59322@jlahtine-desk.ger.corp.intel.com
parents fa3fa222 f8665d79
Loading
Loading
Loading
Loading
+39 −6
Original line number Diff line number Diff line
@@ -10,6 +10,28 @@
#include "intel_display_types.h"
#include "intel_global_state.h"

static void __intel_atomic_global_state_free(struct kref *kref)
{
	struct intel_global_state *obj_state =
		container_of(kref, struct intel_global_state, ref);
	struct intel_global_obj *obj = obj_state->obj;

	obj->funcs->atomic_destroy_state(obj, obj_state);
}

static void intel_atomic_global_state_put(struct intel_global_state *obj_state)
{
	kref_put(&obj_state->ref, __intel_atomic_global_state_free);
}

static struct intel_global_state *
intel_atomic_global_state_get(struct intel_global_state *obj_state)
{
	kref_get(&obj_state->ref);

	return obj_state;
}

void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv,
				  struct intel_global_obj *obj,
				  struct intel_global_state *state,
@@ -17,6 +39,10 @@ void intel_atomic_global_obj_init(struct drm_i915_private *dev_priv,
{
	memset(obj, 0, sizeof(*obj));

	state->obj = obj;

	kref_init(&state->ref);

	obj->state = state;
	obj->funcs = funcs;
	list_add_tail(&obj->head, &dev_priv->global_obj_list);
@@ -28,7 +54,9 @@ void intel_atomic_global_obj_cleanup(struct drm_i915_private *dev_priv)

	list_for_each_entry_safe(obj, next, &dev_priv->global_obj_list, head) {
		list_del(&obj->head);
		obj->funcs->atomic_destroy_state(obj, obj->state);

		drm_WARN_ON(&dev_priv->drm, kref_read(&obj->state->ref) != 1);
		intel_atomic_global_state_put(obj->state);
	}
}

@@ -97,10 +125,14 @@ intel_atomic_get_global_obj_state(struct intel_atomic_state *state,
	if (!obj_state)
		return ERR_PTR(-ENOMEM);

	obj_state->obj = obj;
	obj_state->changed = false;

	kref_init(&obj_state->ref);

	state->global_objs[index].state = obj_state;
	state->global_objs[index].old_state = obj->state;
	state->global_objs[index].old_state =
		intel_atomic_global_state_get(obj->state);
	state->global_objs[index].new_state = obj_state;
	state->global_objs[index].ptr = obj;
	obj_state->state = state;
@@ -163,7 +195,9 @@ void intel_atomic_swap_global_state(struct intel_atomic_state *state)
		new_obj_state->state = NULL;

		state->global_objs[i].state = old_obj_state;
		obj->state = new_obj_state;

		intel_atomic_global_state_put(obj->state);
		obj->state = intel_atomic_global_state_get(new_obj_state);
	}
}

@@ -172,10 +206,9 @@ void intel_atomic_clear_global_state(struct intel_atomic_state *state)
	int i;

	for (i = 0; i < state->num_global_objs; i++) {
		struct intel_global_obj *obj = state->global_objs[i].ptr;
		intel_atomic_global_state_put(state->global_objs[i].old_state);
		intel_atomic_global_state_put(state->global_objs[i].new_state);

		obj->funcs->atomic_destroy_state(obj,
						 state->global_objs[i].state);
		state->global_objs[i].ptr = NULL;
		state->global_objs[i].state = NULL;
		state->global_objs[i].old_state = NULL;
+3 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
#ifndef __INTEL_GLOBAL_STATE_H__
#define __INTEL_GLOBAL_STATE_H__

#include <linux/kref.h>
#include <linux/list.h>

struct drm_i915_private;
@@ -54,7 +55,9 @@ struct intel_global_obj {
		for_each_if(obj)

struct intel_global_state {
	struct intel_global_obj *obj;
	struct intel_atomic_state *state;
	struct kref ref;
	bool changed;
};

+2 −2
Original line number Diff line number Diff line
@@ -230,7 +230,7 @@ static void intel_context_set_gem(struct intel_context *ce,
		ce->timeline = intel_timeline_get(ctx->timeline);

	if (ctx->sched.priority >= I915_PRIORITY_NORMAL &&
	    intel_engine_has_semaphores(ce->engine))
	    intel_engine_has_timeslices(ce->engine))
		__set_bit(CONTEXT_USE_SEMAPHORES, &ce->flags);
}

@@ -1969,7 +1969,7 @@ static int __apply_priority(struct intel_context *ce, void *arg)
{
	struct i915_gem_context *ctx = arg;

	if (!intel_engine_has_semaphores(ce->engine))
	if (!intel_engine_has_timeslices(ce->engine))
		return 0;

	if (ctx->sched.priority >= I915_PRIORITY_NORMAL)
+9 −6
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ static int shmem_get_pages(struct drm_i915_gem_object *obj)
	unsigned long last_pfn = 0;	/* suppress gcc warning */
	unsigned int max_segment = i915_sg_segment_size();
	unsigned int sg_page_sizes;
	struct pagevec pvec;
	gfp_t noreclaim;
	int ret;

@@ -192,6 +191,9 @@ err_sg:
	sg_mark_end(sg);
err_pages:
	mapping_clear_unevictable(mapping);
	if (sg != st->sgl) {
		struct pagevec pvec;

		pagevec_init(&pvec);
		for_each_sgt_page(page, sgt_iter, st) {
			if (!pagevec_add(&pvec, page))
@@ -199,6 +201,7 @@ err_pages:
		}
		if (pagevec_count(&pvec))
			check_release_pagevec(&pvec);
	}
	sg_free_table(st);
	kfree(st);

+0 −2
Original line number Diff line number Diff line
@@ -97,8 +97,6 @@ int __intel_context_do_pin(struct intel_context *ce)
{
	int err;

	GEM_BUG_ON(intel_context_is_closed(ce));

	if (unlikely(!test_bit(CONTEXT_ALLOC_BIT, &ce->flags))) {
		err = intel_context_alloc_state(ce);
		if (err)
Loading