Commit 88b0b92b authored by Dave Airlie's avatar Dave Airlie

Merge tag 'drm-intel-fixes-2017-04-12' of...

Merge tag 'drm-intel-fixes-2017-04-12' of git://anongit.freedesktop.org/git/drm-intel into drm-fixes

drm/i915 fixes for v4.11-rc7

one rcu related fix, and a few GVT fixes.

* tag 'drm-intel-fixes-2017-04-12' of git://anongit.freedesktop.org/git/drm-intel:
  drm/i915: Don't call synchronize_rcu_expedited under struct_mutex
  drm/i915: Suspend GuC prior to GPU Reset during GEM suspend
  drm/i915/gvt: set the correct default value of CTX STATUS PTR
  drm/i915/gvt: Fix firmware loading interface for GVT-g golden HW state
  drm/i915: Use a dummy timeline name for a signaled fence
  drm/i915: Ironlake do_idle_maps w/a may be called w/o struct_mutex
  drm/i915/gvt: remove the redundant info NULL check
  drm/i915/gvt: adjust mem size for low resolution type
  drm/i915: Avoid lock dropping between rescheduling
  drm/i915/gvt: exclude cfg space from failsafe mode
  drm/i915/gvt: Activate/de-activate vGPU in mdev ops.
  drm/i915/execlists: Wrap tail pointer after reset tweaking
  drm/i915/perf: remove user triggerable warn
  drm/i915/perf: destroy stream on sample_flags mismatch
  drm/i915: Align "unfenced" tiled access on gen2, early gen3
parents 97d93f35 c053b5a5
...@@ -285,9 +285,6 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset, ...@@ -285,9 +285,6 @@ int intel_vgpu_emulate_cfg_write(struct intel_vgpu *vgpu, unsigned int offset,
{ {
int ret; int ret;
if (vgpu->failsafe)
return 0;
if (WARN_ON(bytes > 4)) if (WARN_ON(bytes > 4))
return -EINVAL; return -EINVAL;
......
...@@ -775,7 +775,8 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id) ...@@ -775,7 +775,8 @@ static void init_vgpu_execlist(struct intel_vgpu *vgpu, int ring_id)
_EL_OFFSET_STATUS_PTR); _EL_OFFSET_STATUS_PTR);
ctx_status_ptr.dw = vgpu_vreg(vgpu, ctx_status_ptr_reg); ctx_status_ptr.dw = vgpu_vreg(vgpu, ctx_status_ptr_reg);
ctx_status_ptr.read_ptr = ctx_status_ptr.write_ptr = 0x7; ctx_status_ptr.read_ptr = 0;
ctx_status_ptr.write_ptr = 0x7;
vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw; vgpu_vreg(vgpu, ctx_status_ptr_reg) = ctx_status_ptr.dw;
} }
......
...@@ -75,11 +75,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt) ...@@ -75,11 +75,11 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
struct gvt_firmware_header *h; struct gvt_firmware_header *h;
void *firmware; void *firmware;
void *p; void *p;
unsigned long size; unsigned long size, crc32_start;
int i; int i;
int ret; int ret;
size = sizeof(*h) + info->mmio_size + info->cfg_space_size - 1; size = sizeof(*h) + info->mmio_size + info->cfg_space_size;
firmware = vzalloc(size); firmware = vzalloc(size);
if (!firmware) if (!firmware)
return -ENOMEM; return -ENOMEM;
...@@ -112,6 +112,9 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt) ...@@ -112,6 +112,9 @@ static int expose_firmware_sysfs(struct intel_gvt *gvt)
memcpy(gvt->firmware.mmio, p, info->mmio_size); memcpy(gvt->firmware.mmio, p, info->mmio_size);
crc32_start = offsetof(struct gvt_firmware_header, crc32) + 4;
h->crc32 = crc32_le(0, firmware + crc32_start, size - crc32_start);
firmware_attr.size = size; firmware_attr.size = size;
firmware_attr.private = firmware; firmware_attr.private = firmware;
...@@ -234,7 +237,7 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt) ...@@ -234,7 +237,7 @@ int intel_gvt_load_firmware(struct intel_gvt *gvt)
firmware->mmio = mem; firmware->mmio = mem;
sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%04x.golden_hw_state", sprintf(path, "%s/vid_0x%04x_did_0x%04x_rid_0x%02x.golden_hw_state",
GVT_FIRMWARE_PATH, pdev->vendor, pdev->device, GVT_FIRMWARE_PATH, pdev->vendor, pdev->device,
pdev->revision); pdev->revision);
......
...@@ -52,6 +52,8 @@ static const struct intel_gvt_ops intel_gvt_ops = { ...@@ -52,6 +52,8 @@ static const struct intel_gvt_ops intel_gvt_ops = {
.vgpu_create = intel_gvt_create_vgpu, .vgpu_create = intel_gvt_create_vgpu,
.vgpu_destroy = intel_gvt_destroy_vgpu, .vgpu_destroy = intel_gvt_destroy_vgpu,
.vgpu_reset = intel_gvt_reset_vgpu, .vgpu_reset = intel_gvt_reset_vgpu,
.vgpu_activate = intel_gvt_activate_vgpu,
.vgpu_deactivate = intel_gvt_deactivate_vgpu,
}; };
/** /**
......
...@@ -382,7 +382,8 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu); ...@@ -382,7 +382,8 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu);
void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr, void intel_gvt_reset_vgpu_locked(struct intel_vgpu *vgpu, bool dmlr,
unsigned int engine_mask); unsigned int engine_mask);
void intel_gvt_reset_vgpu(struct intel_vgpu *vgpu); void intel_gvt_reset_vgpu(struct intel_vgpu *vgpu);
void intel_gvt_activate_vgpu(struct intel_vgpu *vgpu);
void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu);
/* validating GM functions */ /* validating GM functions */
#define vgpu_gmadr_is_aperture(vgpu, gmadr) \ #define vgpu_gmadr_is_aperture(vgpu, gmadr) \
...@@ -449,6 +450,8 @@ struct intel_gvt_ops { ...@@ -449,6 +450,8 @@ struct intel_gvt_ops {
struct intel_vgpu_type *); struct intel_vgpu_type *);
void (*vgpu_destroy)(struct intel_vgpu *); void (*vgpu_destroy)(struct intel_vgpu *);
void (*vgpu_reset)(struct intel_vgpu *); void (*vgpu_reset)(struct intel_vgpu *);
void (*vgpu_activate)(struct intel_vgpu *);
void (*vgpu_deactivate)(struct intel_vgpu *);
}; };
......
...@@ -544,6 +544,8 @@ static int intel_vgpu_open(struct mdev_device *mdev) ...@@ -544,6 +544,8 @@ static int intel_vgpu_open(struct mdev_device *mdev)
if (ret) if (ret)
goto undo_group; goto undo_group;
intel_gvt_ops->vgpu_activate(vgpu);
atomic_set(&vgpu->vdev.released, 0); atomic_set(&vgpu->vdev.released, 0);
return ret; return ret;
...@@ -569,6 +571,8 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu) ...@@ -569,6 +571,8 @@ static void __intel_vgpu_release(struct intel_vgpu *vgpu)
if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1)) if (atomic_cmpxchg(&vgpu->vdev.released, 0, 1))
return; return;
intel_gvt_ops->vgpu_deactivate(vgpu);
ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_IOMMU_NOTIFY, ret = vfio_unregister_notifier(mdev_dev(vgpu->vdev.mdev), VFIO_IOMMU_NOTIFY,
&vgpu->vdev.iommu_notifier); &vgpu->vdev.iommu_notifier);
WARN(ret, "vfio_unregister_notifier for iommu failed: %d\n", ret); WARN(ret, "vfio_unregister_notifier for iommu failed: %d\n", ret);
...@@ -1340,13 +1344,6 @@ static int kvmgt_guest_init(struct mdev_device *mdev) ...@@ -1340,13 +1344,6 @@ static int kvmgt_guest_init(struct mdev_device *mdev)
static bool kvmgt_guest_exit(struct kvmgt_guest_info *info) static bool kvmgt_guest_exit(struct kvmgt_guest_info *info)
{ {
struct intel_vgpu *vgpu = info->vgpu;
if (!info) {
gvt_vgpu_err("kvmgt_guest_info invalid\n");
return false;
}
kvm_page_track_unregister_notifier(info->kvm, &info->track_node); kvm_page_track_unregister_notifier(info->kvm, &info->track_node);
kvm_put_kvm(info->kvm); kvm_put_kvm(info->kvm);
kvmgt_protect_table_destroy(info); kvmgt_protect_table_destroy(info);
......
...@@ -72,7 +72,7 @@ static struct { ...@@ -72,7 +72,7 @@ static struct {
char *name; char *name;
} vgpu_types[] = { } vgpu_types[] = {
/* Fixed vGPU type table */ /* Fixed vGPU type table */
{ MB_TO_BYTES(64), MB_TO_BYTES(512), 4, GVT_EDID_1024_768, "8" }, { MB_TO_BYTES(64), MB_TO_BYTES(384), 4, GVT_EDID_1024_768, "8" },
{ MB_TO_BYTES(128), MB_TO_BYTES(512), 4, GVT_EDID_1920_1200, "4" }, { MB_TO_BYTES(128), MB_TO_BYTES(512), 4, GVT_EDID_1920_1200, "4" },
{ MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, GVT_EDID_1920_1200, "2" }, { MB_TO_BYTES(256), MB_TO_BYTES(1024), 4, GVT_EDID_1920_1200, "2" },
{ MB_TO_BYTES(512), MB_TO_BYTES(2048), 4, GVT_EDID_1920_1200, "1" }, { MB_TO_BYTES(512), MB_TO_BYTES(2048), 4, GVT_EDID_1920_1200, "1" },
...@@ -179,20 +179,34 @@ static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt) ...@@ -179,20 +179,34 @@ static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt)
} }
/** /**
* intel_gvt_destroy_vgpu - destroy a virtual GPU * intel_gvt_active_vgpu - activate a virtual GPU
* @vgpu: virtual GPU * @vgpu: virtual GPU
* *
* This function is called when user wants to destroy a virtual GPU. * This function is called when user wants to activate a virtual GPU.
* *
*/ */
void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) void intel_gvt_activate_vgpu(struct intel_vgpu *vgpu)
{
mutex_lock(&vgpu->gvt->lock);
vgpu->active = true;
mutex_unlock(&vgpu->gvt->lock);
}
/**
* intel_gvt_deactive_vgpu - deactivate a virtual GPU
* @vgpu: virtual GPU
*
* This function is called when user wants to deactivate a virtual GPU.
* All virtual GPU runtime information will be destroyed.
*
*/
void intel_gvt_deactivate_vgpu(struct intel_vgpu *vgpu)
{ {
struct intel_gvt *gvt = vgpu->gvt; struct intel_gvt *gvt = vgpu->gvt;
mutex_lock(&gvt->lock); mutex_lock(&gvt->lock);
vgpu->active = false; vgpu->active = false;
idr_remove(&gvt->vgpu_idr, vgpu->id);
if (atomic_read(&vgpu->running_workload_num)) { if (atomic_read(&vgpu->running_workload_num)) {
mutex_unlock(&gvt->lock); mutex_unlock(&gvt->lock);
...@@ -201,6 +215,26 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu) ...@@ -201,6 +215,26 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
} }
intel_vgpu_stop_schedule(vgpu); intel_vgpu_stop_schedule(vgpu);
mutex_unlock(&gvt->lock);
}
/**
* intel_gvt_destroy_vgpu - destroy a virtual GPU
* @vgpu: virtual GPU
*
* This function is called when user wants to destroy a virtual GPU.
*
*/
void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
{
struct intel_gvt *gvt = vgpu->gvt;
mutex_lock(&gvt->lock);
WARN(vgpu->active, "vGPU is still active!\n");
idr_remove(&gvt->vgpu_idr, vgpu->id);
intel_vgpu_clean_sched_policy(vgpu); intel_vgpu_clean_sched_policy(vgpu);
intel_vgpu_clean_gvt_context(vgpu); intel_vgpu_clean_gvt_context(vgpu);
intel_vgpu_clean_execlist(vgpu); intel_vgpu_clean_execlist(vgpu);
...@@ -277,7 +311,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt, ...@@ -277,7 +311,6 @@ static struct intel_vgpu *__intel_gvt_create_vgpu(struct intel_gvt *gvt,
if (ret) if (ret)
goto out_clean_shadow_ctx; goto out_clean_shadow_ctx;
vgpu->active = true;
mutex_unlock(&gvt->lock); mutex_unlock(&gvt->lock);
return vgpu; return vgpu;
......
...@@ -1434,8 +1434,6 @@ static int i915_drm_suspend(struct drm_device *dev) ...@@ -1434,8 +1434,6 @@ static int i915_drm_suspend(struct drm_device *dev)
goto out; goto out;
} }
intel_guc_suspend(dev_priv);
intel_display_suspend(dev); intel_display_suspend(dev);
intel_dp_mst_suspend(dev); intel_dp_mst_suspend(dev);
......
...@@ -806,6 +806,7 @@ struct intel_csr { ...@@ -806,6 +806,7 @@ struct intel_csr {
func(has_resource_streamer); \ func(has_resource_streamer); \
func(has_runtime_pm); \ func(has_runtime_pm); \
func(has_snoop); \ func(has_snoop); \
func(unfenced_needs_alignment); \
func(cursor_needs_physical); \ func(cursor_needs_physical); \
func(hws_needs_physical); \ func(hws_needs_physical); \
func(overlay_needs_physical); \ func(overlay_needs_physical); \
......
...@@ -4348,6 +4348,8 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv) ...@@ -4348,6 +4348,8 @@ int i915_gem_suspend(struct drm_i915_private *dev_priv)
i915_gem_context_lost(dev_priv); i915_gem_context_lost(dev_priv);
mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->struct_mutex);
intel_guc_suspend(dev_priv);
cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work); cancel_delayed_work_sync(&dev_priv->gpu_error.hangcheck_work);
cancel_delayed_work_sync(&dev_priv->gt.retire_work); cancel_delayed_work_sync(&dev_priv->gt.retire_work);
......
...@@ -888,6 +888,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *engine, ...@@ -888,6 +888,7 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *engine,
struct list_head ordered_vmas; struct list_head ordered_vmas;
struct list_head pinned_vmas; struct list_head pinned_vmas;
bool has_fenced_gpu_access = INTEL_GEN(engine->i915) < 4; bool has_fenced_gpu_access = INTEL_GEN(engine->i915) < 4;
bool needs_unfenced_map = INTEL_INFO(engine->i915)->unfenced_needs_alignment;
int retry; int retry;
vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm; vm = list_first_entry(vmas, struct i915_vma, exec_list)->vm;
...@@ -908,7 +909,8 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *engine, ...@@ -908,7 +909,8 @@ i915_gem_execbuffer_reserve(struct intel_engine_cs *engine,
if (!has_fenced_gpu_access) if (!has_fenced_gpu_access)
entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE; entry->flags &= ~EXEC_OBJECT_NEEDS_FENCE;
need_fence = need_fence =
entry->flags & EXEC_OBJECT_NEEDS_FENCE && (entry->flags & EXEC_OBJECT_NEEDS_FENCE ||
needs_unfenced_map) &&
i915_gem_object_is_tiled(obj); i915_gem_object_is_tiled(obj);
need_mappable = need_fence || need_reloc_mappable(vma); need_mappable = need_fence || need_reloc_mappable(vma);
......
...@@ -2704,7 +2704,7 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj, ...@@ -2704,7 +2704,7 @@ void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
struct i915_ggtt *ggtt = &dev_priv->ggtt; struct i915_ggtt *ggtt = &dev_priv->ggtt;
if (unlikely(ggtt->do_idle_maps)) { if (unlikely(ggtt->do_idle_maps)) {
if (i915_gem_wait_for_idle(dev_priv, I915_WAIT_LOCKED)) { if (i915_gem_wait_for_idle(dev_priv, 0)) {
DRM_ERROR("Failed to wait for idle; VT'd may hang.\n"); DRM_ERROR("Failed to wait for idle; VT'd may hang.\n");
/* Wait a bit, in hopes it avoids the hang */ /* Wait a bit, in hopes it avoids the hang */
udelay(10); udelay(10);
......
...@@ -37,6 +37,17 @@ static const char *i915_fence_get_driver_name(struct dma_fence *fence) ...@@ -37,6 +37,17 @@ static const char *i915_fence_get_driver_name(struct dma_fence *fence)
static const char *i915_fence_get_timeline_name(struct dma_fence *fence) static const char *i915_fence_get_timeline_name(struct dma_fence *fence)
{ {
/* The timeline struct (as part of the ppgtt underneath a context)
* may be freed when the request is no longer in use by the GPU.
* We could extend the life of a context to beyond that of all
* fences, possibly keeping the hw resource around indefinitely,
* or we just give them a false name. Since
* dma_fence_ops.get_timeline_name is a debug feature, the occasional
* lie seems justifiable.
*/
if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
return "signaled";
return to_request(fence)->timeline->common->name; return to_request(fence)->timeline->common->name;
} }
......
...@@ -53,6 +53,17 @@ static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock) ...@@ -53,6 +53,17 @@ static bool i915_gem_shrinker_lock(struct drm_device *dev, bool *unlock)
BUG(); BUG();
} }
static void i915_gem_shrinker_unlock(struct drm_device *dev, bool unlock)
{
if (!unlock)
return;
mutex_unlock(&dev->struct_mutex);
/* expedite the RCU grace period to free some request slabs */
synchronize_rcu_expedited();
}
static bool any_vma_pinned(struct drm_i915_gem_object *obj) static bool any_vma_pinned(struct drm_i915_gem_object *obj)
{ {
struct i915_vma *vma; struct i915_vma *vma;
...@@ -232,11 +243,8 @@ i915_gem_shrink(struct drm_i915_private *dev_priv, ...@@ -232,11 +243,8 @@ i915_gem_shrink(struct drm_i915_private *dev_priv,
intel_runtime_pm_put(dev_priv); intel_runtime_pm_put(dev_priv);
i915_gem_retire_requests(dev_priv); i915_gem_retire_requests(dev_priv);
if (unlock)
mutex_unlock(&dev_priv->drm.struct_mutex);
/* expedite the RCU grace period to free some request slabs */ i915_gem_shrinker_unlock(&dev_priv->drm, unlock);
synchronize_rcu_expedited();
return count; return count;
} }
...@@ -293,8 +301,7 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc) ...@@ -293,8 +301,7 @@ i915_gem_shrinker_count(struct shrinker *shrinker, struct shrink_control *sc)
count += obj->base.size >> PAGE_SHIFT; count += obj->base.size >> PAGE_SHIFT;
} }
if (unlock) i915_gem_shrinker_unlock(dev, unlock);
mutex_unlock(&dev->struct_mutex);
return count; return count;
} }
...@@ -321,8 +328,8 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc) ...@@ -321,8 +328,8 @@ i915_gem_shrinker_scan(struct shrinker *shrinker, struct shrink_control *sc)
sc->nr_to_scan - freed, sc->nr_to_scan - freed,
I915_SHRINK_BOUND | I915_SHRINK_BOUND |
I915_SHRINK_UNBOUND); I915_SHRINK_UNBOUND);
if (unlock)
mutex_unlock(&dev->struct_mutex); i915_gem_shrinker_unlock(dev, unlock);
return freed; return freed;
} }
...@@ -364,8 +371,7 @@ i915_gem_shrinker_unlock_uninterruptible(struct drm_i915_private *dev_priv, ...@@ -364,8 +371,7 @@ i915_gem_shrinker_unlock_uninterruptible(struct drm_i915_private *dev_priv,
struct shrinker_lock_uninterruptible *slu) struct shrinker_lock_uninterruptible *slu)
{ {
dev_priv->mm.interruptible = slu->was_interruptible; dev_priv->mm.interruptible = slu->was_interruptible;
if (slu->unlock) i915_gem_shrinker_unlock(&dev_priv->drm, slu->unlock);
mutex_unlock(&dev_priv->drm.struct_mutex);
} }
static int static int
......
...@@ -60,6 +60,7 @@ ...@@ -60,6 +60,7 @@
.has_overlay = 1, .overlay_needs_physical = 1, \ .has_overlay = 1, .overlay_needs_physical = 1, \
.has_gmch_display = 1, \ .has_gmch_display = 1, \
.hws_needs_physical = 1, \ .hws_needs_physical = 1, \
.unfenced_needs_alignment = 1, \
.ring_mask = RENDER_RING, \ .ring_mask = RENDER_RING, \
GEN_DEFAULT_PIPEOFFSETS, \ GEN_DEFAULT_PIPEOFFSETS, \
CURSOR_OFFSETS CURSOR_OFFSETS
...@@ -101,6 +102,7 @@ static const struct intel_device_info intel_i915g_info = { ...@@ -101,6 +102,7 @@ static const struct intel_device_info intel_i915g_info = {
.platform = INTEL_I915G, .cursor_needs_physical = 1, .platform = INTEL_I915G, .cursor_needs_physical = 1,
.has_overlay = 1, .overlay_needs_physical = 1, .has_overlay = 1, .overlay_needs_physical = 1,
.hws_needs_physical = 1, .hws_needs_physical = 1,
.unfenced_needs_alignment = 1,
}; };
static const struct intel_device_info intel_i915gm_info = { static const struct intel_device_info intel_i915gm_info = {
...@@ -112,6 +114,7 @@ static const struct intel_device_info intel_i915gm_info = { ...@@ -112,6 +114,7 @@ static const struct intel_device_info intel_i915gm_info = {
.supports_tv = 1, .supports_tv = 1,
.has_fbc = 1, .has_fbc = 1,
.hws_needs_physical = 1, .hws_needs_physical = 1,
.unfenced_needs_alignment = 1,
}; };
static const struct intel_device_info intel_i945g_info = { static const struct intel_device_info intel_i945g_info = {
...@@ -120,6 +123,7 @@ static const struct intel_device_info intel_i945g_info = { ...@@ -120,6 +123,7 @@ static const struct intel_device_info intel_i945g_info = {
.has_hotplug = 1, .cursor_needs_physical = 1, .has_hotplug = 1, .cursor_needs_physical = 1,
.has_overlay = 1, .overlay_needs_physical = 1, .has_overlay = 1, .overlay_needs_physical = 1,
.hws_needs_physical = 1, .hws_needs_physical = 1,
.unfenced_needs_alignment = 1,
}; };
static const struct intel_device_info intel_i945gm_info = { static const struct intel_device_info intel_i945gm_info = {
...@@ -130,6 +134,7 @@ static const struct intel_device_info intel_i945gm_info = { ...@@ -130,6 +134,7 @@ static const struct intel_device_info intel_i945gm_info = {
.supports_tv = 1, .supports_tv = 1,
.has_fbc = 1, .has_fbc = 1,
.hws_needs_physical = 1, .hws_needs_physical = 1,
.unfenced_needs_alignment = 1,
}; };
static const struct intel_device_info intel_g33_info = { static const struct intel_device_info intel_g33_info = {
......
...@@ -1705,7 +1705,7 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv, ...@@ -1705,7 +1705,7 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
*/ */
if (WARN_ON(stream->sample_flags != props->sample_flags)) { if (WARN_ON(stream->sample_flags != props->sample_flags)) {
ret = -ENODEV; ret = -ENODEV;
goto err_alloc; goto err_flags;
} }
list_add(&stream->link, &dev_priv->perf.streams); list_add(&stream->link, &dev_priv->perf.streams);
...@@ -1728,6 +1728,7 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv, ...@@ -1728,6 +1728,7 @@ i915_perf_open_ioctl_locked(struct drm_i915_private *dev_priv,
err_open: err_open:
list_del(&stream->link); list_del(&stream->link);
err_flags:
if (stream->ops->destroy) if (stream->ops->destroy)
stream->ops->destroy(stream); stream->ops->destroy(stream);
err_alloc: err_alloc:
...@@ -1793,6 +1794,11 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv, ...@@ -1793,6 +1794,11 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
if (ret) if (ret)
return ret; return ret;
if (id == 0 || id >= DRM_I915_PERF_PROP_MAX) {
DRM_DEBUG("Unknown i915 perf property ID\n");
return -EINVAL;
}
switch ((enum drm_i915_perf_property_id)id) { switch ((enum drm_i915_perf_property_id)id) {
case DRM_I915_PERF_PROP_CTX_HANDLE: case DRM_I915_PERF_PROP_CTX_HANDLE:
props->single_context = 1; props->single_context = 1;
...@@ -1862,9 +1868,8 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv, ...@@ -1862,9 +1868,8 @@ static int read_properties_unlocked(struct drm_i915_private *dev_priv,
props->oa_periodic = true; props->oa_periodic = true;
props->oa_period_exponent = value; props->oa_period_exponent = value;
break; break;
default: case DRM_I915_PERF_PROP_MAX:
MISSING_CASE(id); MISSING_CASE(id);
DRM_DEBUG("Unknown i915 perf property ID\n");
return -EINVAL; return -EINVAL;
} }
......
...@@ -670,15 +670,14 @@ static void execlists_submit_request(struct drm_i915_gem_request *request) ...@@ -670,15 +670,14 @@ static void execlists_submit_request(struct drm_i915_gem_request *request)
static struct intel_engine_cs * static struct intel_engine_cs *
pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked) pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked)
{ {
struct intel_engine_cs *engine; struct intel_engine_cs *engine =
container_of(pt, struct drm_i915_gem_request, priotree)->engine;
GEM_BUG_ON(!locked);
engine = container_of(pt,
struct drm_i915_gem_request,
priotree)->engine;
if (engine != locked) { if (engine != locked) {
if (locked) spin_unlock(&locked->timeline->lock);
spin_unlock_irq(&locked->timeline->lock); spin_lock(&engine->timeline->lock);
spin_lock_irq(&engine->timeline->lock);
} }
return engine; return engine;
...@@ -686,7 +685,7 @@ pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked) ...@@ -686,7 +685,7 @@ pt_lock_engine(struct i915_priotree *pt, struct intel_engine_cs *locked)
static void execlists_schedule(struct drm_i915_gem_request *request, int prio) static void execlists_schedule(struct drm_i915_gem_request *request, int prio)
{ {
struct intel_engine_cs *engine = NULL; struct intel_engine_cs *engine;
struct i915_dependency *dep, *p; struct i915_dependency *dep, *p;
struct i915_dependency stack; struct i915_dependency stack;
LIST_HEAD(dfs); LIST_HEAD(dfs);
...@@ -720,26 +719,23 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) ...@@ -720,26 +719,23 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio)
list_for_each_entry_safe(dep, p, &dfs, dfs_link) { list_for_each_entry_safe(dep, p, &dfs, dfs_link) {
struct i915_priotree *pt = dep->signaler; struct i915_priotree *pt = dep->signaler;
list_for_each_entry(p, &pt->signalers_list, signal_link) /* Within an engine, there can be no cycle, but we may
* refer to the same dependency chain multiple times
* (redundant dependencies are not eliminated) and across
* engines.
*/
list_for_each_entry(p, &pt->signalers_list, signal_link) {
GEM_BUG_ON(p->signaler->priority < pt->priority);
if (prio > READ_ONCE(p->signaler->priority)) if (prio > READ_ONCE(p->signaler->priority))
list_move_tail(&p->dfs_link, &dfs); list_move_tail(&p->dfs_link, &dfs);
}
list_safe_reset_next(dep, p, dfs_link); list_safe_reset_next(dep, p, dfs_link);
if (!RB_EMPTY_NODE(&pt->node))
continue;
engine = pt_lock_engine(pt, engine);
/* If it is not already in the rbtree, we can update the
* priority inplace and skip over it (and its dependencies)
* if it is referenced *again* as we descend the dfs.
*/
if (prio > pt->priority && RB_EMPTY_NODE(&pt->node)) {
pt->priority = prio;
list_del_init(&dep->dfs_link);
}
} }
engine = request->engine;
spin_lock_irq(&engine->timeline->lock);
/* Fifo and depth-first replacement ensure our deps execute before us */ /* Fifo and depth-first replacement ensure our deps execute before us */
list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) { list_for_each_entry_safe_reverse(dep, p, &dfs, dfs_link) {
struct i915_priotree *pt = dep->signaler; struct i915_priotree *pt = dep->signaler;
...@@ -751,16 +747,15 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio) ...@@ -751,16 +747,15 @@ static void execlists_schedule(struct drm_i915_gem_request *request, int prio)
if (prio <= pt->priority) if (prio <= pt->priority)
continue; continue;
GEM_BUG_ON(RB_EMPTY_NODE(&pt->node));
pt->priority = prio; pt->priority = prio;
rb_erase(&pt->node, &engine->execlist_queue); if (!RB_EMPTY_NODE(&pt->node)) {
if (insert_request(pt, &engine->execlist_queue)) rb_erase(&pt->node, &engine->execlist_queue);
engine->execlist_first = &pt->node; if (insert_request(pt, &engine->execlist_queue))
engine->execlist_first = &pt->node;
}
} }
if (engine) spin_unlock_irq(&engine->timeline->lock);
spin_unlock_irq(&engine->timeline->lock);
/* XXX Do we need to preempt to make room for us and our deps? */ /* XXX Do we need to preempt to make room for us and our deps? */
} }
...@@ -1440,7 +1435,9 @@ static void reset_common_ring(struct intel_engine_cs *engine, ...@@ -1440,7 +1435,9 @@ static void reset_common_ring(struct intel_engine_cs *engine,
GEM_BUG_ON(request->ctx != port[0].request->ctx); GEM_BUG_ON(request->ctx != port[0].request->ctx);
/* Reset WaIdleLiteRestore:bdw,skl as well */ /* Reset WaIdleLiteRestore:bdw,skl as well */
request->tail = request->wa_tail - WA_TAIL_DWORDS * sizeof(u32); request->tail =
intel_ring_wrap(request->ring,
request->wa_tail - WA_TAIL_DWORDS*sizeof(u32));
} }
static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req) static int intel_logical_ring_emit_pdps(struct drm_i915_gem_request *req)
......
...@@ -521,11 +521,17 @@ static inline void intel_ring_advance(struct intel_ring *ring) ...@@ -521,11 +521,17 @@ static inline void intel_ring_advance(struct intel_ring *ring)
*/ */
} }
static inline u32
intel_ring_wrap(const struct intel_ring *ring, u32 pos)
{
return pos & (ring->size - 1);
}
static inline u32 intel_ring_offset(struct intel_ring *ring, void *addr) static inline u32 intel_ring_offset(struct intel_ring *ring, void *addr)
{ {
/* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */ /* Don't write ring->size (equivalent to 0) as that hangs some GPUs. */
u32 offset = addr - ring->vaddr; u32 offset = addr - ring->vaddr;
return offset & (ring->size - 1); return intel_ring_wrap(ring, offset);
} }
int __intel_ring_space(int head, int tail, int size); int __intel_ring_space(int head, int tail, int size);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment