aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c1
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h7
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c81
-rw-r--r--include/drm/i915_drm.h18
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
1621int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls); 1622int 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);
706int i915_gem_throttle_ioctl(struct drm_device *dev, void *data, 711int i915_gem_throttle_ioctl(struct drm_device *dev, void *data,
707 struct drm_file *file_priv); 712 struct drm_file *file_priv);
713int i915_gem_madvise_ioctl(struct drm_device *dev, void *data,
714 struct drm_file *file_priv);
708int i915_gem_entervt_ioctl(struct drm_device *dev, void *data, 715int i915_gem_entervt_ioctl(struct drm_device *dev, void *data,
709 struct drm_file *file_priv); 716 struct drm_file *file_priv);
710int i915_gem_leavevt_ioctl(struct drm_device *dev, void *data, 717int 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
3815int
3816i915_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
3794int i915_gem_init_object(struct drm_gem_object *obj) 3858int 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)
4506static inline int 4571static inline int
4507i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj_priv) 4572i915_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
4512static int 4577static 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
675struct 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_ */