Remove the clean_unfenced function.
[platform/upstream/libdrm.git] / linux-core / drm_bo.c
index 6e1de80..89c014e 100644 (file)
@@ -80,7 +80,8 @@ void drm_bo_add_to_lru(struct drm_buffer_object * bo)
 
        DRM_ASSERT_LOCKED(&bo->dev->struct_mutex);
 
-       if (!bo->pinned || bo->mem.mem_type != bo->pinned_mem_type) {
+       if (!(bo->mem.mask & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT))
+           || bo->mem.mem_type != bo->pinned_mem_type) {
                man = &bo->dev->bm.man[bo->mem.mem_type];
                list_add_tail(&bo->lru, &man->lru);
        } else {
@@ -638,8 +639,7 @@ int drm_fence_buffer_objects(struct drm_device *dev,
                mutex_lock(&entry->mutex);
                mutex_lock(&dev->struct_mutex);
                list_del_init(l);
-               if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED &&
-                   entry->fence_class == fence_class) {
+               if (entry->priv_flags & _DRM_BO_FLAG_UNFENCED) {
                        count++;
                        if (entry->fence)
                                drm_fence_usage_deref_locked(&entry->fence);
@@ -761,7 +761,7 @@ static int drm_bo_mem_force_space(struct drm_device * dev,
                atomic_inc(&entry->usage);
                mutex_unlock(&dev->struct_mutex);
                mutex_lock(&entry->mutex);
-               BUG_ON(entry->pinned);
+               BUG_ON(entry->mem.flags & (DRM_BO_FLAG_NO_MOVE | DRM_BO_FLAG_NO_EVICT));
 
                ret = drm_bo_evict(entry, mem_type, no_wait);
                mutex_unlock(&entry->mutex);
@@ -930,6 +930,19 @@ static int drm_bo_new_mask(struct drm_buffer_object * bo,
                return -EINVAL;
        }
 
+       if ((new_mask & DRM_BO_FLAG_NO_EVICT) && !DRM_SUSER(DRM_CURPROC)) {
+               DRM_ERROR
+                   ("DRM_BO_FLAG_NO_EVICT is only available to priviliged "
+                    "processes\n");
+               return -EPERM;
+       }
+
+       if ((new_mask & DRM_BO_FLAG_NO_MOVE)) {
+               DRM_ERROR
+                       ("DRM_BO_FLAG_NO_MOVE is not properly implemented yet.\n");
+               return -EPERM;
+       }
+
        new_props = new_mask & (DRM_BO_FLAG_EXE | DRM_BO_FLAG_WRITE |
                                DRM_BO_FLAG_READ);
 
@@ -1148,11 +1161,9 @@ static int drm_buffer_object_map(struct drm_file *file_priv, uint32_t handle,
                return -EINVAL;
 
        mutex_lock(&bo->mutex);
-       if (!(hint & DRM_BO_HINT_ALLOW_UNFENCED_MAP)) {
-               ret = drm_bo_wait_unfenced(bo, no_wait, 0);
-               if (ret)
-                       goto out;
-       }
+       ret = drm_bo_wait_unfenced(bo, no_wait, 0);
+       if (ret)
+               goto out;
 
        /*
         * If this returns true, we are currently unmapped.
@@ -1372,12 +1383,6 @@ static int drm_buffer_object_validate(struct drm_buffer_object * bo,
                return ret;
        }
 
-       if (bo->pinned && bo->pinned_mem_type != bo->mem.mem_type) {
-               DRM_ERROR("Attempt to validate pinned buffer into different memory "
-                   "type\n");
-               return -EINVAL;
-       }
-
        /*
         * We're switching command submission mechanism,
         * or cannot simply rely on the hardware serializing for us.
@@ -1419,6 +1424,37 @@ static int drm_buffer_object_validate(struct drm_buffer_object * bo,
        }
 
        /*
+        * Pinned buffers.
+        */
+
+       if (bo->mem.mask & (DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE)) {
+               bo->pinned_mem_type = bo->mem.mem_type;
+               mutex_lock(&dev->struct_mutex);
+               list_del_init(&bo->pinned_lru);
+               drm_bo_add_to_pinned_lru(bo);
+
+               if (bo->pinned_node != bo->mem.mm_node) {
+                       if (bo->pinned_node != NULL)
+                               drm_mm_put_block(bo->pinned_node);
+                       bo->pinned_node = bo->mem.mm_node;
+               }
+
+               mutex_unlock(&dev->struct_mutex);
+
+       } else if (bo->pinned_node != NULL) {
+
+               mutex_lock(&dev->struct_mutex);
+
+               if (bo->pinned_node != bo->mem.mm_node)
+                       drm_mm_put_block(bo->pinned_node);
+
+               list_del_init(&bo->pinned_lru);
+               bo->pinned_node = NULL;
+               mutex_unlock(&dev->struct_mutex);
+
+       }
+
+       /*
         * We might need to add a TTM.
         */
 
@@ -1504,7 +1540,15 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle,
        if (!bo) {
                return -EINVAL;
        }
+       
+       /*
+        * Only allow creator to change shared buffer mask.
+        */
 
+       if (bo->base.owner != file_priv) 
+               mask &= ~(DRM_BO_FLAG_NO_EVICT | DRM_BO_FLAG_NO_MOVE);
+
+               
        ret = drm_bo_do_validate(bo, flags, mask, hint, fence_class,
                                 no_wait, rep);
 
@@ -1517,10 +1561,6 @@ int drm_bo_handle_validate(struct drm_file * file_priv, uint32_t handle,
 }
 EXPORT_SYMBOL(drm_bo_handle_validate);
 
-/**
- * Fills out the generic buffer object ioctl reply with the information for
- * the BO with id of handle.
- */
 static int drm_bo_handle_info(struct drm_file *file_priv, uint32_t handle,
                              struct drm_bo_info_rep *rep)
 {
@@ -1630,8 +1670,10 @@ int drm_buffer_object_create(struct drm_device *dev,
        bo->mem.page_alignment = page_alignment;
        bo->buffer_start = buffer_start;
        bo->priv_flags = 0;
-       bo->mem.flags = 0ULL;
-       bo->mem.mask = 0ULL;
+       bo->mem.flags = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED | 
+               DRM_BO_FLAG_MAPPABLE;
+       bo->mem.mask = DRM_BO_FLAG_MEM_LOCAL | DRM_BO_FLAG_CACHED |
+               DRM_BO_FLAG_MAPPABLE;
        atomic_inc(&bm->count);
        ret = drm_bo_new_mask(bo, mask, hint);
 
@@ -1645,18 +1687,8 @@ int drm_buffer_object_create(struct drm_device *dev,
                if (ret)
                        goto out_err;
        }
-#if 0
-       bo->fence_class = 0;
-       ret = driver->fence_type(bo, &bo->fence_class, &bo->fence_type);
-       if (ret) {
-               DRM_ERROR("Driver did not support given buffer permissions\n");
-               goto out_err;
-       }
 
-       ret = drm_bo_add_ttm(bo);
-#else
        ret = drm_buffer_object_validate(bo, 0, 0, hint & DRM_BO_HINT_DONT_BLOCK);
-#endif
        if (ret)
                goto out_err;
 
@@ -1672,6 +1704,7 @@ int drm_buffer_object_create(struct drm_device *dev,
 }
 EXPORT_SYMBOL(drm_buffer_object_create);
 
+
 static int drm_bo_add_user_object(struct drm_file *file_priv,
                                  struct drm_buffer_object *bo, int shareable)
 {
@@ -1693,86 +1726,6 @@ static int drm_bo_add_user_object(struct drm_file *file_priv,
        return ret;
 }
 
-static int drm_bo_lock_test(struct drm_device * dev, struct drm_file *file_priv)
-{
-       LOCK_TEST_WITH_RETURN(dev, file_priv);
-       return 0;
-}
-
-int drm_bo_op_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
-{
-       struct drm_bo_op_arg curarg;
-       struct drm_bo_op_arg *arg = data;
-       struct drm_bo_op_req *req = &arg->d.req;
-       struct drm_bo_info_rep rep;
-       unsigned long next = 0;
-       void __user *curuserarg = NULL;
-       int ret;
-
-       if (!dev->bm.initialized) {
-               DRM_ERROR("Buffer object manager is not initialized.\n");
-               return -EINVAL;
-       }
-
-       do {
-               if (next != 0) {
-                       curuserarg = (void __user *)next;
-                       if (copy_from_user(&curarg, curuserarg,
-                                          sizeof(curarg)) != 0)
-                               return -EFAULT;
-                       arg = &curarg;
-               }
-
-               if (arg->handled) {
-                       next = arg->next;
-                       continue;
-               }
-               req = &arg->d.req;
-               ret = 0;
-               switch (req->op) {
-               case drm_bo_validate:
-                       ret = drm_bo_lock_test(dev, file_priv);
-                       if (ret)
-                               break;
-                       ret = drm_bo_handle_validate(file_priv, req->bo_req.handle,
-                                                    req->bo_req.fence_class,
-                                                    req->bo_req.flags,
-                                                    req->bo_req.mask,
-                                                    req->bo_req.hint,
-                                                    &rep, NULL);
-                       break;
-               case drm_bo_fence:
-                       ret = -EINVAL;
-                       DRM_ERROR("Function is not implemented yet.\n");
-                       break;
-               case drm_bo_ref_fence:
-                       ret = -EINVAL;
-                       DRM_ERROR("Function is not implemented yet.\n");
-                       break;
-               default:
-                       ret = -EINVAL;
-               }
-               next = arg->next;
-
-               /*
-                * A signal interrupted us. Make sure the ioctl is restartable.
-                */
-
-               if (ret == -EAGAIN)
-                       return -EAGAIN;
-
-               arg->handled = 1;
-               arg->d.rep.ret = ret;
-               arg->d.rep.bo_info = rep;
-               if (arg != data) {
-                       if (copy_to_user(curuserarg, &curarg,
-                                        sizeof(curarg)) != 0)
-                               return -EFAULT;
-               }
-       } while (next != 0);
-       return 0;
-}
-
 int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        struct drm_bo_create_arg *arg = data;
@@ -1788,11 +1741,6 @@ int drm_bo_create_ioctl(struct drm_device *dev, void *data, struct drm_file *fil
                DRM_ERROR("Buffer object manager is not initialized.\n");
                return -EINVAL;
        }
-#if 0
-       ret = drm_bo_lock_test(dev, file_priv);
-       if (ret)
-               goto out;
-#endif
 
        ret = drm_buffer_object_create(file_priv->head->dev,
                                       req->size, drm_bo_type_dc, req->mask,
@@ -1816,6 +1764,30 @@ out:
        return ret;
 }
 
+int drm_bo_setstatus_ioctl(struct drm_device *dev, 
+                          void *data, struct drm_file *file_priv)
+{
+       struct drm_bo_map_wait_idle_arg *arg = data;
+       struct drm_bo_info_req *req = &arg->d.req;
+       struct drm_bo_info_rep *rep = &arg->d.rep;
+       int ret;
+       if (!dev->bm.initialized) {
+               DRM_ERROR("Buffer object manager is not initialized.\n");
+               return -EINVAL;
+       }
+
+       ret = drm_bo_handle_validate(file_priv, req->handle, req->fence_class,
+                                    req->flags,
+                                    req->mask,
+                                    req->hint | DRM_BO_HINT_DONT_FENCE,
+                                    rep, NULL);
+
+       if (ret)
+               return ret;
+
+       return 0;
+}
+
 int drm_bo_map_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
 {
        struct drm_bo_map_wait_idle_arg *arg = data;
@@ -1926,166 +1898,6 @@ int drm_bo_wait_idle_ioctl(struct drm_device *dev, void *data, struct drm_file *
        return 0;
 }
 
-/**
- * Pins or unpins the given buffer object in the given memory area.
- *
- * Pinned buffers will not be evicted from or move within their memory area.
- * Must be called with the hardware lock held for pinning.
- */
-static int
-drm_bo_set_pin(struct drm_device *dev, struct drm_buffer_object *bo,
-    int pin)
-{
-       int ret = 0;
-
-       mutex_lock(&bo->mutex);
-       if (bo->pinned == pin) {
-               mutex_unlock(&bo->mutex);
-               return 0;
-       }
-
-       if (pin) {
-               ret = drm_bo_wait_unfenced(bo, 0, 0);
-               if (ret) {
-                       mutex_unlock(&bo->mutex);
-                       return ret;
-               }
-
-               /* Validate the buffer into its pinned location, with no pending
-                * fence.
-                */
-               ret = drm_buffer_object_validate(bo, bo->fence_class, 0, 0);
-               if (ret) {
-                       mutex_unlock(&bo->mutex);
-                       return ret;
-               }
-
-               /* Add our buffer to the pinned list */
-               bo->pinned_mem_type = bo->mem.mem_type;
-               mutex_lock(&dev->struct_mutex);
-               list_del_init(&bo->pinned_lru);
-               drm_bo_add_to_pinned_lru(bo);
-
-               if (bo->pinned_node != bo->mem.mm_node) {
-                       if (bo->pinned_node != NULL)
-                               drm_mm_put_block(bo->pinned_node);
-                       bo->pinned_node = bo->mem.mm_node;
-               }
-
-               mutex_unlock(&dev->struct_mutex);
-
-       } else {
-               mutex_lock(&dev->struct_mutex);
-
-               /* Remove our buffer from the pinned list */
-               if (bo->pinned_node != bo->mem.mm_node)
-                       drm_mm_put_block(bo->pinned_node);
-
-               list_del_init(&bo->pinned_lru);
-               bo->pinned_node = NULL;
-               mutex_unlock(&dev->struct_mutex);
-       }
-       bo->pinned = pin;
-       mutex_unlock(&bo->mutex);
-       return 0;
-}
-
-int drm_bo_set_pin_ioctl(struct drm_device *dev, void *data,
-                        struct drm_file *file_priv)
-{
-       struct drm_bo_set_pin_arg *arg = data;
-       struct drm_bo_set_pin_req *req = &arg->d.req;
-       struct drm_bo_info_rep *rep = &arg->d.rep;
-       struct drm_buffer_object *bo;
-       int ret;
-
-       if (!dev->bm.initialized) {
-               DRM_ERROR("Buffer object manager is not initialized.\n");
-               return -EINVAL;
-       }
-
-       if (req->pin < 0 || req->pin > 1) {
-               DRM_ERROR("Bad arguments to set_pin\n");
-               return -EINVAL;
-       }
-
-       if (req->pin)
-               LOCK_TEST_WITH_RETURN(dev, file_priv);
-
-       mutex_lock(&dev->struct_mutex);
-       bo = drm_lookup_buffer_object(file_priv, req->handle, 1);
-       mutex_unlock(&dev->struct_mutex);
-       if (!bo) {
-               return -EINVAL;
-       }
-
-       ret = drm_bo_set_pin(dev, bo, req->pin);
-       if (ret) {
-               drm_bo_usage_deref_unlocked(&bo);
-               return ret;
-       }
-
-       drm_bo_fill_rep_arg(bo, rep);
-       drm_bo_usage_deref_unlocked(&bo);
-
-       return 0;
-}
-
-
-/**
- *Clean the unfenced list and put on regular LRU.
- *This is part of the memory manager cleanup and should only be
- *called with the DRI lock held.
- *Call dev->struct_sem locked.
- */
-
-static void drm_bo_clean_unfenced(struct drm_device *dev)
-{
-       struct drm_buffer_manager *bm  = &dev->bm;
-       struct list_head *head, *list;
-       struct drm_buffer_object *entry;
-       struct drm_fence_object *fence;
-
-       head = &bm->unfenced;
-
-       if (list_empty(head))
-               return;
-
-       DRM_ERROR("Clean unfenced\n");
-
-       if (drm_fence_buffer_objects(dev, NULL, 0, NULL, &fence)) {
-
-               /*
-                * Fixme: Should really wait here.
-                */
-       }
-
-       if (fence)
-               drm_fence_usage_deref_locked(&fence);
-
-       if (list_empty(head))
-               return;
-
-       DRM_ERROR("Really clean unfenced\n");
-
-       list = head->next;
-       while(list != head) {
-               prefetch(list->next);
-               entry = list_entry(list, struct drm_buffer_object, lru);
-
-               atomic_inc(&entry->usage);
-               mutex_unlock(&dev->struct_mutex);
-               mutex_lock(&entry->mutex);
-               mutex_lock(&dev->struct_mutex);
-
-               list_del(&entry->lru);
-               DRM_FLAG_MASKED(entry->priv_flags, 0, _DRM_BO_FLAG_UNFENCED);
-               drm_bo_add_to_lru(entry);
-               mutex_unlock(&entry->mutex);
-               list = head->next;
-       }
-}
-
 static int drm_bo_leave_list(struct drm_buffer_object * bo,
                             uint32_t mem_type,
                             int free_pinned, int allow_errors)
@@ -2112,10 +1924,11 @@ static int drm_bo_leave_list(struct drm_buffer_object * bo,
                mutex_unlock(&dev->struct_mutex);
        }
 
-       if (bo->pinned) {
-               DRM_ERROR("A pinned buffer was present at "
+       if (bo->mem.flags & DRM_BO_FLAG_NO_EVICT) {
+               DRM_ERROR("A DRM_BO_NO_EVICT buffer present at "
                          "cleanup. Removing flag and evicting.\n");
-               bo->pinned = 0;
+               bo->mem.flags &= ~DRM_BO_FLAG_NO_EVICT;
+               bo->mem.mask &= ~DRM_BO_FLAG_NO_EVICT;
        }
 
        if (bo->mem.mem_type == mem_type)
@@ -2235,8 +2048,7 @@ int drm_bo_clean_mm(struct drm_device * dev, unsigned mem_type)
 
        ret = 0;
        if (mem_type > 0) {
-
-               drm_bo_clean_unfenced(dev);
+               BUG_ON(!list_empty(&bm->unfenced));
                drm_bo_force_list_clean(dev, &man->lru, mem_type, 1, 0, 0);
                drm_bo_force_list_clean(dev, &man->pinned, mem_type, 1, 0, 1);
 
@@ -2274,7 +2086,6 @@ static int drm_bo_lock_mm(struct drm_device * dev, unsigned mem_type)
                return 0;
        }
 
-       drm_bo_clean_unfenced(dev);
        ret = drm_bo_force_list_clean(dev, &man->lru, mem_type, 0, 1, 0);
        if (ret)
                return ret;