struct drm_i915_gem_object * i915_gem_alloc_context_obj(struct drm_device *dev, size_t size) { struct drm_i915_gem_object *obj; int ret; obj = i915_gem_alloc_object(dev, size); if (obj == NULL) return ERR_PTR(-ENOMEM); /* * Try to make the context utilize L3 as well as LLC. * * On VLV we don't have L3 controls in the PTEs so we * shouldn't touch the cache level, especially as that * would make the object snooped which might have a * negative performance impact. */ if (INTEL_INFO(dev)->gen >= 7 && !IS_VALLEYVIEW(dev)) { ret = i915_gem_object_set_cache_level(obj, I915_CACHE_L3_LLC); /* Failure shouldn't ever happen this early */ if (WARN_ON(ret)) { drm_gem_object_unreference(&obj->base); return ERR_PTR(ret); } } return obj; }
static int create_hw_context(struct drm_device *dev, struct drm_i915_file_private *file_priv, struct i915_hw_context **ret_ctx) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_context *ctx; int ret, id; ctx = malloc(sizeof(*ctx), DRM_I915_GEM, M_NOWAIT | M_ZERO); if (ctx == NULL) return (-ENOMEM); ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); if (ctx->obj == NULL) { free(ctx, DRM_I915_GEM); DRM_DEBUG_DRIVER("Context object allocated failed\n"); return (-ENOMEM); } if (INTEL_INFO(dev)->gen >= 7) { ret = i915_gem_object_set_cache_level(ctx->obj, I915_CACHE_LLC_MLC); if (ret) goto err_out; } /* The ring associated with the context object is handled by the normal * object tracking code. We give an initial ring value simple to pass an * assertion in the context switch code. */ ctx->ring = &dev_priv->rings[RCS]; /* Default context will never have a file_priv */ if (file_priv == NULL) { *ret_ctx = ctx; return (0); } ctx->file_priv = file_priv; again: id = 0; ret = drm_gem_name_create(&file_priv->context_idr, ctx, &id); if (ret == 0) ctx->id = id; if (ret == -EAGAIN) goto again; else if (ret) goto err_out; *ret_ctx = ctx; return (0); err_out: do_destroy(ctx); return (ret); }
static struct i915_hw_context * create_hw_context(struct drm_device *dev, struct drm_i915_file_private *file_priv) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_context *ctx; int ret; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (ctx == NULL) return ERR_PTR(-ENOMEM); kref_init(&ctx->ref); ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); INIT_LIST_HEAD(&ctx->link); if (ctx->obj == NULL) { kfree(ctx); DRM_DEBUG_DRIVER("Context object allocated failed\n"); return ERR_PTR(-ENOMEM); } if (INTEL_INFO(dev)->gen >= 7) { ret = i915_gem_object_set_cache_level(ctx->obj, I915_CACHE_L3_LLC); /* Failure shouldn't ever happen this early */ if (WARN_ON(ret)) goto err_out; } /* The ring associated with the context object is handled by the normal * object tracking code. We give an initial ring value simple to pass an * assertion in the context switch code. */ ctx->ring = &dev_priv->ring[RCS]; list_add_tail(&ctx->link, &dev_priv->context_list); /* Default context will never have a file_priv */ if (file_priv == NULL) return ctx; ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0, GFP_KERNEL); if (ret < 0) goto err_out; ctx->file_priv = file_priv; ctx->id = ret; /* NB: Mark all slices as needing a remap so that when the context first * loads it will restore whatever remap state already exists. If there * is no remap info, it will be a NOP. */ ctx->remap_slice = (1 << NUM_L3_SLICES(dev)) - 1; return ctx; err_out: i915_gem_context_unreference(ctx); return ERR_PTR(ret); }
static int hang_init(struct hang *h, struct drm_i915_private *i915) { void *vaddr; int err; memset(h, 0, sizeof(*h)); h->i915 = i915; h->ctx = kernel_context(i915); if (IS_ERR(h->ctx)) return PTR_ERR(h->ctx); h->hws = i915_gem_object_create_internal(i915, PAGE_SIZE); if (IS_ERR(h->hws)) { err = PTR_ERR(h->hws); goto err_ctx; } h->obj = i915_gem_object_create_internal(i915, PAGE_SIZE); if (IS_ERR(h->obj)) { err = PTR_ERR(h->obj); goto err_hws; } i915_gem_object_set_cache_level(h->hws, I915_CACHE_LLC); vaddr = i915_gem_object_pin_map(h->hws, I915_MAP_WB); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_obj; } h->seqno = memset(vaddr, 0xff, PAGE_SIZE); vaddr = i915_gem_object_pin_map(h->obj, i915_coherent_map_type(i915)); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_unpin_hws; } h->batch = vaddr; return 0; err_unpin_hws: i915_gem_object_unpin_map(h->hws); err_obj: i915_gem_object_put(h->obj); err_hws: i915_gem_object_put(h->hws); err_ctx: kernel_context_close(h->ctx); return err; }
static struct i915_hw_context * create_hw_context(struct drm_device *dev, struct drm_i915_file_private *file_priv) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_context *ctx; int ret; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (ctx == NULL) return ERR_PTR(-ENOMEM); kref_init(&ctx->ref); ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); if (ctx->obj == NULL) { kfree(ctx); DRM_DEBUG_DRIVER("Context object allocated failed\n"); return ERR_PTR(-ENOMEM); } if (INTEL_INFO(dev)->gen >= 7) { ret = i915_gem_object_set_cache_level(ctx->obj, I915_CACHE_LLC_MLC); /* Failure shouldn't ever happen this early */ if (WARN_ON(ret)) goto err_out; } /* The ring associated with the context object is handled by the normal * object tracking code. We give an initial ring value simple to pass an * assertion in the context switch code. */ ctx->ring = &dev_priv->ring[RCS]; /* Default context will never have a file_priv */ if (file_priv == NULL) return ctx; ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, 0, GFP_KERNEL); if (ret < 0) goto err_out; ctx->file_priv = file_priv; ctx->id = ret; return ctx; err_out: i915_gem_context_unreference(ctx); return ERR_PTR(ret); }
int igt_spinner_init(struct igt_spinner *spin, struct drm_i915_private *i915) { unsigned int mode; void *vaddr; int err; GEM_BUG_ON(INTEL_GEN(i915) < 8); memset(spin, 0, sizeof(*spin)); spin->i915 = i915; spin->hws = i915_gem_object_create_internal(i915, PAGE_SIZE); if (IS_ERR(spin->hws)) { err = PTR_ERR(spin->hws); goto err; } spin->obj = i915_gem_object_create_internal(i915, PAGE_SIZE); if (IS_ERR(spin->obj)) { err = PTR_ERR(spin->obj); goto err_hws; } i915_gem_object_set_cache_level(spin->hws, I915_CACHE_LLC); vaddr = i915_gem_object_pin_map(spin->hws, I915_MAP_WB); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_obj; } spin->seqno = memset(vaddr, 0xff, PAGE_SIZE); mode = i915_coherent_map_type(i915); vaddr = i915_gem_object_pin_map(spin->obj, mode); if (IS_ERR(vaddr)) { err = PTR_ERR(vaddr); goto err_unpin_hws; } spin->batch = vaddr; return 0; err_unpin_hws: i915_gem_object_unpin_map(spin->hws); err_obj: i915_gem_object_put(spin->obj); err_hws: i915_gem_object_put(spin->hws); err: return err; }
static struct drm_i915_gem_object * alloc_context_obj(struct drm_i915_private *dev_priv, u64 size) { struct drm_i915_gem_object *obj; int ret; lockdep_assert_held(&dev_priv->drm.struct_mutex); obj = i915_gem_object_create(dev_priv, size); if (IS_ERR(obj)) return obj; /* * Try to make the context utilize L3 as well as LLC. * * On VLV we don't have L3 controls in the PTEs so we * shouldn't touch the cache level, especially as that * would make the object snooped which might have a * negative performance impact. * * Snooping is required on non-llc platforms in execlist * mode, but since all GGTT accesses use PAT entry 0 we * get snooping anyway regardless of cache_level. * * This is only applicable for Ivy Bridge devices since * later platforms don't have L3 control bits in the PTE. */ if (IS_IVYBRIDGE(dev_priv)) { ret = i915_gem_object_set_cache_level(obj, I915_CACHE_L3_LLC); /* Failure shouldn't ever happen this early */ if (WARN_ON(ret)) { i915_gem_object_put(obj); return ERR_PTR(ret); } } return obj; }
static struct i915_hw_context * create_hw_context(struct drm_device *dev, struct drm_i915_file_private *file_priv) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_context *ctx; int ret, id; ctx = kmalloc(sizeof(*ctx), DRM_I915_GEM, M_WAITOK | M_ZERO); if (ctx == NULL) return ERR_PTR(-ENOMEM); ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); if (ctx->obj == NULL) { kfree(ctx, DRM_I915_GEM); DRM_DEBUG_DRIVER("Context object allocated failed\n"); return ERR_PTR(-ENOMEM); } if (INTEL_INFO(dev)->gen >= 7) { ret = i915_gem_object_set_cache_level(ctx->obj, I915_CACHE_LLC_MLC); if (ret) goto err_out; } /* The ring associated with the context object is handled by the normal * object tracking code. We give an initial ring value simple to pass an * assertion in the context switch code. */ ctx->ring = &dev_priv->ring[RCS]; /* Default context will never have a file_priv */ if (file_priv == NULL) return ctx; ctx->file_priv = file_priv; again: if (idr_pre_get(&file_priv->context_idr, GFP_KERNEL) == 0) { ret = -ENOMEM; DRM_DEBUG_DRIVER("idr allocation failed\n"); goto err_out; } ret = idr_get_new_above(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID + 1, &id); if (ret == 0) ctx->id = id; if (ret == -EAGAIN) goto again; else if (ret) goto err_out; return ctx; err_out: do_destroy(ctx); return ERR_PTR(ret); }
static struct i915_hw_context * create_hw_context(struct drm_device *dev, struct drm_i915_file_private *file_priv) { struct drm_i915_private *dev_priv = dev->dev_private; struct i915_hw_context *ctx; struct i915_ctx_handle *han; int ret; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); if (ctx == NULL) return ERR_PTR(-ENOMEM); ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size); if (ctx->obj == NULL) { kfree(ctx); DRM_DEBUG_DRIVER("Context object allocated failed\n"); return ERR_PTR(-ENOMEM); } if (INTEL_INFO(dev)->gen >= 7) { ret = i915_gem_object_set_cache_level(ctx->obj, I915_CACHE_LLC_MLC); if (ret) goto err_out; } /* The ring associated with the context object is handled by the normal * object tracking code. We give an initial ring value simple to pass an * assertion in the context switch code. */ ctx->ring = &dev_priv->ring[RCS]; /* Default context will never have a file_priv */ if (file_priv == NULL) return ctx; ctx->file_priv = file_priv; han = malloc(sizeof(*han), M_DRM, M_WAITOK | M_CANFAIL | M_ZERO); if (han == NULL) { ret = -ENOMEM; DRM_DEBUG_DRIVER("idr allocation failed\n"); goto err_out; } han->ctx = ctx; again: han->handle = ++file_priv->ctx_id; if (han->handle <= DEFAULT_CONTEXT_ID + 1 || SPLAY_INSERT(i915_ctx_tree, &file_priv->ctx_tree, han)) goto again; ctx->id = han->handle; return ctx; err_out: do_destroy(ctx); return ERR_PTR(ret); }