mirror of
https://github.com/rd-stuffs/msm-4.14.git
synced 2025-02-20 11:45:48 +08:00
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
This commit is contained in:
commit
88b0b92bda
@ -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)
|
|||||||
_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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
|
|
||||||
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 = {
|
|||||||
.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);
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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 {
|
|||||||
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" },
|
||||||
@ -178,6 +178,47 @@ static void intel_gvt_update_vgpu_types(struct intel_gvt *gvt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* intel_gvt_active_vgpu - activate a virtual GPU
|
||||||
|
* @vgpu: virtual GPU
|
||||||
|
*
|
||||||
|
* This function is called when user wants to activate a virtual GPU.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
mutex_lock(&gvt->lock);
|
||||||
|
|
||||||
|
vgpu->active = false;
|
||||||
|
|
||||||
|
if (atomic_read(&vgpu->running_workload_num)) {
|
||||||
|
mutex_unlock(&gvt->lock);
|
||||||
|
intel_gvt_wait_vgpu_idle(vgpu);
|
||||||
|
mutex_lock(&gvt->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
intel_vgpu_stop_schedule(vgpu);
|
||||||
|
|
||||||
|
mutex_unlock(&gvt->lock);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* intel_gvt_destroy_vgpu - destroy a virtual GPU
|
* intel_gvt_destroy_vgpu - destroy a virtual GPU
|
||||||
* @vgpu: virtual GPU
|
* @vgpu: virtual GPU
|
||||||
@ -191,16 +232,9 @@ void intel_gvt_destroy_vgpu(struct intel_vgpu *vgpu)
|
|||||||
|
|
||||||
mutex_lock(&gvt->lock);
|
mutex_lock(&gvt->lock);
|
||||||
|
|
||||||
vgpu->active = false;
|
WARN(vgpu->active, "vGPU is still active!\n");
|
||||||
|
|
||||||
idr_remove(&gvt->vgpu_idr, vgpu->id);
|
idr_remove(&gvt->vgpu_idr, vgpu->id);
|
||||||
|
|
||||||
if (atomic_read(&vgpu->running_workload_num)) {
|
|
||||||
mutex_unlock(&gvt->lock);
|
|
||||||
intel_gvt_wait_vgpu_idle(vgpu);
|
|
||||||
mutex_lock(&gvt->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
intel_vgpu_stop_schedule(vgpu);
|
|
||||||
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,
|
|||||||
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)
|
|||||||
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 {
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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 = {
|
|||||||
.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,
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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)
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user