Commit 0e5539b9 authored by Daniel Vetter's avatar Daniel Vetter

Merge branch 'topic/ppgtt' into drm-intel-next-queued

Because whatever.*

* This should contain a fairly long list of issues and still
unresolved resgressions, but I didn't really get a vote.
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parents fc2c807b f72d21ed
......@@ -98,7 +98,7 @@ static const char *get_pin_flag(struct drm_i915_gem_object *obj)
{
if (obj->user_pin_count > 0)
return "P";
else if (obj->pin_count > 0)
else if (i915_gem_obj_is_pinned(obj))
return "p";
else
return " ";
......@@ -123,6 +123,8 @@ static void
describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
{
struct i915_vma *vma;
int pin_count = 0;
seq_printf(m, "%pK: %s%s%s %8zdKiB %02x %02x %u %u %u%s%s%s",
&obj->base,
get_pin_flag(obj),
......@@ -139,8 +141,10 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
obj->madv == I915_MADV_DONTNEED ? " purgeable" : "");
if (obj->base.name)
seq_printf(m, " (name: %d)", obj->base.name);
if (obj->pin_count)
seq_printf(m, " (pinned x %d)", obj->pin_count);
list_for_each_entry(vma, &obj->vma_list, vma_link)
if (vma->pin_count > 0)
pin_count++;
seq_printf(m, " (pinned x %d)", pin_count);
if (obj->pin_display)
seq_printf(m, " (display)");
if (obj->fence_reg != I915_FENCE_REG_NONE)
......@@ -447,7 +451,7 @@ static int i915_gem_gtt_info(struct seq_file *m, void *data)
total_obj_size = total_gtt_size = count = 0;
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
if (list == PINNED_LIST && obj->pin_count == 0)
if (list == PINNED_LIST && !i915_gem_obj_is_pinned(obj))
continue;
seq_puts(m, " ");
......@@ -1731,6 +1735,17 @@ static int i915_swizzle_info(struct seq_file *m, void *data)
return 0;
}
static int per_file_ctx(int id, void *ptr, void *data)
{
struct i915_hw_context *ctx = ptr;
struct seq_file *m = data;
struct i915_hw_ppgtt *ppgtt = ctx_to_ppgtt(ctx);
ppgtt->debug_dump(ppgtt, m);
return 0;
}
static void gen8_ppgtt_info(struct seq_file *m, struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
......@@ -1760,6 +1775,7 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_ring_buffer *ring;
struct drm_file *file;
int i;
if (INTEL_INFO(dev)->gen == 6)
......@@ -1778,6 +1794,20 @@ static void gen6_ppgtt_info(struct seq_file *m, struct drm_device *dev)
seq_puts(m, "aliasing PPGTT:\n");
seq_printf(m, "pd gtt offset: 0x%08x\n", ppgtt->pd_offset);
ppgtt->debug_dump(ppgtt, m);
} else
return;
list_for_each_entry_reverse(file, &dev->filelist, lhead) {
struct drm_i915_file_private *file_priv = file->driver_priv;
struct i915_hw_ppgtt *pvt_ppgtt;
pvt_ppgtt = ctx_to_ppgtt(file_priv->private_default_ctx);
seq_printf(m, "proc: %s\n",
get_pid_task(file->pid, PIDTYPE_PID)->comm);
seq_puts(m, " default context:\n");
idr_for_each(&file_priv->context_idr, per_file_ctx, m);
}
seq_printf(m, "ECOCHK: 0x%08x\n", I915_READ(GAM_ECOCHK));
}
......@@ -2927,7 +2957,7 @@ i915_drop_caches_set(void *data, u64 val)
list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
list_for_each_entry_safe(vma, x, &vm->inactive_list,
mm_list) {
if (vma->obj->pin_count)
if (vma->pin_count)
continue;
ret = i915_vma_unbind(vma);
......
......@@ -990,7 +990,7 @@ static int i915_getparam(struct drm_device *dev, void *data,
value = HAS_WT(dev);
break;
case I915_PARAM_HAS_ALIASING_PPGTT:
value = dev_priv->mm.aliasing_ppgtt ? 1 : 0;
value = dev_priv->mm.aliasing_ppgtt || USES_FULL_PPGTT(dev);
break;
case I915_PARAM_HAS_WAIT_TIMEOUT:
value = 1;
......@@ -1374,7 +1374,7 @@ static int i915_load_modeset_init(struct drm_device *dev)
i915_gem_cleanup_ringbuffer(dev);
i915_gem_context_fini(dev);
mutex_unlock(&dev->struct_mutex);
i915_gem_cleanup_aliasing_ppgtt(dev);
WARN_ON(dev_priv->mm.aliasing_ppgtt);
drm_mm_takedown(&dev_priv->gtt.base.mm);
cleanup_power:
intel_display_power_put(dev, POWER_DOMAIN_VGA);
......@@ -1775,8 +1775,8 @@ int i915_driver_unload(struct drm_device *dev)
i915_gem_free_all_phys_object(dev);
i915_gem_cleanup_ringbuffer(dev);
i915_gem_context_fini(dev);
WARN_ON(dev_priv->mm.aliasing_ppgtt);
mutex_unlock(&dev->struct_mutex);
i915_gem_cleanup_aliasing_ppgtt(dev);
i915_gem_cleanup_stolen(dev);
if (!I915_NEED_GFX_HWS(dev))
......
......@@ -113,7 +113,8 @@ MODULE_PARM_DESC(enable_hangcheck,
int i915_enable_ppgtt __read_mostly = -1;
module_param_named(i915_enable_ppgtt, i915_enable_ppgtt, int, 0400);
MODULE_PARM_DESC(i915_enable_ppgtt,
"Enable PPGTT (default: true)");
"Override PPGTT usage. "
"(-1=auto [default], 0=disabled, 1=aliasing, 2=full)");
int i915_enable_psr __read_mostly = 0;
module_param_named(enable_psr, i915_enable_psr, int, 0600);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -36,7 +36,8 @@
static bool
mark_free(struct i915_vma *vma, struct list_head *unwind)
{
if (vma->obj->pin_count)
/* Freeing up memory requires no VMAs are pinned */
if (i915_gem_obj_is_pinned(vma->obj))
return false;
if (WARN_ON(!list_empty(&vma->exec_list)))
......@@ -207,7 +208,7 @@ int i915_gem_evict_vm(struct i915_address_space *vm, bool do_idle)
}
list_for_each_entry_safe(vma, next, &vm->inactive_list, mm_list)
if (vma->obj->pin_count == 0)
if (vma->pin_count == 0)
WARN_ON(i915_vma_unbind(vma));
return 0;
......
This diff is collapsed.
This diff is collapsed.
......@@ -308,7 +308,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data,
return -EINVAL;
}
if (obj->pin_count || obj->framebuffer_references) {
if (i915_gem_obj_is_pinned(obj) || obj->framebuffer_references) {
drm_gem_object_unreference_unlocked(&obj->base);
return -EBUSY;
}
......
......@@ -481,6 +481,7 @@ static void i915_error_state_free(struct kref *error_ref)
static struct drm_i915_error_object *
i915_error_object_create_sized(struct drm_i915_private *dev_priv,
struct drm_i915_gem_object *src,
struct i915_address_space *vm,
const int num_pages)
{
struct drm_i915_error_object *dst;
......@@ -494,7 +495,7 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv,
if (dst == NULL)
return NULL;
reloc_offset = dst->gtt_offset = i915_gem_obj_ggtt_offset(src);
reloc_offset = dst->gtt_offset = i915_gem_obj_offset(src, vm);
for (i = 0; i < num_pages; i++) {
unsigned long flags;
void *d;
......@@ -505,7 +506,8 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv,
local_irq_save(flags);
if (reloc_offset < dev_priv->gtt.mappable_end &&
src->has_global_gtt_mapping) {
src->has_global_gtt_mapping &&
i915_is_ggtt(vm)) {
void __iomem *s;
/* Simply ignore tiling or any overlapping fence.
......@@ -555,8 +557,12 @@ i915_error_object_create_sized(struct drm_i915_private *dev_priv,
kfree(dst);
return NULL;
}
#define i915_error_object_create(dev_priv, src) \
i915_error_object_create_sized((dev_priv), (src), \
#define i915_error_object_create(dev_priv, src, vm) \
i915_error_object_create_sized((dev_priv), (src), (vm), \
(src)->base.size>>PAGE_SHIFT)
#define i915_error_ggtt_object_create(dev_priv, src) \
i915_error_object_create_sized((dev_priv), (src), &(dev_priv)->gtt.base, \
(src)->base.size>>PAGE_SHIFT)
static void capture_bo(struct drm_i915_error_buffer *err,
......@@ -571,7 +577,7 @@ static void capture_bo(struct drm_i915_error_buffer *err,
err->write_domain = obj->base.write_domain;
err->fence_reg = obj->fence_reg;
err->pinned = 0;
if (obj->pin_count > 0)
if (i915_gem_obj_is_pinned(obj))
err->pinned = 1;
if (obj->user_pin_count > 0)
err->pinned = -1;
......@@ -604,7 +610,7 @@ static u32 capture_pinned_bo(struct drm_i915_error_buffer *err,
int i = 0;
list_for_each_entry(obj, head, global_list) {
if (obj->pin_count == 0)
if (!i915_gem_obj_is_pinned(obj))
continue;
capture_bo(err++, obj);
......@@ -648,6 +654,32 @@ static void i915_gem_record_fences(struct drm_device *dev,
}
}
/* This assumes all batchbuffers are executed from the PPGTT. It might have to
* change in the future. */
static bool is_active_vm(struct i915_address_space *vm,
struct intel_ring_buffer *ring)
{
struct drm_device *dev = vm->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct i915_hw_ppgtt *ppgtt;
if (INTEL_INFO(dev)->gen < 7)
return i915_is_ggtt(vm);
/* FIXME: This ignores that the global gtt vm is also on this list. */
ppgtt = container_of(vm, struct i915_hw_ppgtt, base);
if (INTEL_INFO(dev)->gen >= 8) {
u64 pdp0 = (u64)I915_READ(GEN8_RING_PDP_UDW(ring, 0)) << 32;
pdp0 |= I915_READ(GEN8_RING_PDP_LDW(ring, 0));
return pdp0 == ppgtt->pd_dma_addr[0];
} else {
u32 pp_db;
pp_db = I915_READ(RING_PP_DIR_BASE(ring));
return (pp_db >> 10) == ppgtt->pd_offset;
}
}
static struct drm_i915_error_object *
i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
struct intel_ring_buffer *ring)
......@@ -655,6 +687,7 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
struct i915_address_space *vm;
struct i915_vma *vma;
struct drm_i915_gem_object *obj;
bool found_active = false;
u32 seqno;
if (!ring->get_seqno)
......@@ -669,11 +702,16 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
obj = ring->scratch.obj;
if (acthd >= i915_gem_obj_ggtt_offset(obj) &&
acthd < i915_gem_obj_ggtt_offset(obj) + obj->base.size)
return i915_error_object_create(dev_priv, obj);
return i915_error_ggtt_object_create(dev_priv, obj);
}
seqno = ring->get_seqno(ring, false);
list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
if (!is_active_vm(vm, ring))
continue;
found_active = true;
list_for_each_entry(vma, &vm->active_list, mm_list) {
obj = vma->obj;
if (obj->ring != ring)
......@@ -688,10 +726,11 @@ i915_error_first_batchbuffer(struct drm_i915_private *dev_priv,
/* We need to copy these to an anonymous buffer as the simplest
* method to avoid being overwritten by userspace.
*/
return i915_error_object_create(dev_priv, obj);
return i915_error_object_create(dev_priv, obj, vm);
}
}
WARN_ON(!found_active);
return NULL;
}
......@@ -765,7 +804,9 @@ static void i915_gem_record_active_context(struct intel_ring_buffer *ring,
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list) {
if ((error->ccid & PAGE_MASK) == i915_gem_obj_ggtt_offset(obj)) {
ering->ctx = i915_error_object_create_sized(dev_priv,
obj, 1);
obj,
&dev_priv->gtt.base,
1);
break;
}
}
......@@ -786,7 +827,7 @@ static void i915_gem_record_rings(struct drm_device *dev,
i915_error_first_batchbuffer(dev_priv, ring);
error->ring[i].ringbuffer =
i915_error_object_create(dev_priv, ring->obj);
i915_error_ggtt_object_create(dev_priv, ring->obj);
i915_gem_record_active_context(ring, error, &error->ring[i]);
......@@ -834,7 +875,7 @@ static void i915_gem_capture_vm(struct drm_i915_private *dev_priv,
i++;
error->active_bo_count[ndx] = i;
list_for_each_entry(obj, &dev_priv->mm.bound_list, global_list)
if (obj->pin_count)
if (i915_gem_obj_is_pinned(obj))
i++;
error->pinned_bo_count[ndx] = i - error->active_bo_count[ndx];
......@@ -868,11 +909,6 @@ static void i915_gem_capture_buffers(struct drm_i915_private *dev_priv,
list_for_each_entry(vm, &dev_priv->vm_list, global_link)
cnt++;
if (WARN(cnt > 1, "Multiple VMs not yet supported\n"))
cnt = 1;
vm = &dev_priv->gtt.base;
error->active_bo = kcalloc(cnt, sizeof(*error->active_bo), GFP_ATOMIC);
error->pinned_bo = kcalloc(cnt, sizeof(*error->pinned_bo), GFP_ATOMIC);
error->active_bo_count = kcalloc(cnt, sizeof(*error->active_bo_count),
......
......@@ -104,7 +104,7 @@ static int intelfb_alloc(struct drm_fb_helper *helper,
return 0;
out_unpin:
i915_gem_object_unpin(obj);
i915_gem_object_ggtt_unpin(obj);
out_unref:
drm_gem_object_unreference(&obj->base);
out:
......@@ -208,7 +208,7 @@ static int intelfb_create(struct drm_fb_helper *helper,
return 0;
out_unpin:
i915_gem_object_unpin(obj);
i915_gem_object_ggtt_unpin(obj);
drm_gem_object_unreference(&obj->base);
out_unlock:
mutex_unlock(&dev->struct_mutex);
......
......@@ -293,7 +293,7 @@ static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
{
struct drm_i915_gem_object *obj = overlay->old_vid_bo;
i915_gem_object_unpin(obj);
i915_gem_object_ggtt_unpin(obj);
drm_gem_object_unreference(&obj->base);
overlay->old_vid_bo = NULL;
......@@ -306,7 +306,7 @@ static void intel_overlay_off_tail(struct intel_overlay *overlay)
/* never have the overlay hw on without showing a frame */
BUG_ON(!overlay->vid_bo);
i915_gem_object_unpin(obj);
i915_gem_object_ggtt_unpin(obj);
drm_gem_object_unreference(&obj->base);
overlay->vid_bo = NULL;
......@@ -782,7 +782,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay,
return 0;
out_unpin:
i915_gem_object_unpin(new_bo);
i915_gem_object_ggtt_unpin(new_bo);
return ret;
}
......@@ -1386,7 +1386,7 @@ void intel_setup_overlay(struct drm_device *dev)
out_unpin_bo:
if (!OVERLAY_NEEDS_PHYSICAL(dev))
i915_gem_object_unpin(reg_bo);
i915_gem_object_ggtt_unpin(reg_bo);
out_free_bo:
drm_gem_object_unreference(&reg_bo->base);
out_free:
......
......@@ -2753,7 +2753,7 @@ intel_alloc_context_page(struct drm_device *dev)
return ctx;
err_unpin:
i915_gem_object_unpin(ctx);
i915_gem_object_ggtt_unpin(ctx);
err_unref:
drm_gem_object_unreference(&ctx->base);
return NULL;
......@@ -3625,13 +3625,13 @@ void ironlake_teardown_rc6(struct drm_device *dev)
struct drm_i915_private *dev_priv = dev->dev_private;
if (dev_priv->ips.renderctx) {
i915_gem_object_unpin(dev_priv->ips.renderctx);
i915_gem_object_ggtt_unpin(dev_priv->ips.renderctx);
drm_gem_object_unreference(&dev_priv->ips.renderctx->base);
dev_priv->ips.renderctx = NULL;
}
if (dev_priv->ips.pwrctx) {
i915_gem_object_unpin(dev_priv->ips.pwrctx);
i915_gem_object_ggtt_unpin(dev_priv->ips.pwrctx);
drm_gem_object_unreference(&dev_priv->ips.pwrctx->base);
dev_priv->ips.pwrctx = NULL;
}
......
......@@ -549,7 +549,7 @@ init_pipe_control(struct intel_ring_buffer *ring)
return 0;
err_unpin:
i915_gem_object_unpin(ring->scratch.obj);
i915_gem_object_ggtt_unpin(ring->scratch.obj);
err_unref:
drm_gem_object_unreference(&ring->scratch.obj->base);
err:
......@@ -625,7 +625,7 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring)
if (INTEL_INFO(dev)->gen >= 5) {
kunmap(sg_page(ring->scratch.obj->pages->sgl));
i915_gem_object_unpin(ring->scratch.obj);
i915_gem_object_ggtt_unpin(ring->scratch.obj);
}
drm_gem_object_unreference(&ring->scratch.obj->base);
......@@ -1253,7 +1253,7 @@ static void cleanup_status_page(struct intel_ring_buffer *ring)
return;
kunmap(sg_page(obj->pages->sgl));
i915_gem_object_unpin(obj);
i915_gem_object_ggtt_unpin(obj);
drm_gem_object_unreference(&obj->base);
ring->status_page.obj = NULL;
}
......@@ -1293,7 +1293,7 @@ static int init_status_page(struct intel_ring_buffer *ring)
return 0;
err_unpin:
i915_gem_object_unpin(obj);
i915_gem_object_ggtt_unpin(obj);
err_unref:
drm_gem_object_unreference(&obj->base);
err:
......@@ -1390,7 +1390,7 @@ static int intel_init_ring_buffer(struct drm_device *dev,
err_unmap:
iounmap(ring->virtual_start);
err_unpin:
i915_gem_object_unpin(obj);
i915_gem_object_ggtt_unpin(obj);
err_unref:
drm_gem_object_unreference(&obj->base);
ring->obj = NULL;
......@@ -1418,7 +1418,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring)
iounmap(ring->virtual_start);
i915_gem_object_unpin(ring->obj);
i915_gem_object_ggtt_unpin(ring->obj);
drm_gem_object_unreference(&ring->obj->base);
ring->obj = NULL;
ring->preallocated_lazy_request = NULL;
......
......@@ -852,6 +852,7 @@ int i915_get_reset_stats_ioctl(struct drm_device *dev,
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_reset_stats *args = data;
struct i915_ctx_hang_stats *hs;
struct i915_hw_context *ctx;
int ret;
if (args->flags || args->pad)
......@@ -864,11 +865,12 @@ int i915_get_reset_stats_ioctl(struct drm_device *dev,
if (ret)
return ret;
hs = i915_gem_context_get_hang_stats(dev, file, args->ctx_id);
if (IS_ERR(hs)) {
ctx = i915_gem_context_get(file->driver_priv, args->ctx_id);
if (IS_ERR(ctx)) {
mutex_unlock(&dev->struct_mutex);
return PTR_ERR(hs);
return PTR_ERR(ctx);
}
hs = &ctx->hang_stats;
if (capable(CAP_SYS_ADMIN))
args->reset_count = i915_reset_count(&dev_priv->gpu_error);
......
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