aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_gem.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem.c')
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c185
1 files changed, 118 insertions, 67 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 818576654092..28b726d07a0c 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -34,10 +34,6 @@
34 34
35#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT)) 35#define I915_GEM_GPU_DOMAINS (~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))
36 36
37static void
38i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
39 uint32_t read_domains,
40 uint32_t write_domain);
41static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj); 37static void i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj);
42static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); 38static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj);
43static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); 39static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj);
@@ -607,8 +603,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
607 case -EAGAIN: 603 case -EAGAIN:
608 return VM_FAULT_OOM; 604 return VM_FAULT_OOM;
609 case -EFAULT: 605 case -EFAULT:
610 case -EBUSY:
611 DRM_ERROR("can't insert pfn?? fault or busy...\n");
612 return VM_FAULT_SIGBUS; 606 return VM_FAULT_SIGBUS;
613 default: 607 default:
614 return VM_FAULT_NOPAGE; 608 return VM_FAULT_NOPAGE;
@@ -684,6 +678,30 @@ out_free_list:
684 return ret; 678 return ret;
685} 679}
686 680
681static void
682i915_gem_free_mmap_offset(struct drm_gem_object *obj)
683{
684 struct drm_device *dev = obj->dev;
685 struct drm_i915_gem_object *obj_priv = obj->driver_private;
686 struct drm_gem_mm *mm = dev->mm_private;
687 struct drm_map_list *list;
688
689 list = &obj->map_list;
690 drm_ht_remove_item(&mm->offset_hash, &list->hash);
691
692 if (list->file_offset_node) {
693 drm_mm_put_block(list->file_offset_node);
694 list->file_offset_node = NULL;
695 }
696
697 if (list->map) {
698 drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER);
699 list->map = NULL;
700 }
701
702 obj_priv->mmap_offset = 0;
703}
704
687/** 705/**
688 * i915_gem_get_gtt_alignment - return required GTT alignment for an object 706 * i915_gem_get_gtt_alignment - return required GTT alignment for an object
689 * @obj: object to check 707 * @obj: object to check
@@ -758,8 +776,11 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data,
758 776
759 if (!obj_priv->mmap_offset) { 777 if (!obj_priv->mmap_offset) {
760 ret = i915_gem_create_mmap_offset(obj); 778 ret = i915_gem_create_mmap_offset(obj);
761 if (ret) 779 if (ret) {
780 drm_gem_object_unreference(obj);
781 mutex_unlock(&dev->struct_mutex);
762 return ret; 782 return ret;
783 }
763 } 784 }
764 785
765 args->offset = obj_priv->mmap_offset; 786 args->offset = obj_priv->mmap_offset;
@@ -1030,6 +1051,9 @@ i915_gem_retire_requests(struct drm_device *dev)
1030 drm_i915_private_t *dev_priv = dev->dev_private; 1051 drm_i915_private_t *dev_priv = dev->dev_private;
1031 uint32_t seqno; 1052 uint32_t seqno;
1032 1053
1054 if (!dev_priv->hw_status_page)
1055 return;
1056
1033 seqno = i915_get_gem_seqno(dev); 1057 seqno = i915_get_gem_seqno(dev);
1034 1058
1035 while (!list_empty(&dev_priv->mm.request_list)) { 1059 while (!list_empty(&dev_priv->mm.request_list)) {
@@ -1996,30 +2020,28 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write)
1996 * drm_agp_chipset_flush 2020 * drm_agp_chipset_flush
1997 */ 2021 */
1998static void 2022static void
1999i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, 2023i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj)
2000 uint32_t read_domains,
2001 uint32_t write_domain)
2002{ 2024{
2003 struct drm_device *dev = obj->dev; 2025 struct drm_device *dev = obj->dev;
2004 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2026 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2005 uint32_t invalidate_domains = 0; 2027 uint32_t invalidate_domains = 0;
2006 uint32_t flush_domains = 0; 2028 uint32_t flush_domains = 0;
2007 2029
2008 BUG_ON(read_domains & I915_GEM_DOMAIN_CPU); 2030 BUG_ON(obj->pending_read_domains & I915_GEM_DOMAIN_CPU);
2009 BUG_ON(write_domain == I915_GEM_DOMAIN_CPU); 2031 BUG_ON(obj->pending_write_domain == I915_GEM_DOMAIN_CPU);
2010 2032
2011#if WATCH_BUF 2033#if WATCH_BUF
2012 DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n", 2034 DRM_INFO("%s: object %p read %08x -> %08x write %08x -> %08x\n",
2013 __func__, obj, 2035 __func__, obj,
2014 obj->read_domains, read_domains, 2036 obj->read_domains, obj->pending_read_domains,
2015 obj->write_domain, write_domain); 2037 obj->write_domain, obj->pending_write_domain);
2016#endif 2038#endif
2017 /* 2039 /*
2018 * If the object isn't moving to a new write domain, 2040 * If the object isn't moving to a new write domain,
2019 * let the object stay in multiple read domains 2041 * let the object stay in multiple read domains
2020 */ 2042 */
2021 if (write_domain == 0) 2043 if (obj->pending_write_domain == 0)
2022 read_domains |= obj->read_domains; 2044 obj->pending_read_domains |= obj->read_domains;
2023 else 2045 else
2024 obj_priv->dirty = 1; 2046 obj_priv->dirty = 1;
2025 2047
@@ -2029,15 +2051,17 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
2029 * any read domains which differ from the old 2051 * any read domains which differ from the old
2030 * write domain 2052 * write domain
2031 */ 2053 */
2032 if (obj->write_domain && obj->write_domain != read_domains) { 2054 if (obj->write_domain &&
2055 obj->write_domain != obj->pending_read_domains) {
2033 flush_domains |= obj->write_domain; 2056 flush_domains |= obj->write_domain;
2034 invalidate_domains |= read_domains & ~obj->write_domain; 2057 invalidate_domains |=
2058 obj->pending_read_domains & ~obj->write_domain;
2035 } 2059 }
2036 /* 2060 /*
2037 * Invalidate any read caches which may have 2061 * Invalidate any read caches which may have
2038 * stale data. That is, any new read domains. 2062 * stale data. That is, any new read domains.
2039 */ 2063 */
2040 invalidate_domains |= read_domains & ~obj->read_domains; 2064 invalidate_domains |= obj->pending_read_domains & ~obj->read_domains;
2041 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) { 2065 if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) {
2042#if WATCH_BUF 2066#if WATCH_BUF
2043 DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n", 2067 DRM_INFO("%s: CPU domain flush %08x invalidate %08x\n",
@@ -2046,9 +2070,15 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj,
2046 i915_gem_clflush_object(obj); 2070 i915_gem_clflush_object(obj);
2047 } 2071 }
2048 2072
2049 if ((write_domain | flush_domains) != 0) 2073 /* The actual obj->write_domain will be updated with
2050 obj->write_domain = write_domain; 2074 * pending_write_domain after we emit the accumulated flush for all
2051 obj->read_domains = read_domains; 2075 * of our domain changes in execbuffers (which clears objects'
2076 * write_domains). So if we have a current write domain that we
2077 * aren't changing, set pending_write_domain to that.
2078 */
2079 if (flush_domains == 0 && obj->pending_write_domain == 0)
2080 obj->pending_write_domain = obj->write_domain;
2081 obj->read_domains = obj->pending_read_domains;
2052 2082
2053 dev->invalidate_domains |= invalidate_domains; 2083 dev->invalidate_domains |= invalidate_domains;
2054 dev->flush_domains |= flush_domains; 2084 dev->flush_domains |= flush_domains;
@@ -2251,6 +2281,8 @@ i915_gem_object_pin_and_relocate(struct drm_gem_object *obj,
2251 (int) reloc.offset, 2281 (int) reloc.offset,
2252 reloc.read_domains, 2282 reloc.read_domains,
2253 reloc.write_domain); 2283 reloc.write_domain);
2284 drm_gem_object_unreference(target_obj);
2285 i915_gem_object_unpin(obj);
2254 return -EINVAL; 2286 return -EINVAL;
2255 } 2287 }
2256 2288
@@ -2480,13 +2512,15 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2480 if (dev_priv->mm.wedged) { 2512 if (dev_priv->mm.wedged) {
2481 DRM_ERROR("Execbuf while wedged\n"); 2513 DRM_ERROR("Execbuf while wedged\n");
2482 mutex_unlock(&dev->struct_mutex); 2514 mutex_unlock(&dev->struct_mutex);
2483 return -EIO; 2515 ret = -EIO;
2516 goto pre_mutex_err;
2484 } 2517 }
2485 2518
2486 if (dev_priv->mm.suspended) { 2519 if (dev_priv->mm.suspended) {
2487 DRM_ERROR("Execbuf while VT-switched.\n"); 2520 DRM_ERROR("Execbuf while VT-switched.\n");
2488 mutex_unlock(&dev->struct_mutex); 2521 mutex_unlock(&dev->struct_mutex);
2489 return -EBUSY; 2522 ret = -EBUSY;
2523 goto pre_mutex_err;
2490 } 2524 }
2491 2525
2492 /* Look up object handles */ 2526 /* Look up object handles */
@@ -2554,9 +2588,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2554 struct drm_gem_object *obj = object_list[i]; 2588 struct drm_gem_object *obj = object_list[i];
2555 2589
2556 /* Compute new gpu domains and update invalidate/flush */ 2590 /* Compute new gpu domains and update invalidate/flush */
2557 i915_gem_object_set_to_gpu_domain(obj, 2591 i915_gem_object_set_to_gpu_domain(obj);
2558 obj->pending_read_domains,
2559 obj->pending_write_domain);
2560 } 2592 }
2561 2593
2562 i915_verify_inactive(dev, __FILE__, __LINE__); 2594 i915_verify_inactive(dev, __FILE__, __LINE__);
@@ -2575,6 +2607,12 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2575 (void)i915_add_request(dev, dev->flush_domains); 2607 (void)i915_add_request(dev, dev->flush_domains);
2576 } 2608 }
2577 2609
2610 for (i = 0; i < args->buffer_count; i++) {
2611 struct drm_gem_object *obj = object_list[i];
2612
2613 obj->write_domain = obj->pending_write_domain;
2614 }
2615
2578 i915_verify_inactive(dev, __FILE__, __LINE__); 2616 i915_verify_inactive(dev, __FILE__, __LINE__);
2579 2617
2580#if WATCH_COHERENCY 2618#if WATCH_COHERENCY
@@ -2632,15 +2670,6 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
2632 2670
2633 i915_verify_inactive(dev, __FILE__, __LINE__); 2671 i915_verify_inactive(dev, __FILE__, __LINE__);
2634 2672
2635 /* Copy the new buffer offsets back to the user's exec list. */
2636 ret = copy_to_user((struct drm_i915_relocation_entry __user *)
2637 (uintptr_t) args->buffers_ptr,
2638 exec_list,
2639 sizeof(*exec_list) * args->buffer_count);
2640 if (ret)
2641 DRM_ERROR("failed to copy %d exec entries "
2642 "back to user (%d)\n",
2643 args->buffer_count, ret);
2644err: 2673err:
2645 for (i = 0; i < pinned; i++) 2674 for (i = 0; i < pinned; i++)
2646 i915_gem_object_unpin(object_list[i]); 2675 i915_gem_object_unpin(object_list[i]);
@@ -2650,6 +2679,18 @@ err:
2650 2679
2651 mutex_unlock(&dev->struct_mutex); 2680 mutex_unlock(&dev->struct_mutex);
2652 2681
2682 if (!ret) {
2683 /* Copy the new buffer offsets back to the user's exec list. */
2684 ret = copy_to_user((struct drm_i915_relocation_entry __user *)
2685 (uintptr_t) args->buffers_ptr,
2686 exec_list,
2687 sizeof(*exec_list) * args->buffer_count);
2688 if (ret)
2689 DRM_ERROR("failed to copy %d exec entries "
2690 "back to user (%d)\n",
2691 args->buffer_count, ret);
2692 }
2693
2653pre_mutex_err: 2694pre_mutex_err:
2654 drm_free(object_list, sizeof(*object_list) * args->buffer_count, 2695 drm_free(object_list, sizeof(*object_list) * args->buffer_count,
2655 DRM_MEM_DRIVER); 2696 DRM_MEM_DRIVER);
@@ -2753,6 +2794,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
2753 if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { 2794 if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) {
2754 DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", 2795 DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n",
2755 args->handle); 2796 args->handle);
2797 drm_gem_object_unreference(obj);
2756 mutex_unlock(&dev->struct_mutex); 2798 mutex_unlock(&dev->struct_mutex);
2757 return -EINVAL; 2799 return -EINVAL;
2758 } 2800 }
@@ -2833,6 +2875,13 @@ i915_gem_busy_ioctl(struct drm_device *dev, void *data,
2833 return -EBADF; 2875 return -EBADF;
2834 } 2876 }
2835 2877
2878 /* Update the active list for the hardware's current position.
2879 * Otherwise this only updates on a delayed timer or when irqs are
2880 * actually unmasked, and our working set ends up being larger than
2881 * required.
2882 */
2883 i915_gem_retire_requests(dev);
2884
2836 obj_priv = obj->driver_private; 2885 obj_priv = obj->driver_private;
2837 /* Don't count being on the flushing list against the object being 2886 /* Don't count being on the flushing list against the object being
2838 * done. Otherwise, a buffer left on the flushing list but not getting 2887 * done. Otherwise, a buffer left on the flushing list but not getting
@@ -2885,9 +2934,6 @@ int i915_gem_init_object(struct drm_gem_object *obj)
2885void i915_gem_free_object(struct drm_gem_object *obj) 2934void i915_gem_free_object(struct drm_gem_object *obj)
2886{ 2935{
2887 struct drm_device *dev = obj->dev; 2936 struct drm_device *dev = obj->dev;
2888 struct drm_gem_mm *mm = dev->mm_private;
2889 struct drm_map_list *list;
2890 struct drm_map *map;
2891 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2937 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2892 2938
2893 while (obj_priv->pin_count > 0) 2939 while (obj_priv->pin_count > 0)
@@ -2898,19 +2944,7 @@ void i915_gem_free_object(struct drm_gem_object *obj)
2898 2944
2899 i915_gem_object_unbind(obj); 2945 i915_gem_object_unbind(obj);
2900 2946
2901 list = &obj->map_list; 2947 i915_gem_free_mmap_offset(obj);
2902 drm_ht_remove_item(&mm->offset_hash, &list->hash);
2903
2904 if (list->file_offset_node) {
2905 drm_mm_put_block(list->file_offset_node);
2906 list->file_offset_node = NULL;
2907 }
2908
2909 map = list->map;
2910 if (map) {
2911 drm_free(map, sizeof(*map), DRM_MEM_DRIVER);
2912 list->map = NULL;
2913 }
2914 2948
2915 drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); 2949 drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
2916 drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); 2950 drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
@@ -2949,7 +2983,7 @@ i915_gem_evict_from_list(struct drm_device *dev, struct list_head *head)
2949 return 0; 2983 return 0;
2950} 2984}
2951 2985
2952static int 2986int
2953i915_gem_idle(struct drm_device *dev) 2987i915_gem_idle(struct drm_device *dev)
2954{ 2988{
2955 drm_i915_private_t *dev_priv = dev->dev_private; 2989 drm_i915_private_t *dev_priv = dev->dev_private;
@@ -3095,6 +3129,7 @@ i915_gem_init_hws(struct drm_device *dev)
3095 if (dev_priv->hw_status_page == NULL) { 3129 if (dev_priv->hw_status_page == NULL) {
3096 DRM_ERROR("Failed to map status page.\n"); 3130 DRM_ERROR("Failed to map status page.\n");
3097 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); 3131 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3132 i915_gem_object_unpin(obj);
3098 drm_gem_object_unreference(obj); 3133 drm_gem_object_unreference(obj);
3099 return -EINVAL; 3134 return -EINVAL;
3100 } 3135 }
@@ -3107,6 +3142,31 @@ i915_gem_init_hws(struct drm_device *dev)
3107 return 0; 3142 return 0;
3108} 3143}
3109 3144
3145static void
3146i915_gem_cleanup_hws(struct drm_device *dev)
3147{
3148 drm_i915_private_t *dev_priv = dev->dev_private;
3149 struct drm_gem_object *obj;
3150 struct drm_i915_gem_object *obj_priv;
3151
3152 if (dev_priv->hws_obj == NULL)
3153 return;
3154
3155 obj = dev_priv->hws_obj;
3156 obj_priv = obj->driver_private;
3157
3158 kunmap(obj_priv->page_list[0]);
3159 i915_gem_object_unpin(obj);
3160 drm_gem_object_unreference(obj);
3161 dev_priv->hws_obj = NULL;
3162
3163 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3164 dev_priv->hw_status_page = NULL;
3165
3166 /* Write high address into HWS_PGA when disabling. */
3167 I915_WRITE(HWS_PGA, 0x1ffff000);
3168}
3169
3110int 3170int
3111i915_gem_init_ringbuffer(struct drm_device *dev) 3171i915_gem_init_ringbuffer(struct drm_device *dev)
3112{ 3172{
@@ -3124,6 +3184,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3124 obj = drm_gem_object_alloc(dev, 128 * 1024); 3184 obj = drm_gem_object_alloc(dev, 128 * 1024);
3125 if (obj == NULL) { 3185 if (obj == NULL) {
3126 DRM_ERROR("Failed to allocate ringbuffer\n"); 3186 DRM_ERROR("Failed to allocate ringbuffer\n");
3187 i915_gem_cleanup_hws(dev);
3127 return -ENOMEM; 3188 return -ENOMEM;
3128 } 3189 }
3129 obj_priv = obj->driver_private; 3190 obj_priv = obj->driver_private;
@@ -3131,6 +3192,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3131 ret = i915_gem_object_pin(obj, 4096); 3192 ret = i915_gem_object_pin(obj, 4096);
3132 if (ret != 0) { 3193 if (ret != 0) {
3133 drm_gem_object_unreference(obj); 3194 drm_gem_object_unreference(obj);
3195 i915_gem_cleanup_hws(dev);
3134 return ret; 3196 return ret;
3135 } 3197 }
3136 3198
@@ -3148,7 +3210,9 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
3148 if (ring->map.handle == NULL) { 3210 if (ring->map.handle == NULL) {
3149 DRM_ERROR("Failed to map ringbuffer.\n"); 3211 DRM_ERROR("Failed to map ringbuffer.\n");
3150 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); 3212 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3213 i915_gem_object_unpin(obj);
3151 drm_gem_object_unreference(obj); 3214 drm_gem_object_unreference(obj);
3215 i915_gem_cleanup_hws(dev);
3152 return -EINVAL; 3216 return -EINVAL;
3153 } 3217 }
3154 ring->ring_obj = obj; 3218 ring->ring_obj = obj;
@@ -3228,20 +3292,7 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev)
3228 dev_priv->ring.ring_obj = NULL; 3292 dev_priv->ring.ring_obj = NULL;
3229 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring)); 3293 memset(&dev_priv->ring, 0, sizeof(dev_priv->ring));
3230 3294
3231 if (dev_priv->hws_obj != NULL) { 3295 i915_gem_cleanup_hws(dev);
3232 struct drm_gem_object *obj = dev_priv->hws_obj;
3233 struct drm_i915_gem_object *obj_priv = obj->driver_private;
3234
3235 kunmap(obj_priv->page_list[0]);
3236 i915_gem_object_unpin(obj);
3237 drm_gem_object_unreference(obj);
3238 dev_priv->hws_obj = NULL;
3239 memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map));
3240 dev_priv->hw_status_page = NULL;
3241
3242 /* Write high address into HWS_PGA when disabling. */
3243 I915_WRITE(HWS_PGA, 0x1ffff000);
3244 }
3245} 3296}
3246 3297
3247int 3298int