Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 63ffbcda authored by Joonas Lahtinen's avatar Joonas Lahtinen
Browse files

drm/i915: Sanitize engine context sizes



Pre-calculate engine context size based on engine class and device
generation and store it in the engine instance.

v2:
- Squash and get rid of hw_context_size (Chris)

v3:
- Move after MMIO init for probing on Gen7 and 8 (Chris)
- Retained rounding (Tvrtko)
v4:
- Rebase for deferred legacy context allocation

Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Oscar Mateo <oscar.mateo@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Cc: intel-gvt-dev@lists.freedesktop.org
Acked-by: default avatarTvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent a3662830
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -69,8 +69,7 @@ static int populate_shadow_context(struct intel_vgpu_workload *workload)
	gvt_dbg_sched("ring id %d workload lrca %x", ring_id,
			workload->ctx_desc.lrca);

	context_page_num = intel_lr_context_size(
			gvt->dev_priv->engine[ring_id]);
	context_page_num = gvt->dev_priv->engine[ring_id]->context_size;

	context_page_num = context_page_num >> PAGE_SHIFT;

@@ -333,8 +332,7 @@ static void update_guest_context(struct intel_vgpu_workload *workload)
	gvt_dbg_sched("ring id %d workload lrca %x\n", ring_id,
			workload->ctx_desc.lrca);

	context_page_num = intel_lr_context_size(
			gvt->dev_priv->engine[ring_id]);
	context_page_num = gvt->dev_priv->engine[ring_id]->context_size;

	context_page_num = context_page_num >> PAGE_SHIFT;

+9 −6
Original line number Diff line number Diff line
@@ -835,10 +835,6 @@ static int i915_driver_init_early(struct drm_i915_private *dev_priv,
	intel_uc_init_early(dev_priv);
	i915_memcpy_init_early(dev_priv);

	ret = intel_engines_init_early(dev_priv);
	if (ret)
		return ret;

	ret = i915_workqueues_init(dev_priv);
	if (ret < 0)
		goto err_engines;
@@ -948,14 +944,21 @@ static int i915_driver_init_mmio(struct drm_i915_private *dev_priv)

	ret = i915_mmio_setup(dev_priv);
	if (ret < 0)
		goto put_bridge;
		goto err_bridge;

	intel_uncore_init(dev_priv);

	ret = intel_engines_init_mmio(dev_priv);
	if (ret)
		goto err_uncore;

	i915_gem_init_mmio(dev_priv);

	return 0;

put_bridge:
err_uncore:
	intel_uncore_fini(dev_priv);
err_bridge:
	pci_dev_put(dev_priv->bridge_dev);

	return ret;
+1 −2
Original line number Diff line number Diff line
@@ -2359,7 +2359,6 @@ struct drm_i915_private {
	 */
	struct mutex av_mutex;

	uint32_t hw_context_size;
	struct list_head context_list;

	u32 fdi_rx_config;
@@ -3023,7 +3022,7 @@ extern unsigned long i915_gfx_val(struct drm_i915_private *dev_priv);
extern void i915_update_gfx_val(struct drm_i915_private *dev_priv);
int vlv_force_gfx_clock(struct drm_i915_private *dev_priv, bool on);

int intel_engines_init_early(struct drm_i915_private *dev_priv);
int intel_engines_init_mmio(struct drm_i915_private *dev_priv);
int intel_engines_init(struct drm_i915_private *dev_priv);

/* intel_hotplug.c */
+5 −51
Original line number Diff line number Diff line
@@ -92,33 +92,6 @@

#define ALL_L3_SLICES(dev) (1 << NUM_L3_SLICES(dev)) - 1

static int get_context_size(struct drm_i915_private *dev_priv)
{
	int ret;
	u32 reg;

	switch (INTEL_GEN(dev_priv)) {
	case 6:
		reg = I915_READ(CXT_SIZE);
		ret = GEN6_CXT_TOTAL_SIZE(reg) * 64;
		break;
	case 7:
		reg = I915_READ(GEN7_CXT_SIZE);
		if (IS_HASWELL(dev_priv))
			ret = HSW_CXT_TOTAL_SIZE;
		else
			ret = GEN7_CXT_TOTAL_SIZE(reg) * 64;
		break;
	case 8:
		ret = GEN8_CXT_TOTAL_SIZE;
		break;
	default:
		BUG();
	}

	return ret;
}

void i915_gem_context_free(struct kref *ctx_ref)
{
	struct i915_gem_context *ctx = container_of(ctx_ref, typeof(*ctx), ref);
@@ -384,21 +357,6 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
	BUILD_BUG_ON(MAX_CONTEXT_HW_ID > INT_MAX);
	ida_init(&dev_priv->context_hw_ida);

	if (i915.enable_execlists) {
		/* NB: intentionally left blank. We will allocate our own
		 * backing objects as we need them, thank you very much */
		dev_priv->hw_context_size = 0;
	} else if (HAS_HW_CONTEXTS(dev_priv)) {
		dev_priv->hw_context_size =
			round_up(get_context_size(dev_priv),
				 I915_GTT_PAGE_SIZE);
		if (dev_priv->hw_context_size > (1<<20)) {
			DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n",
					 dev_priv->hw_context_size);
			dev_priv->hw_context_size = 0;
		}
	}

	ctx = i915_gem_create_context(dev_priv, NULL);
	if (IS_ERR(ctx)) {
		DRM_ERROR("Failed to create default global context (error %ld)\n",
@@ -418,8 +376,8 @@ int i915_gem_context_init(struct drm_i915_private *dev_priv)
	GEM_BUG_ON(!i915_gem_context_is_kernel(ctx));

	DRM_DEBUG_DRIVER("%s context support initialized\n",
			i915.enable_execlists ? "LR" :
			dev_priv->hw_context_size ? "HW" : "fake");
			 dev_priv->engine[RCS]->context_size ? "logical" :
			 "fake");
	return 0;
}

@@ -882,11 +840,6 @@ int i915_gem_switch_to_kernel_context(struct drm_i915_private *dev_priv)
	return 0;
}

static bool contexts_enabled(struct drm_device *dev)
{
	return i915.enable_execlists || to_i915(dev)->hw_context_size;
}

static bool client_is_banned(struct drm_i915_file_private *file_priv)
{
	return file_priv->context_bans > I915_MAX_CLIENT_CONTEXT_BANS;
@@ -895,12 +848,13 @@ static bool client_is_banned(struct drm_i915_file_private *file_priv)
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
				  struct drm_file *file)
{
	struct drm_i915_private *dev_priv = to_i915(dev);
	struct drm_i915_gem_context_create *args = data;
	struct drm_i915_file_private *file_priv = file->driver_priv;
	struct i915_gem_context *ctx;
	int ret;

	if (!contexts_enabled(dev))
	if (!dev_priv->engine[RCS]->context_size)
		return -ENODEV;

	if (args->pad != 0)
@@ -918,7 +872,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
	if (ret)
		return ret;

	ctx = i915_gem_create_context(to_i915(dev), file_priv);
	ctx = i915_gem_create_context(dev_priv, file_priv);
	mutex_unlock(&dev->struct_mutex);
	if (IS_ERR(ctx))
		return PTR_ERR(ctx);
+1 −2
Original line number Diff line number Diff line
@@ -1051,8 +1051,7 @@ static int guc_ads_create(struct intel_guc *guc)
		dev_priv->engine[RCS]->status_page.ggtt_offset;

	for_each_engine(engine, dev_priv, id)
		blob->ads.eng_state_size[engine->guc_id] =
			intel_lr_context_size(engine);
		blob->ads.eng_state_size[engine->guc_id] = engine->context_size;

	base = guc_ggtt_offset(vma);
	blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
Loading