Merge branch 'writeback' of git://git.kernel.dk/linux-2.6-block
[pandora-kernel.git] / drivers / gpu / drm / drm_gem.c
index 4984aa8..8039199 100644 (file)
@@ -89,7 +89,7 @@ drm_gem_init(struct drm_device *dev)
        atomic_set(&dev->gtt_count, 0);
        atomic_set(&dev->gtt_memory, 0);
 
-       mm = drm_calloc(1, sizeof(struct drm_gem_mm), DRM_MEM_MM);
+       mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL);
        if (!mm) {
                DRM_ERROR("out of memory\n");
                return -ENOMEM;
@@ -98,14 +98,14 @@ drm_gem_init(struct drm_device *dev)
        dev->mm_private = mm;
 
        if (drm_ht_create(&mm->offset_hash, 19)) {
-               drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
+               kfree(mm);
                return -ENOMEM;
        }
 
        if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
                        DRM_FILE_PAGE_OFFSET_SIZE)) {
                drm_ht_remove(&mm->offset_hash);
-               drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
+               kfree(mm);
                return -ENOMEM;
        }
 
@@ -119,7 +119,7 @@ drm_gem_destroy(struct drm_device *dev)
 
        drm_mm_takedown(&mm->offset_manager);
        drm_ht_remove(&mm->offset_hash);
-       drm_free(mm, sizeof(struct drm_gem_mm), DRM_MEM_MM);
+       kfree(mm);
        dev->mm_private = NULL;
 }
 
@@ -133,27 +133,43 @@ drm_gem_object_alloc(struct drm_device *dev, size_t size)
 
        BUG_ON((size & (PAGE_SIZE - 1)) != 0);
 
-       obj = kcalloc(1, sizeof(*obj), GFP_KERNEL);
+       obj = kzalloc(sizeof(*obj), GFP_KERNEL);
+       if (!obj)
+               goto free;
 
        obj->dev = dev;
        obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
-       if (IS_ERR(obj->filp)) {
-               kfree(obj);
-               return NULL;
-       }
+       if (IS_ERR(obj->filp))
+               goto free;
+
+       /* Basically we want to disable the OOM killer and handle ENOMEM
+        * ourselves by sacrificing pages from cached buffers.
+        * XXX shmem_file_[gs]et_gfp_mask()
+        */
+       mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping,
+                            GFP_HIGHUSER |
+                            __GFP_COLD |
+                            __GFP_FS |
+                            __GFP_RECLAIMABLE |
+                            __GFP_NORETRY |
+                            __GFP_NOWARN |
+                            __GFP_NOMEMALLOC);
 
        kref_init(&obj->refcount);
        kref_init(&obj->handlecount);
        obj->size = size;
        if (dev->driver->gem_init_object != NULL &&
            dev->driver->gem_init_object(obj) != 0) {
-               fput(obj->filp);
-               kfree(obj);
-               return NULL;
+               goto fput;
        }
        atomic_inc(&dev->object_count);
        atomic_add(obj->size, &dev->object_memory);
        return obj;
+fput:
+       fput(obj->filp);
+free:
+       kfree(obj);
+       return NULL;
 }
 EXPORT_SYMBOL(drm_gem_object_alloc);
 
@@ -161,7 +177,7 @@ EXPORT_SYMBOL(drm_gem_object_alloc);
  * Removes the mapping from handle to filp for this object.
  */
 static int
-drm_gem_handle_delete(struct drm_file *filp, int handle)
+drm_gem_handle_delete(struct drm_file *filp, u32 handle)
 {
        struct drm_device *dev;
        struct drm_gem_object *obj;
@@ -204,7 +220,7 @@ drm_gem_handle_delete(struct drm_file *filp, int handle)
 int
 drm_gem_handle_create(struct drm_file *file_priv,
                       struct drm_gem_object *obj,
-                      int *handlep)
+                      u32 *handlep)
 {
        int     ret;
 
@@ -218,7 +234,7 @@ again:
 
        /* do the allocation under our spinlock */
        spin_lock(&file_priv->table_lock);
-       ret = idr_get_new_above(&file_priv->object_idr, obj, 1, handlep);
+       ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep);
        spin_unlock(&file_priv->table_lock);
        if (ret == -EAGAIN)
                goto again;
@@ -234,7 +250,7 @@ EXPORT_SYMBOL(drm_gem_handle_create);
 /** Returns a reference to the object named by the handle. */
 struct drm_gem_object *
 drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
-                     int handle)
+                     u32 handle)
 {
        struct drm_gem_object *obj;
 
@@ -341,7 +357,7 @@ drm_gem_open_ioctl(struct drm_device *dev, void *data,
        struct drm_gem_open *args = data;
        struct drm_gem_object *obj;
        int ret;
-       int handle;
+       u32 handle;
 
        if (!(dev->driver->driver_features & DRIVER_GEM))
                return -ENODEV;
@@ -536,7 +552,6 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
        vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
        vma->vm_ops = obj->dev->driver->gem_vm_ops;
        vma->vm_private_data = map->handle;
-       /* FIXME: use pgprot_writecombine when available */
        vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
 
        /* Take a ref for this mapping of the object, so that the fault