Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-intel-fixes-2013-12-11' of git://people.freedesktop.org/~danvet/drm-intel into drm-fixes

Just a bunch of regression fixes plus a few patches for long-standing
issues in gem corner-cases that we've hunted down in the past weeks. Since
apparently people hit those in the wild (and we also have nice igts for
them) I've opted for -fixes and cc: stable.

There's 1-2 things oustanding on top of this where I'm still waiting on
confirmation from testing, but nothing really scary.

* tag 'drm-intel-fixes-2013-12-11' of git://people.freedesktop.org/~danvet/drm-intel:
drm/i915: don't update the dri1 breadcrumb with modesetting
drm/i915: Repeat eviction search after idling the GPU
drm/i915: Fix use-after-free in do_switch
drm/i915: fix pm init ordering
drm/i915: Hold mutex across i915_gem_release
drm/i915: Skip clock checks on BDW
drm/i915: Do not clobber config status after a forced restore of hw state
drm/i915: Take modeset locks around intel_modeset_setup_hw_state()

+50 -22
+11 -9
drivers/gpu/drm/i915/i915_dma.c
··· 83 83 drm_i915_private_t *dev_priv = dev->dev_private; 84 84 struct drm_i915_master_private *master_priv; 85 85 86 + /* 87 + * The dri breadcrumb update races against the drm master disappearing. 88 + * Instead of trying to fix this (this is by far not the only ums issue) 89 + * just don't do the update in kms mode. 90 + */ 91 + if (drm_core_check_feature(dev, DRIVER_MODESET)) 92 + return; 93 + 86 94 if (dev->primary->master) { 87 95 master_priv = dev->primary->master->driver_priv; 88 96 if (master_priv->sarea_priv) ··· 1498 1490 spin_lock_init(&dev_priv->uncore.lock); 1499 1491 spin_lock_init(&dev_priv->mm.object_stat_lock); 1500 1492 mutex_init(&dev_priv->dpio_lock); 1501 - mutex_init(&dev_priv->rps.hw_lock); 1502 1493 mutex_init(&dev_priv->modeset_restore_lock); 1503 1494 1504 - mutex_init(&dev_priv->pc8.lock); 1505 - dev_priv->pc8.requirements_met = false; 1506 - dev_priv->pc8.gpu_idle = false; 1507 - dev_priv->pc8.irqs_disabled = false; 1508 - dev_priv->pc8.enabled = false; 1509 - dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */ 1510 - INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); 1495 + intel_pm_setup(dev); 1511 1496 1512 1497 intel_display_crc_init(dev); 1513 1498 ··· 1604 1603 } 1605 1604 1606 1605 intel_irq_init(dev); 1607 - intel_pm_init(dev); 1608 1606 intel_uncore_sanitize(dev); 1609 1607 1610 1608 /* Try to make sure MCHBAR is enabled before poking at it */ ··· 1848 1848 1849 1849 void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv) 1850 1850 { 1851 + mutex_lock(&dev->struct_mutex); 1851 1852 i915_gem_context_close(dev, file_priv); 1852 1853 i915_gem_release(dev, file_priv); 1854 + mutex_unlock(&dev->struct_mutex); 1853 1855 } 1854 1856 1855 1857 void i915_driver_postclose(struct drm_device *dev, struct drm_file *file)
+1
drivers/gpu/drm/i915/i915_drv.c
··· 651 651 intel_modeset_init_hw(dev); 652 652 653 653 drm_modeset_lock_all(dev); 654 + drm_mode_config_reset(dev); 654 655 intel_modeset_setup_hw_state(dev, true); 655 656 drm_modeset_unlock_all(dev); 656 657
-2
drivers/gpu/drm/i915/i915_drv.h
··· 1906 1906 void i915_handle_error(struct drm_device *dev, bool wedged); 1907 1907 1908 1908 extern void intel_irq_init(struct drm_device *dev); 1909 - extern void intel_pm_init(struct drm_device *dev); 1910 1909 extern void intel_hpd_init(struct drm_device *dev); 1911 - extern void intel_pm_init(struct drm_device *dev); 1912 1910 1913 1911 extern void intel_uncore_sanitize(struct drm_device *dev); 1914 1912 extern void intel_uncore_early_sanitize(struct drm_device *dev);
+12 -4
drivers/gpu/drm/i915/i915_gem_context.c
··· 347 347 { 348 348 struct drm_i915_file_private *file_priv = file->driver_priv; 349 349 350 - mutex_lock(&dev->struct_mutex); 351 350 idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL); 352 351 idr_destroy(&file_priv->context_idr); 353 - mutex_unlock(&dev->struct_mutex); 354 352 } 355 353 356 354 static struct i915_hw_context * ··· 421 423 if (ret) 422 424 return ret; 423 425 424 - /* Clear this page out of any CPU caches for coherent swap-in/out. Note 426 + /* 427 + * Pin can switch back to the default context if we end up calling into 428 + * evict_everything - as a last ditch gtt defrag effort that also 429 + * switches to the default context. Hence we need to reload from here. 430 + */ 431 + from = ring->last_context; 432 + 433 + /* 434 + * Clear this page out of any CPU caches for coherent swap-in/out. Note 425 435 * that thanks to write = false in this call and us not setting any gpu 426 436 * write domains when putting a context object onto the active list 427 437 * (when switching away from it), this won't block. 428 - * XXX: We need a real interface to do this instead of trickery. */ 438 + * 439 + * XXX: We need a real interface to do this instead of trickery. 440 + */ 429 441 ret = i915_gem_object_set_to_gtt_domain(to->obj, false); 430 442 if (ret) { 431 443 i915_gem_object_unpin(to->obj);
+11 -3
drivers/gpu/drm/i915/i915_gem_evict.c
··· 88 88 } else 89 89 drm_mm_init_scan(&vm->mm, min_size, alignment, cache_level); 90 90 91 + search_again: 91 92 /* First see if there is a large enough contiguous idle region... */ 92 93 list_for_each_entry(vma, &vm->inactive_list, mm_list) { 93 94 if (mark_free(vma, &unwind_list)) ··· 116 115 list_del_init(&vma->exec_list); 117 116 } 118 117 119 - /* We expect the caller to unpin, evict all and try again, or give up. 120 - * So calling i915_gem_evict_vm() is unnecessary. 118 + /* Can we unpin some objects such as idle hw contents, 119 + * or pending flips? 121 120 */ 122 - return -ENOSPC; 121 + ret = nonblocking ? -ENOSPC : i915_gpu_idle(dev); 122 + if (ret) 123 + return ret; 124 + 125 + /* Only idle the GPU and repeat the search once */ 126 + i915_gem_retire_requests(dev); 127 + nonblocking = true; 128 + goto search_again; 123 129 124 130 found: 125 131 /* drm_mm doesn't allow any other other operations while
+4 -3
drivers/gpu/drm/i915/intel_display.c
··· 9135 9135 if (IS_G4X(dev) || INTEL_INFO(dev)->gen >= 5) 9136 9136 PIPE_CONF_CHECK_I(pipe_bpp); 9137 9137 9138 - if (!IS_HASWELL(dev)) { 9138 + if (!HAS_DDI(dev)) { 9139 9139 PIPE_CONF_CHECK_CLOCK_FUZZY(adjusted_mode.crtc_clock); 9140 9140 PIPE_CONF_CHECK_CLOCK_FUZZY(port_clock); 9141 9141 } ··· 11036 11036 } 11037 11037 11038 11038 intel_modeset_check_state(dev); 11039 - 11040 - drm_mode_config_reset(dev); 11041 11039 } 11042 11040 11043 11041 void intel_modeset_gem_init(struct drm_device *dev) ··· 11044 11046 11045 11047 intel_setup_overlay(dev); 11046 11048 11049 + drm_modeset_lock_all(dev); 11050 + drm_mode_config_reset(dev); 11047 11051 intel_modeset_setup_hw_state(dev, false); 11052 + drm_modeset_unlock_all(dev); 11048 11053 } 11049 11054 11050 11055 void intel_modeset_cleanup(struct drm_device *dev)
+1
drivers/gpu/drm/i915/intel_drv.h
··· 821 821 uint32_t sprite_width, int pixel_size, 822 822 bool enabled, bool scaled); 823 823 void intel_init_pm(struct drm_device *dev); 824 + void intel_pm_setup(struct drm_device *dev); 824 825 bool intel_fbc_enabled(struct drm_device *dev); 825 826 void intel_update_fbc(struct drm_device *dev); 826 827 void intel_gpu_ips_init(struct drm_i915_private *dev_priv);
+10 -1
drivers/gpu/drm/i915/intel_pm.c
··· 6146 6146 return val; 6147 6147 } 6148 6148 6149 - void intel_pm_init(struct drm_device *dev) 6149 + void intel_pm_setup(struct drm_device *dev) 6150 6150 { 6151 6151 struct drm_i915_private *dev_priv = dev->dev_private; 6152 6152 6153 + mutex_init(&dev_priv->rps.hw_lock); 6154 + 6155 + mutex_init(&dev_priv->pc8.lock); 6156 + dev_priv->pc8.requirements_met = false; 6157 + dev_priv->pc8.gpu_idle = false; 6158 + dev_priv->pc8.irqs_disabled = false; 6159 + dev_priv->pc8.enabled = false; 6160 + dev_priv->pc8.disable_count = 2; /* requirements_met + gpu_idle */ 6161 + INIT_DELAYED_WORK(&dev_priv->pc8.enable_work, hsw_enable_pc8_work); 6153 6162 INIT_DELAYED_WORK(&dev_priv->rps.delayed_resume_work, 6154 6163 intel_gen6_powersave_work); 6155 6164 }