linux/drivers/gpu/drm/drm_gem.c
<<
>>
Prefs
   1/*
   2 * Copyright © 2008 Intel Corporation
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice (including the next
  12 * paragraph) shall be included in all copies or substantial portions of the
  13 * Software.
  14 *
  15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21 * IN THE SOFTWARE.
  22 *
  23 * Authors:
  24 *    Eric Anholt <eric@anholt.net>
  25 *
  26 */
  27
  28#include <linux/types.h>
  29#include <linux/slab.h>
  30#include <linux/mm.h>
  31#include <linux/uaccess.h>
  32#include <linux/fs.h>
  33#include <linux/file.h>
  34#include <linux/module.h>
  35#include <linux/mman.h>
  36#include <linux/pagemap.h>
  37#include "drmP.h"
  38
  39/** @file drm_gem.c
  40 *
  41 * This file provides some of the base ioctls and library routines for
  42 * the graphics memory manager implemented by each device driver.
  43 *
  44 * Because various devices have different requirements in terms of
  45 * synchronization and migration strategies, implementing that is left up to
  46 * the driver, and all that the general API provides should be generic --
  47 * allocating objects, reading/writing data with the cpu, freeing objects.
  48 * Even there, platform-dependent optimizations for reading/writing data with
  49 * the CPU mean we'll likely hook those out to driver-specific calls.  However,
  50 * the DRI2 implementation wants to have at least allocate/mmap be generic.
  51 *
  52 * The goal was to have swap-backed object allocation managed through
  53 * struct file.  However, file descriptors as handles to a struct file have
  54 * two major failings:
  55 * - Process limits prevent more than 1024 or so being used at a time by
  56 *   default.
  57 * - Inability to allocate high fds will aggravate the X Server's select()
  58 *   handling, and likely that of many GL client applications as well.
  59 *
  60 * This led to a plan of using our own integer IDs (called handles, following
  61 * DRM terminology) to mimic fds, and implement the fd syscalls we need as
  62 * ioctls.  The objects themselves will still include the struct file so
  63 * that we can transition to fds if the required kernel infrastructure shows
  64 * up at a later date, and as our interface with shmfs for memory allocation.
  65 */
  66
  67/*
  68 * We make up offsets for buffer objects so we can recognize them at
  69 * mmap time.
  70 */
  71#define DRM_FILE_PAGE_OFFSET_START ((0xFFFFFFFFUL >> PAGE_SHIFT) + 1)
  72#define DRM_FILE_PAGE_OFFSET_SIZE ((0xFFFFFFFFUL >> PAGE_SHIFT) * 16)
  73
  74/**
  75 * Initialize the GEM device fields
  76 */
  77
  78int
  79drm_gem_init(struct drm_device *dev)
  80{
  81        struct drm_gem_mm *mm;
  82
  83        spin_lock_init(&dev->object_name_lock);
  84        idr_init(&dev->object_name_idr);
  85        atomic_set(&dev->object_count, 0);
  86        atomic_set(&dev->object_memory, 0);
  87        atomic_set(&dev->pin_count, 0);
  88        atomic_set(&dev->pin_memory, 0);
  89        atomic_set(&dev->gtt_count, 0);
  90        atomic_set(&dev->gtt_memory, 0);
  91
  92        mm = kzalloc(sizeof(struct drm_gem_mm), GFP_KERNEL);
  93        if (!mm) {
  94                DRM_ERROR("out of memory\n");
  95                return -ENOMEM;
  96        }
  97
  98        dev->mm_private = mm;
  99
 100        if (drm_ht_create(&mm->offset_hash, 19)) {
 101                kfree(mm);
 102                return -ENOMEM;
 103        }
 104
 105        if (drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
 106                        DRM_FILE_PAGE_OFFSET_SIZE)) {
 107                drm_ht_remove(&mm->offset_hash);
 108                kfree(mm);
 109                return -ENOMEM;
 110        }
 111
 112        return 0;
 113}
 114
 115void
 116drm_gem_destroy(struct drm_device *dev)
 117{
 118        struct drm_gem_mm *mm = dev->mm_private;
 119
 120        drm_mm_takedown(&mm->offset_manager);
 121        drm_ht_remove(&mm->offset_hash);
 122        kfree(mm);
 123        dev->mm_private = NULL;
 124}
 125
 126/**
 127 * Allocate a GEM object of the specified size with shmfs backing store
 128 */
 129struct drm_gem_object *
 130drm_gem_object_alloc(struct drm_device *dev, size_t size)
 131{
 132        struct drm_gem_object *obj;
 133
 134        BUG_ON((size & (PAGE_SIZE - 1)) != 0);
 135
 136        obj = kzalloc(sizeof(*obj), GFP_KERNEL);
 137        if (!obj)
 138                goto free;
 139
 140        obj->dev = dev;
 141        obj->filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
 142        if (IS_ERR(obj->filp))
 143                goto free;
 144
 145        /* Basically we want to disable the OOM killer and handle ENOMEM
 146         * ourselves by sacrificing pages from cached buffers.
 147         * XXX shmem_file_[gs]et_gfp_mask()
 148         */
 149        mapping_set_gfp_mask(obj->filp->f_path.dentry->d_inode->i_mapping,
 150                             GFP_HIGHUSER |
 151                             __GFP_COLD |
 152                             __GFP_FS |
 153                             __GFP_RECLAIMABLE |
 154                             __GFP_NORETRY |
 155                             __GFP_NOWARN |
 156                             __GFP_NOMEMALLOC);
 157
 158        kref_init(&obj->refcount);
 159        kref_init(&obj->handlecount);
 160        obj->size = size;
 161        if (dev->driver->gem_init_object != NULL &&
 162            dev->driver->gem_init_object(obj) != 0) {
 163                goto fput;
 164        }
 165        atomic_inc(&dev->object_count);
 166        atomic_add(obj->size, &dev->object_memory);
 167        return obj;
 168fput:
 169        fput(obj->filp);
 170free:
 171        kfree(obj);
 172        return NULL;
 173}
 174EXPORT_SYMBOL(drm_gem_object_alloc);
 175
 176/**
 177 * Removes the mapping from handle to filp for this object.
 178 */
 179static int
 180drm_gem_handle_delete(struct drm_file *filp, u32 handle)
 181{
 182        struct drm_device *dev;
 183        struct drm_gem_object *obj;
 184
 185        /* This is gross. The idr system doesn't let us try a delete and
 186         * return an error code.  It just spews if you fail at deleting.
 187         * So, we have to grab a lock around finding the object and then
 188         * doing the delete on it and dropping the refcount, or the user
 189         * could race us to double-decrement the refcount and cause a
 190         * use-after-free later.  Given the frequency of our handle lookups,
 191         * we may want to use ida for number allocation and a hash table
 192         * for the pointers, anyway.
 193         */
 194        spin_lock(&filp->table_lock);
 195
 196        /* Check if we currently have a reference on the object */
 197        obj = idr_find(&filp->object_idr, handle);
 198        if (obj == NULL) {
 199                spin_unlock(&filp->table_lock);
 200                return -EINVAL;
 201        }
 202        dev = obj->dev;
 203
 204        /* Release reference and decrement refcount. */
 205        idr_remove(&filp->object_idr, handle);
 206        spin_unlock(&filp->table_lock);
 207
 208        mutex_lock(&dev->struct_mutex);
 209        drm_gem_object_handle_unreference(obj);
 210        mutex_unlock(&dev->struct_mutex);
 211
 212        return 0;
 213}
 214
 215/**
 216 * Create a handle for this object. This adds a handle reference
 217 * to the object, which includes a regular reference count. Callers
 218 * will likely want to dereference the object afterwards.
 219 */
 220int
 221drm_gem_handle_create(struct drm_file *file_priv,
 222                       struct drm_gem_object *obj,
 223                       u32 *handlep)
 224{
 225        int     ret;
 226
 227        /*
 228         * Get the user-visible handle using idr.
 229         */
 230again:
 231        /* ensure there is space available to allocate a handle */
 232        if (idr_pre_get(&file_priv->object_idr, GFP_KERNEL) == 0)
 233                return -ENOMEM;
 234
 235        /* do the allocation under our spinlock */
 236        spin_lock(&file_priv->table_lock);
 237        ret = idr_get_new_above(&file_priv->object_idr, obj, 1, (int *)handlep);
 238        spin_unlock(&file_priv->table_lock);
 239        if (ret == -EAGAIN)
 240                goto again;
 241
 242        if (ret != 0)
 243                return ret;
 244
 245        drm_gem_object_handle_reference(obj);
 246        return 0;
 247}
 248EXPORT_SYMBOL(drm_gem_handle_create);
 249
 250/** Returns a reference to the object named by the handle. */
 251struct drm_gem_object *
 252drm_gem_object_lookup(struct drm_device *dev, struct drm_file *filp,
 253                      u32 handle)
 254{
 255        struct drm_gem_object *obj;
 256
 257        spin_lock(&filp->table_lock);
 258
 259        /* Check if we currently have a reference on the object */
 260        obj = idr_find(&filp->object_idr, handle);
 261        if (obj == NULL) {
 262                spin_unlock(&filp->table_lock);
 263                return NULL;
 264        }
 265
 266        drm_gem_object_reference(obj);
 267
 268        spin_unlock(&filp->table_lock);
 269
 270        return obj;
 271}
 272EXPORT_SYMBOL(drm_gem_object_lookup);
 273
 274/**
 275 * Releases the handle to an mm object.
 276 */
 277int
 278drm_gem_close_ioctl(struct drm_device *dev, void *data,
 279                    struct drm_file *file_priv)
 280{
 281        struct drm_gem_close *args = data;
 282        int ret;
 283
 284        if (!(dev->driver->driver_features & DRIVER_GEM))
 285                return -ENODEV;
 286
 287        ret = drm_gem_handle_delete(file_priv, args->handle);
 288
 289        return ret;
 290}
 291
 292/**
 293 * Create a global name for an object, returning the name.
 294 *
 295 * Note that the name does not hold a reference; when the object
 296 * is freed, the name goes away.
 297 */
 298int
 299drm_gem_flink_ioctl(struct drm_device *dev, void *data,
 300                    struct drm_file *file_priv)
 301{
 302        struct drm_gem_flink *args = data;
 303        struct drm_gem_object *obj;
 304        int ret;
 305
 306        if (!(dev->driver->driver_features & DRIVER_GEM))
 307                return -ENODEV;
 308
 309        obj = drm_gem_object_lookup(dev, file_priv, args->handle);
 310        if (obj == NULL)
 311                return -EBADF;
 312
 313again:
 314        if (idr_pre_get(&dev->object_name_idr, GFP_KERNEL) == 0) {
 315                ret = -ENOMEM;
 316                goto err;
 317        }
 318
 319        spin_lock(&dev->object_name_lock);
 320        if (!obj->name) {
 321                ret = idr_get_new_above(&dev->object_name_idr, obj, 1,
 322                                        &obj->name);
 323                args->name = (uint64_t) obj->name;
 324                spin_unlock(&dev->object_name_lock);
 325
 326                if (ret == -EAGAIN)
 327                        goto again;
 328
 329                if (ret != 0)
 330                        goto err;
 331
 332                /* Allocate a reference for the name table.  */
 333                drm_gem_object_reference(obj);
 334        } else {
 335                args->name = (uint64_t) obj->name;
 336                spin_unlock(&dev->object_name_lock);
 337                ret = 0;
 338        }
 339
 340err:
 341        mutex_lock(&dev->struct_mutex);
 342        drm_gem_object_unreference(obj);
 343        mutex_unlock(&dev->struct_mutex);
 344        return ret;
 345}
 346
 347/**
 348 * Open an object using the global name, returning a handle and the size.
 349 *
 350 * This handle (of course) holds a reference to the object, so the object
 351 * will not go away until the handle is deleted.
 352 */
 353int
 354drm_gem_open_ioctl(struct drm_device *dev, void *data,
 355                   struct drm_file *file_priv)
 356{
 357        struct drm_gem_open *args = data;
 358        struct drm_gem_object *obj;
 359        int ret;
 360        u32 handle;
 361
 362        if (!(dev->driver->driver_features & DRIVER_GEM))
 363                return -ENODEV;
 364
 365        spin_lock(&dev->object_name_lock);
 366        obj = idr_find(&dev->object_name_idr, (int) args->name);
 367        if (obj)
 368                drm_gem_object_reference(obj);
 369        spin_unlock(&dev->object_name_lock);
 370        if (!obj)
 371                return -ENOENT;
 372
 373        ret = drm_gem_handle_create(file_priv, obj, &handle);
 374        mutex_lock(&dev->struct_mutex);
 375        drm_gem_object_unreference(obj);
 376        mutex_unlock(&dev->struct_mutex);
 377        if (ret)
 378                return ret;
 379
 380        args->handle = handle;
 381        args->size = obj->size;
 382
 383        return 0;
 384}
 385
 386/**
 387 * Called at device open time, sets up the structure for handling refcounting
 388 * of mm objects.
 389 */
 390void
 391drm_gem_open(struct drm_device *dev, struct drm_file *file_private)
 392{
 393        idr_init(&file_private->object_idr);
 394        spin_lock_init(&file_private->table_lock);
 395}
 396
 397/**
 398 * Called at device close to release the file's
 399 * handle references on objects.
 400 */
 401static int
 402drm_gem_object_release_handle(int id, void *ptr, void *data)
 403{
 404        struct drm_gem_object *obj = ptr;
 405
 406        drm_gem_object_handle_unreference(obj);
 407
 408        return 0;
 409}
 410
 411/**
 412 * Called at close time when the filp is going away.
 413 *
 414 * Releases any remaining references on objects by this filp.
 415 */
 416void
 417drm_gem_release(struct drm_device *dev, struct drm_file *file_private)
 418{
 419        mutex_lock(&dev->struct_mutex);
 420        idr_for_each(&file_private->object_idr,
 421                     &drm_gem_object_release_handle, NULL);
 422
 423        idr_destroy(&file_private->object_idr);
 424        mutex_unlock(&dev->struct_mutex);
 425}
 426
 427/**
 428 * Called after the last reference to the object has been lost.
 429 *
 430 * Frees the object
 431 */
 432void
 433drm_gem_object_free(struct kref *kref)
 434{
 435        struct drm_gem_object *obj = (struct drm_gem_object *) kref;
 436        struct drm_device *dev = obj->dev;
 437
 438        BUG_ON(!mutex_is_locked(&dev->struct_mutex));
 439
 440        if (dev->driver->gem_free_object != NULL)
 441                dev->driver->gem_free_object(obj);
 442
 443        fput(obj->filp);
 444        atomic_dec(&dev->object_count);
 445        atomic_sub(obj->size, &dev->object_memory);
 446        kfree(obj);
 447}
 448EXPORT_SYMBOL(drm_gem_object_free);
 449
 450/**
 451 * Called after the last handle to the object has been closed
 452 *
 453 * Removes any name for the object. Note that this must be
 454 * called before drm_gem_object_free or we'll be touching
 455 * freed memory
 456 */
 457void
 458drm_gem_object_handle_free(struct kref *kref)
 459{
 460        struct drm_gem_object *obj = container_of(kref,
 461                                                  struct drm_gem_object,
 462                                                  handlecount);
 463        struct drm_device *dev = obj->dev;
 464
 465        /* Remove any name for this object */
 466        spin_lock(&dev->object_name_lock);
 467        if (obj->name) {
 468                idr_remove(&dev->object_name_idr, obj->name);
 469                obj->name = 0;
 470                spin_unlock(&dev->object_name_lock);
 471                /*
 472                 * The object name held a reference to this object, drop
 473                 * that now.
 474                 */
 475                drm_gem_object_unreference(obj);
 476        } else
 477                spin_unlock(&dev->object_name_lock);
 478
 479}
 480EXPORT_SYMBOL(drm_gem_object_handle_free);
 481
 482void drm_gem_vm_open(struct vm_area_struct *vma)
 483{
 484        struct drm_gem_object *obj = vma->vm_private_data;
 485
 486        drm_gem_object_reference(obj);
 487}
 488EXPORT_SYMBOL(drm_gem_vm_open);
 489
 490void drm_gem_vm_close(struct vm_area_struct *vma)
 491{
 492        struct drm_gem_object *obj = vma->vm_private_data;
 493        struct drm_device *dev = obj->dev;
 494
 495        mutex_lock(&dev->struct_mutex);
 496        drm_gem_object_unreference(obj);
 497        mutex_unlock(&dev->struct_mutex);
 498}
 499EXPORT_SYMBOL(drm_gem_vm_close);
 500
 501
 502/**
 503 * drm_gem_mmap - memory map routine for GEM objects
 504 * @filp: DRM file pointer
 505 * @vma: VMA for the area to be mapped
 506 *
 507 * If a driver supports GEM object mapping, mmap calls on the DRM file
 508 * descriptor will end up here.
 509 *
 510 * If we find the object based on the offset passed in (vma->vm_pgoff will
 511 * contain the fake offset we created when the GTT map ioctl was called on
 512 * the object), we set up the driver fault handler so that any accesses
 513 * to the object can be trapped, to perform migration, GTT binding, surface
 514 * register allocation, or performance monitoring.
 515 */
 516int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
 517{
 518        struct drm_file *priv = filp->private_data;
 519        struct drm_device *dev = priv->minor->dev;
 520        struct drm_gem_mm *mm = dev->mm_private;
 521        struct drm_local_map *map = NULL;
 522        struct drm_gem_object *obj;
 523        struct drm_hash_item *hash;
 524        int ret = 0;
 525
 526        mutex_lock(&dev->struct_mutex);
 527
 528        if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) {
 529                mutex_unlock(&dev->struct_mutex);
 530                return drm_mmap(filp, vma);
 531        }
 532
 533        map = drm_hash_entry(hash, struct drm_map_list, hash)->map;
 534        if (!map ||
 535            ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) {
 536                ret =  -EPERM;
 537                goto out_unlock;
 538        }
 539
 540        /* Check for valid size. */
 541        if (map->size < vma->vm_end - vma->vm_start) {
 542                ret = -EINVAL;
 543                goto out_unlock;
 544        }
 545
 546        obj = map->handle;
 547        if (!obj->dev->driver->gem_vm_ops) {
 548                ret = -EINVAL;
 549                goto out_unlock;
 550        }
 551
 552        vma->vm_flags |= VM_RESERVED | VM_IO | VM_PFNMAP | VM_DONTEXPAND;
 553        vma->vm_ops = obj->dev->driver->gem_vm_ops;
 554        vma->vm_private_data = map->handle;
 555        vma->vm_page_prot =  pgprot_writecombine(vm_get_page_prot(vma->vm_flags));
 556
 557        /* Take a ref for this mapping of the object, so that the fault
 558         * handler can dereference the mmap offset's pointer to the object.
 559         * This reference is cleaned up by the corresponding vm_close
 560         * (which should happen whether the vma was created by this call, or
 561         * by a vm_open due to mremap or partial unmap or whatever).
 562         */
 563        drm_gem_object_reference(obj);
 564
 565        vma->vm_file = filp;    /* Needed for drm_vm_open() */
 566        drm_vm_open_locked(vma);
 567
 568out_unlock:
 569        mutex_unlock(&dev->struct_mutex);
 570
 571        return ret;
 572}
 573EXPORT_SYMBOL(drm_gem_mmap);
 574
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.