diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem.c | 81 | ||||
-rw-r--r-- | include/drm/i915_drm.h | 18 |
4 files changed, 99 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f47adb4aa59a..250999cdf814 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1616,6 +1616,7 @@ struct drm_ioctl_desc i915_ioctls[] = { | |||
1616 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), | 1616 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_TILING, i915_gem_get_tiling, 0), |
1617 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), | 1617 | DRM_IOCTL_DEF(DRM_I915_GEM_GET_APERTURE, i915_gem_get_aperture_ioctl, 0), |
1618 | DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0), | 1618 | DRM_IOCTL_DEF(DRM_I915_GET_PIPE_FROM_CRTC_ID, intel_get_pipe_from_crtc_id, 0), |
1619 | DRM_IOCTL_DEF(DRM_I915_GEM_MADVISE, i915_gem_madvise_ioctl, 0), | ||
1619 | }; | 1620 | }; |
1620 | 1621 | ||
1621 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); | 1622 | int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index bbcf5fc72666..2f89c2136be9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -566,6 +566,11 @@ struct drm_i915_gem_object { | |||
566 | * in an execbuffer object list. | 566 | * in an execbuffer object list. |
567 | */ | 567 | */ |
568 | int in_execbuffer; | 568 | int in_execbuffer; |
569 | |||
570 | /** | ||
571 | * Advice: are the backing pages purgeable? | ||
572 | */ | ||
573 | int madv; | ||
569 | }; | 574 | }; |
570 | 575 | ||
571 | /** | 576 | /** |
@@ -705,6 +710,8 @@ int i915_gem_busy_ioctl(struct drm_device *dev, void *data, | |||
705 | struct drm_file *file_priv); | 710 | struct drm_file *file_priv); |
706 | int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, | 711 | int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, |
707 | struct drm_file *file_priv); | 712 | struct drm_file *file_priv); |
713 | int i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | ||
714 | struct drm_file *file_priv); | ||
708 | int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, | 715 | int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, |
709 | struct drm_file *file_priv); | 716 | struct drm_file *file_priv); |
710 | int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, | 717 | int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2fff2e0a976e..2ab30f251943 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1436,13 +1436,21 @@ i915_gem_object_put_pages(struct drm_gem_object *obj) | |||
1436 | if (obj_priv->tiling_mode != I915_TILING_NONE) | 1436 | if (obj_priv->tiling_mode != I915_TILING_NONE) |
1437 | i915_gem_object_save_bit_17_swizzle(obj); | 1437 | i915_gem_object_save_bit_17_swizzle(obj); |
1438 | 1438 | ||
1439 | for (i = 0; i < page_count; i++) | 1439 | if (obj_priv->madv == I915_MADV_DONTNEED) |
1440 | if (obj_priv->pages[i] != NULL) { | 1440 | obj_priv->dirty = 0; |
1441 | if (obj_priv->dirty) | 1441 | |
1442 | set_page_dirty(obj_priv->pages[i]); | 1442 | for (i = 0; i < page_count; i++) { |
1443 | mark_page_accessed(obj_priv->pages[i]); | 1443 | if (obj_priv->pages[i] == NULL) |
1444 | page_cache_release(obj_priv->pages[i]); | 1444 | break; |
1445 | } | 1445 | |
1446 | if (obj_priv->dirty) | ||
1447 | set_page_dirty(obj_priv->pages[i]); | ||
1448 | |||
1449 | if (obj_priv->madv == I915_MADV_WILLNEED) | ||
1450 | mark_page_accessed(obj_priv->pages[i]); | ||
1451 | |||
1452 | page_cache_release(obj_priv->pages[i]); | ||
1453 | } | ||
1446 | obj_priv->dirty = 0; | 1454 | obj_priv->dirty = 0; |
1447 | 1455 | ||
1448 | drm_free_large(obj_priv->pages); | 1456 | drm_free_large(obj_priv->pages); |
@@ -2412,6 +2420,12 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) | |||
2412 | 2420 | ||
2413 | if (dev_priv->mm.suspended) | 2421 | if (dev_priv->mm.suspended) |
2414 | return -EBUSY; | 2422 | return -EBUSY; |
2423 | |||
2424 | if (obj_priv->madv == I915_MADV_DONTNEED) { | ||
2425 | DRM_ERROR("Attempting to bind a purgeable object\n"); | ||
2426 | return -EINVAL; | ||
2427 | } | ||
2428 | |||
2415 | if (alignment == 0) | 2429 | if (alignment == 0) |
2416 | alignment = i915_gem_get_gtt_alignment(obj); | 2430 | alignment = i915_gem_get_gtt_alignment(obj); |
2417 | if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { | 2431 | if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { |
@@ -3679,6 +3693,13 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, | |||
3679 | } | 3693 | } |
3680 | obj_priv = obj->driver_private; | 3694 | obj_priv = obj->driver_private; |
3681 | 3695 | ||
3696 | if (obj_priv->madv == I915_MADV_DONTNEED) { | ||
3697 | DRM_ERROR("Attempting to pin a I915_MADV_DONTNEED buffer\n"); | ||
3698 | drm_gem_object_unreference(obj); | ||
3699 | mutex_unlock(&dev->struct_mutex); | ||
3700 | return -EINVAL; | ||
3701 | } | ||
3702 | |||
3682 | if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { | 3703 | if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { |
3683 | DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", | 3704 | DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", |
3684 | args->handle); | 3705 | args->handle); |
@@ -3791,6 +3812,49 @@ i915_gem_throttle_ioctl(struct drm_device *dev, void *data, | |||
3791 | return i915_gem_ring_throttle(dev, file_priv); | 3812 | return i915_gem_ring_throttle(dev, file_priv); |
3792 | } | 3813 | } |
3793 | 3814 | ||
3815 | int | ||
3816 | i915_gem_madvise_ioctl(struct drm_device *dev, void *data, | ||
3817 | struct drm_file *file_priv) | ||
3818 | { | ||
3819 | struct drm_i915_gem_madvise *args = data; | ||
3820 | struct drm_gem_object *obj; | ||
3821 | struct drm_i915_gem_object *obj_priv; | ||
3822 | |||
3823 | switch (args->madv) { | ||
3824 | case I915_MADV_DONTNEED: | ||
3825 | case I915_MADV_WILLNEED: | ||
3826 | break; | ||
3827 | default: | ||
3828 | return -EINVAL; | ||
3829 | } | ||
3830 | |||
3831 | obj = drm_gem_object_lookup(dev, file_priv, args->handle); | ||
3832 | if (obj == NULL) { | ||
3833 | DRM_ERROR("Bad handle in i915_gem_madvise_ioctl(): %d\n", | ||
3834 | args->handle); | ||
3835 | return -EBADF; | ||
3836 | } | ||
3837 | |||
3838 | mutex_lock(&dev->struct_mutex); | ||
3839 | obj_priv = obj->driver_private; | ||
3840 | |||
3841 | if (obj_priv->pin_count) { | ||
3842 | drm_gem_object_unreference(obj); | ||
3843 | mutex_unlock(&dev->struct_mutex); | ||
3844 | |||
3845 | DRM_ERROR("Attempted i915_gem_madvise_ioctl() on a pinned object\n"); | ||
3846 | return -EINVAL; | ||
3847 | } | ||
3848 | |||
3849 | obj_priv->madv = args->madv; | ||
3850 | args->retained = obj_priv->gtt_space != NULL; | ||
3851 | |||
3852 | drm_gem_object_unreference(obj); | ||
3853 | mutex_unlock(&dev->struct_mutex); | ||
3854 | |||
3855 | return 0; | ||
3856 | } | ||
3857 | |||
3794 | int i915_gem_init_object(struct drm_gem_object *obj) | 3858 | int i915_gem_init_object(struct drm_gem_object *obj) |
3795 | { | 3859 | { |
3796 | struct drm_i915_gem_object *obj_priv; | 3860 | struct drm_i915_gem_object *obj_priv; |
@@ -3815,6 +3879,7 @@ int i915_gem_init_object(struct drm_gem_object *obj) | |||
3815 | obj_priv->fence_reg = I915_FENCE_REG_NONE; | 3879 | obj_priv->fence_reg = I915_FENCE_REG_NONE; |
3816 | INIT_LIST_HEAD(&obj_priv->list); | 3880 | INIT_LIST_HEAD(&obj_priv->list); |
3817 | INIT_LIST_HEAD(&obj_priv->fence_list); | 3881 | INIT_LIST_HEAD(&obj_priv->fence_list); |
3882 | obj_priv->madv = I915_MADV_WILLNEED; | ||
3818 | 3883 | ||
3819 | return 0; | 3884 | return 0; |
3820 | } | 3885 | } |
@@ -4506,7 +4571,7 @@ i915_gem_object_truncate(struct drm_gem_object *obj) | |||
4506 | static inline int | 4571 | static inline int |
4507 | i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj_priv) | 4572 | i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj_priv) |
4508 | { | 4573 | { |
4509 | return !obj_priv->dirty; | 4574 | return !obj_priv->dirty || obj_priv->madv == I915_MADV_DONTNEED; |
4510 | } | 4575 | } |
4511 | 4576 | ||
4512 | static int | 4577 | static int |
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 8e1e92583fbc..607c9da061e8 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h | |||
@@ -185,6 +185,7 @@ typedef struct _drm_i915_sarea { | |||
185 | #define DRM_I915_GEM_GET_APERTURE 0x23 | 185 | #define DRM_I915_GEM_GET_APERTURE 0x23 |
186 | #define DRM_I915_GEM_MMAP_GTT 0x24 | 186 | #define DRM_I915_GEM_MMAP_GTT 0x24 |
187 | #define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 | 187 | #define DRM_I915_GET_PIPE_FROM_CRTC_ID 0x25 |
188 | #define DRM_I915_GEM_MADVISE 0x26 | ||
188 | 189 | ||
189 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) | 190 | #define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t) |
190 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) | 191 | #define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH) |
@@ -221,6 +222,7 @@ typedef struct _drm_i915_sarea { | |||
221 | #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) | 222 | #define DRM_IOCTL_I915_GEM_GET_TILING DRM_IOWR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_TILING, struct drm_i915_gem_get_tiling) |
222 | #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) | 223 | #define DRM_IOCTL_I915_GEM_GET_APERTURE DRM_IOR (DRM_COMMAND_BASE + DRM_I915_GEM_GET_APERTURE, struct drm_i915_gem_get_aperture) |
223 | #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id) | 224 | #define DRM_IOCTL_I915_GET_PIPE_FROM_CRTC_ID DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GET_PIPE_FROM_CRTC_ID, struct drm_intel_get_pipe_from_crtc_id) |
225 | #define DRM_IOCTL_I915_GEM_MADVISE DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GEM_MADVISE, struct drm_i915_gem_madvise) | ||
224 | 226 | ||
225 | /* Allow drivers to submit batchbuffers directly to hardware, relying | 227 | /* Allow drivers to submit batchbuffers directly to hardware, relying |
226 | * on the security mechanisms provided by hardware. | 228 | * on the security mechanisms provided by hardware. |
@@ -667,4 +669,20 @@ struct drm_i915_get_pipe_from_crtc_id { | |||
667 | __u32 pipe; | 669 | __u32 pipe; |
668 | }; | 670 | }; |
669 | 671 | ||
672 | #define I915_MADV_WILLNEED 0 | ||
673 | #define I915_MADV_DONTNEED 1 | ||
674 | |||
675 | struct drm_i915_gem_madvise { | ||
676 | /** Handle of the buffer to change the backing store advice */ | ||
677 | __u32 handle; | ||
678 | |||
679 | /* Advice: either the buffer will be needed again in the near future, | ||
680 | * or wont be and could be discarded under memory pressure. | ||
681 | */ | ||
682 | __u32 madv; | ||
683 | |||
684 | /** Whether the backing store still exists. */ | ||
685 | __u32 retained; | ||
686 | }; | ||
687 | |||
670 | #endif /* _I915_DRM_H_ */ | 688 | #endif /* _I915_DRM_H_ */ |