aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_gem.c28
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c43
-rw-r--r--include/drm/drmP.h2
4 files changed, 57 insertions, 18 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 5dad6b9d0dec..88d3368ffddd 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -463,6 +463,26 @@ drm_gem_object_handle_free(struct kref *kref)
463} 463}
464EXPORT_SYMBOL(drm_gem_object_handle_free); 464EXPORT_SYMBOL(drm_gem_object_handle_free);
465 465
466void drm_gem_vm_open(struct vm_area_struct *vma)
467{
468 struct drm_gem_object *obj = vma->vm_private_data;
469
470 drm_gem_object_reference(obj);
471}
472EXPORT_SYMBOL(drm_gem_vm_open);
473
474void drm_gem_vm_close(struct vm_area_struct *vma)
475{
476 struct drm_gem_object *obj = vma->vm_private_data;
477 struct drm_device *dev = obj->dev;
478
479 mutex_lock(&dev->struct_mutex);
480 drm_gem_object_unreference(obj);
481 mutex_unlock(&dev->struct_mutex);
482}
483EXPORT_SYMBOL(drm_gem_vm_close);
484
485
466/** 486/**
467 * drm_gem_mmap - memory map routine for GEM objects 487 * drm_gem_mmap - memory map routine for GEM objects
468 * @filp: DRM file pointer 488 * @filp: DRM file pointer
@@ -524,6 +544,14 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
524#endif 544#endif
525 vma->vm_page_prot = __pgprot(prot); 545 vma->vm_page_prot = __pgprot(prot);
526 546
547 /* Take a ref for this mapping of the object, so that the fault
548 * handler can dereference the mmap offset's pointer to the object.
549 * This reference is cleaned up by the corresponding vm_close
550 * (which should happen whether the vma was created by this call, or
551 * by a vm_open due to mremap or partial unmap or whatever).
552 */
553 drm_gem_object_reference(obj);
554
527 vma->vm_file = filp; /* Needed for drm_vm_open() */ 555 vma->vm_file = filp; /* Needed for drm_vm_open() */
528 drm_vm_open_locked(vma); 556 drm_vm_open_locked(vma);
529 557
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index aac12ee31a46..a31cbdbc3c54 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -94,6 +94,8 @@ static int i915_resume(struct drm_device *dev)
94 94
95static struct vm_operations_struct i915_gem_vm_ops = { 95static struct vm_operations_struct i915_gem_vm_ops = {
96 .fault = i915_gem_fault, 96 .fault = i915_gem_fault,
97 .open = drm_gem_vm_open,
98 .close = drm_gem_vm_close,
97}; 99};
98 100
99static struct drm_driver driver = { 101static struct drm_driver driver = {
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 078858178832..ac534c9a2f81 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -607,8 +607,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
607 case -EAGAIN: 607 case -EAGAIN:
608 return VM_FAULT_OOM; 608 return VM_FAULT_OOM;
609 case -EFAULT: 609 case -EFAULT:
610 case -EBUSY:
611 DRM_ERROR("can't insert pfn?? fault or busy...\n");
612 return VM_FAULT_SIGBUS; 610 return VM_FAULT_SIGBUS;
613 default: 611 default:
614 return VM_FAULT_NOPAGE; 612 return VM_FAULT_NOPAGE;
@@ -684,6 +682,30 @@ out_free_list:
684 return ret; 682 return ret;
685} 683}
686 684
685static void
686i915_gem_free_mmap_offset(struct drm_gem_object *obj)
687{
688 struct drm_device *dev = obj->dev;
689 struct drm_i915_gem_object *obj_priv = obj->driver_private;
690 struct drm_gem_mm *mm = dev->mm_private;
691 struct drm_map_list *list;
692
693 list = &obj->map_list;
694 drm_ht_remove_item(&mm->offset_hash, &list->hash);
695
696 if (list->file_offset_node) {
697 drm_mm_put_block(list->file_offset_node);
698 list->file_offset_node = NULL;
699 }
700
701 if (list->map) {
702 drm_free(list->map, sizeof(struct drm_map), DRM_MEM_DRIVER);
703 list->map = NULL;
704 }
705
706 obj_priv->mmap_offset = 0;
707}
708
687/** 709/**
688 * i915_gem_get_gtt_alignment - return required GTT alignment for an object 710 * i915_gem_get_gtt_alignment - return required GTT alignment for an object
689 * @obj: object to check 711 * @obj: object to check
@@ -2896,9 +2918,6 @@ int i915_gem_init_object(struct drm_gem_object *obj)
2896void i915_gem_free_object(struct drm_gem_object *obj) 2918void i915_gem_free_object(struct drm_gem_object *obj)
2897{ 2919{
2898 struct drm_device *dev = obj->dev; 2920 struct drm_device *dev = obj->dev;
2899 struct drm_gem_mm *mm = dev->mm_private;
2900 struct drm_map_list *list;
2901 struct drm_map *map;
2902 struct drm_i915_gem_object *obj_priv = obj->driver_private; 2921 struct drm_i915_gem_object *obj_priv = obj->driver_private;
2903 2922
2904 while (obj_priv->pin_count > 0) 2923 while (obj_priv->pin_count > 0)
@@ -2909,19 +2928,7 @@ void i915_gem_free_object(struct drm_gem_object *obj)
2909 2928
2910 i915_gem_object_unbind(obj); 2929 i915_gem_object_unbind(obj);
2911 2930
2912 list = &obj->map_list; 2931 i915_gem_free_mmap_offset(obj);
2913 drm_ht_remove_item(&mm->offset_hash, &list->hash);
2914
2915 if (list->file_offset_node) {
2916 drm_mm_put_block(list->file_offset_node);
2917 list->file_offset_node = NULL;
2918 }
2919
2920 map = list->map;
2921 if (map) {
2922 drm_free(map, sizeof(*map), DRM_MEM_DRIVER);
2923 list->map = NULL;
2924 }
2925 2932
2926 drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER); 2933 drm_free(obj_priv->page_cpu_valid, 1, DRM_MEM_DRIVER);
2927 drm_free(obj->driver_private, 1, DRM_MEM_DRIVER); 2934 drm_free(obj->driver_private, 1, DRM_MEM_DRIVER);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 8190b9bcc2d9..e5f4ae989abf 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -1321,6 +1321,8 @@ void drm_gem_object_free(struct kref *kref);
1321struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev, 1321struct drm_gem_object *drm_gem_object_alloc(struct drm_device *dev,
1322 size_t size); 1322 size_t size);
1323void drm_gem_object_handle_free(struct kref *kref); 1323void drm_gem_object_handle_free(struct kref *kref);
1324void drm_gem_vm_open(struct vm_area_struct *vma);
1325void drm_gem_vm_close(struct vm_area_struct *vma);
1324int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma); 1326int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
1325 1327
1326static inline void 1328static inline void