Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'drm-next' of git://people.freedesktop.org/~dvdhrm/linux into drm-next

This is the 3rd respin of the drm-anon patches. They allow module unloading, use
the pin_fs_* helpers recommended by Al and are rebased on top of drm-next. Note
that there are minor conflicts with the "drm-minor" branch.

* 'drm-next' of git://people.freedesktop.org/~dvdhrm/linux:
drm: init TTM dev_mapping in ttm_bo_device_init()
drm: use anon-inode instead of relying on cdevs
drm: add pseudo filesystem for shared inodes

+140 -66
+3 -2
drivers/gpu/drm/ast/ast_ttm.c
··· 259 259 260 260 ret = ttm_bo_device_init(&ast->ttm.bdev, 261 261 ast->ttm.bo_global_ref.ref.object, 262 - &ast_bo_driver, DRM_FILE_PAGE_OFFSET, 262 + &ast_bo_driver, 263 + dev->anon_inode->i_mapping, 264 + DRM_FILE_PAGE_OFFSET, 263 265 true); 264 266 if (ret) { 265 267 DRM_ERROR("Error initialising bo driver; %d\n", ret); ··· 326 324 } 327 325 328 326 astbo->bo.bdev = &ast->ttm.bdev; 329 - astbo->bo.bdev->dev_mapping = dev->dev_mapping; 330 327 331 328 ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); 332 329
+4 -2
drivers/gpu/drm/bochs/bochs_mm.c
··· 225 225 226 226 ret = ttm_bo_device_init(&bochs->ttm.bdev, 227 227 bochs->ttm.bo_global_ref.ref.object, 228 - &bochs_bo_driver, DRM_FILE_PAGE_OFFSET, 228 + &bochs_bo_driver, 229 + bochs->dev->anon_inode->i_mapping, 230 + DRM_FILE_PAGE_OFFSET, 229 231 true); 230 232 if (ret) { 231 233 DRM_ERROR("Error initialising bo driver; %d\n", ret); ··· 361 359 } 362 360 363 361 bochsbo->bo.bdev = &bochs->ttm.bdev; 364 - bochsbo->bo.bdev->dev_mapping = dev->dev_mapping; 362 + bochsbo->bo.bdev->dev_mapping = dev->anon_inode->i_mapping; 365 363 366 364 bochs_ttm_placement(bochsbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); 367 365
+3 -2
drivers/gpu/drm/cirrus/cirrus_ttm.c
··· 259 259 260 260 ret = ttm_bo_device_init(&cirrus->ttm.bdev, 261 261 cirrus->ttm.bo_global_ref.ref.object, 262 - &cirrus_bo_driver, DRM_FILE_PAGE_OFFSET, 262 + &cirrus_bo_driver, 263 + dev->anon_inode->i_mapping, 264 + DRM_FILE_PAGE_OFFSET, 263 265 true); 264 266 if (ret) { 265 267 DRM_ERROR("Error initialising bo driver; %d\n", ret); ··· 331 329 } 332 330 333 331 cirrusbo->bo.bdev = &cirrus->ttm.bdev; 334 - cirrusbo->bo.bdev->dev_mapping = dev->dev_mapping; 335 332 336 333 cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); 337 334
+3 -22
drivers/gpu/drm/drm_fops.c
··· 83 83 struct drm_minor *minor; 84 84 int retcode; 85 85 int need_setup = 0; 86 - struct address_space *old_mapping; 87 - struct address_space *old_imapping; 88 86 89 87 minor = drm_minor_acquire(iminor(inode)); 90 88 if (IS_ERR(minor)) ··· 91 93 dev = minor->dev; 92 94 if (!dev->open_count++) 93 95 need_setup = 1; 94 - mutex_lock(&dev->struct_mutex); 95 - old_imapping = inode->i_mapping; 96 - old_mapping = dev->dev_mapping; 97 - if (old_mapping == NULL) 98 - dev->dev_mapping = &inode->i_data; 99 - /* ihold ensures nobody can remove inode with our i_data */ 100 - ihold(container_of(dev->dev_mapping, struct inode, i_data)); 101 - inode->i_mapping = dev->dev_mapping; 102 - filp->f_mapping = dev->dev_mapping; 103 - mutex_unlock(&dev->struct_mutex); 96 + 97 + /* share address_space across all char-devs of a single device */ 98 + filp->f_mapping = dev->anon_inode->i_mapping; 104 99 105 100 retcode = drm_open_helper(inode, filp, minor); 106 101 if (retcode) ··· 106 115 return 0; 107 116 108 117 err_undo: 109 - mutex_lock(&dev->struct_mutex); 110 - filp->f_mapping = old_imapping; 111 - inode->i_mapping = old_imapping; 112 - iput(container_of(dev->dev_mapping, struct inode, i_data)); 113 - dev->dev_mapping = old_mapping; 114 - mutex_unlock(&dev->struct_mutex); 115 118 dev->open_count--; 116 119 drm_minor_release(minor); 117 120 return retcode; ··· 406 421 407 422 drm_legacy_dma_takedown(dev); 408 423 409 - dev->dev_mapping = NULL; 410 424 mutex_unlock(&dev->struct_mutex); 411 425 412 426 drm_legacy_dev_reinit(dev); ··· 520 536 drm_master_put(&file_priv->minor->master); 521 537 } 522 538 } 523 - 524 - BUG_ON(dev->dev_mapping == NULL); 525 - iput(container_of(dev->dev_mapping, struct inode, i_data)); 526 539 527 540 /* drop the reference held my the file priv */ 528 541 if (file_priv->master)
+84
drivers/gpu/drm/drm_stub.c
··· 31 31 * DEALINGS IN THE SOFTWARE. 32 32 */ 33 33 34 + #include <linux/fs.h> 34 35 #include <linux/module.h> 35 36 #include <linux/moduleparam.h> 37 + #include <linux/mount.h> 36 38 #include <linux/slab.h> 37 39 #include <drm/drmP.h> 38 40 #include <drm/drm_core.h> ··· 461 459 } 462 460 EXPORT_SYMBOL(drm_unplug_dev); 463 461 462 + /* 463 + * DRM internal mount 464 + * We want to be able to allocate our own "struct address_space" to control 465 + * memory-mappings in VRAM (or stolen RAM, ...). However, core MM does not allow 466 + * stand-alone address_space objects, so we need an underlying inode. As there 467 + * is no way to allocate an independent inode easily, we need a fake internal 468 + * VFS mount-point. 469 + * 470 + * The drm_fs_inode_new() function allocates a new inode, drm_fs_inode_free() 471 + * frees it again. You are allowed to use iget() and iput() to get references to 472 + * the inode. But each drm_fs_inode_new() call must be paired with exactly one 473 + * drm_fs_inode_free() call (which does not have to be the last iput()). 474 + * We use drm_fs_inode_*() to manage our internal VFS mount-point and share it 475 + * between multiple inode-users. You could, technically, call 476 + * iget() + drm_fs_inode_free() directly after alloc and sometime later do an 477 + * iput(), but this way you'd end up with a new vfsmount for each inode. 478 + */ 479 + 480 + static int drm_fs_cnt; 481 + static struct vfsmount *drm_fs_mnt; 482 + 483 + static const struct dentry_operations drm_fs_dops = { 484 + .d_dname = simple_dname, 485 + }; 486 + 487 + static const struct super_operations drm_fs_sops = { 488 + .statfs = simple_statfs, 489 + }; 490 + 491 + static struct dentry *drm_fs_mount(struct file_system_type *fs_type, int flags, 492 + const char *dev_name, void *data) 493 + { 494 + return mount_pseudo(fs_type, 495 + "drm:", 496 + &drm_fs_sops, 497 + &drm_fs_dops, 498 + 0x010203ff); 499 + } 500 + 501 + static struct file_system_type drm_fs_type = { 502 + .name = "drm", 503 + .owner = THIS_MODULE, 504 + .mount = drm_fs_mount, 505 + .kill_sb = kill_anon_super, 506 + }; 507 + 508 + static struct inode *drm_fs_inode_new(void) 509 + { 510 + struct inode *inode; 511 + int r; 512 + 513 + r = simple_pin_fs(&drm_fs_type, &drm_fs_mnt, &drm_fs_cnt); 514 + if (r < 0) { 515 + DRM_ERROR("Cannot mount pseudo fs: %d\n", r); 516 + return ERR_PTR(r); 517 + } 518 + 519 + inode = alloc_anon_inode(drm_fs_mnt->mnt_sb); 520 + if (IS_ERR(inode)) 521 + simple_release_fs(&drm_fs_mnt, &drm_fs_cnt); 522 + 523 + return inode; 524 + } 525 + 526 + static void drm_fs_inode_free(struct inode *inode) 527 + { 528 + if (inode) { 529 + iput(inode); 530 + simple_release_fs(&drm_fs_mnt, &drm_fs_cnt); 531 + } 532 + } 533 + 464 534 /** 465 535 * drm_dev_alloc - Allocate new drm device 466 536 * @driver: DRM driver to allocate device for ··· 572 498 spin_lock_init(&dev->event_lock); 573 499 mutex_init(&dev->struct_mutex); 574 500 mutex_init(&dev->ctxlist_mutex); 501 + 502 + dev->anon_inode = drm_fs_inode_new(); 503 + if (IS_ERR(dev->anon_inode)) { 504 + ret = PTR_ERR(dev->anon_inode); 505 + DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret); 506 + goto err_free; 507 + } 575 508 576 509 if (drm_core_check_feature(dev, DRIVER_MODESET)) { 577 510 ret = drm_minor_alloc(dev, DRM_MINOR_CONTROL); ··· 623 542 drm_minor_free(dev, DRM_MINOR_LEGACY); 624 543 drm_minor_free(dev, DRM_MINOR_RENDER); 625 544 drm_minor_free(dev, DRM_MINOR_CONTROL); 545 + drm_fs_inode_free(dev->anon_inode); 546 + err_free: 626 547 kfree(dev); 627 548 return NULL; 628 549 } ··· 639 556 640 557 drm_ctxbitmap_cleanup(dev); 641 558 drm_ht_remove(&dev->map_hash); 559 + drm_fs_inode_free(dev->anon_inode); 642 560 643 561 drm_minor_free(dev, DRM_MINOR_LEGACY); 644 562 drm_minor_free(dev, DRM_MINOR_RENDER);
+2 -1
drivers/gpu/drm/i915/i915_gem.c
··· 1532 1532 if (!obj->fault_mappable) 1533 1533 return; 1534 1534 1535 - drm_vma_node_unmap(&obj->base.vma_node, obj->base.dev->dev_mapping); 1535 + drm_vma_node_unmap(&obj->base.vma_node, 1536 + obj->base.dev->anon_inode->i_mapping); 1536 1537 obj->fault_mappable = false; 1537 1538 } 1538 1539
+3 -2
drivers/gpu/drm/mgag200/mgag200_ttm.c
··· 259 259 260 260 ret = ttm_bo_device_init(&mdev->ttm.bdev, 261 261 mdev->ttm.bo_global_ref.ref.object, 262 - &mgag200_bo_driver, DRM_FILE_PAGE_OFFSET, 262 + &mgag200_bo_driver, 263 + dev->anon_inode->i_mapping, 264 + DRM_FILE_PAGE_OFFSET, 263 265 true); 264 266 if (ret) { 265 267 DRM_ERROR("Error initialising bo driver; %d\n", ret); ··· 326 324 } 327 325 328 326 mgabo->bo.bdev = &mdev->ttm.bdev; 329 - mgabo->bo.bdev->dev_mapping = dev->dev_mapping; 330 327 331 328 mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM); 332 329
-2
drivers/gpu/drm/nouveau/nouveau_gem.c
··· 228 228 struct nouveau_bo *nvbo = NULL; 229 229 int ret = 0; 230 230 231 - drm->ttm.bdev.dev_mapping = drm->dev->dev_mapping; 232 - 233 231 if (!pfb->memtype_valid(pfb, req->info.tile_flags)) { 234 232 NV_ERROR(cli, "bad page flags: 0x%08x\n", req->info.tile_flags); 235 233 return -EINVAL;
+3 -1
drivers/gpu/drm/nouveau/nouveau_ttm.c
··· 376 376 377 377 ret = ttm_bo_device_init(&drm->ttm.bdev, 378 378 drm->ttm.bo_global_ref.ref.object, 379 - &nouveau_bo_driver, DRM_FILE_PAGE_OFFSET, 379 + &nouveau_bo_driver, 380 + dev->anon_inode->i_mapping, 381 + DRM_FILE_PAGE_OFFSET, 380 382 bits <= 32 ? true : false); 381 383 if (ret) { 382 384 NV_ERROR(drm, "error initialising bo driver, %d\n", ret);
+17 -17
drivers/gpu/drm/omapdrm/omap_gem.c
··· 153 153 static void evict_entry(struct drm_gem_object *obj, 154 154 enum tiler_fmt fmt, struct usergart_entry *entry) 155 155 { 156 - if (obj->dev->dev_mapping) { 157 - struct omap_gem_object *omap_obj = to_omap_bo(obj); 158 - int n = usergart[fmt].height; 159 - size_t size = PAGE_SIZE * n; 160 - loff_t off = mmap_offset(obj) + 161 - (entry->obj_pgoff << PAGE_SHIFT); 162 - const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE); 163 - if (m > 1) { 164 - int i; 165 - /* if stride > than PAGE_SIZE then sparse mapping: */ 166 - for (i = n; i > 0; i--) { 167 - unmap_mapping_range(obj->dev->dev_mapping, 168 - off, PAGE_SIZE, 1); 169 - off += PAGE_SIZE * m; 170 - } 171 - } else { 172 - unmap_mapping_range(obj->dev->dev_mapping, off, size, 1); 156 + struct omap_gem_object *omap_obj = to_omap_bo(obj); 157 + int n = usergart[fmt].height; 158 + size_t size = PAGE_SIZE * n; 159 + loff_t off = mmap_offset(obj) + 160 + (entry->obj_pgoff << PAGE_SHIFT); 161 + const int m = 1 + ((omap_obj->width << fmt) / PAGE_SIZE); 162 + 163 + if (m > 1) { 164 + int i; 165 + /* if stride > than PAGE_SIZE then sparse mapping: */ 166 + for (i = n; i > 0; i--) { 167 + unmap_mapping_range(obj->dev->anon_inode->i_mapping, 168 + off, PAGE_SIZE, 1); 169 + off += PAGE_SIZE * m; 173 170 } 171 + } else { 172 + unmap_mapping_range(obj->dev->anon_inode->i_mapping, 173 + off, size, 1); 174 174 } 175 175 176 176 entry->obj = NULL;
-2
drivers/gpu/drm/qxl/qxl_object.c
··· 82 82 enum ttm_bo_type type; 83 83 int r; 84 84 85 - if (unlikely(qdev->mman.bdev.dev_mapping == NULL)) 86 - qdev->mman.bdev.dev_mapping = qdev->ddev->dev_mapping; 87 85 if (kernel) 88 86 type = ttm_bo_type_kernel; 89 87 else
+3 -3
drivers/gpu/drm/qxl/qxl_ttm.c
··· 493 493 /* No others user of address space so set it to 0 */ 494 494 r = ttm_bo_device_init(&qdev->mman.bdev, 495 495 qdev->mman.bo_global_ref.ref.object, 496 - &qxl_bo_driver, DRM_FILE_PAGE_OFFSET, 0); 496 + &qxl_bo_driver, 497 + qdev->ddev->anon_inode->i_mapping, 498 + DRM_FILE_PAGE_OFFSET, 0); 497 499 if (r) { 498 500 DRM_ERROR("failed initializing buffer object driver(%d).\n", r); 499 501 return r; ··· 520 518 ((unsigned)num_io_pages * PAGE_SIZE) / (1024 * 1024)); 521 519 DRM_INFO("qxl: %uM of Surface memory size\n", 522 520 (unsigned)qdev->surfaceram_size / (1024 * 1024)); 523 - if (unlikely(qdev->mman.bdev.dev_mapping == NULL)) 524 - qdev->mman.bdev.dev_mapping = qdev->ddev->dev_mapping; 525 521 r = qxl_ttm_debugfs_init(qdev); 526 522 if (r) { 527 523 DRM_ERROR("Failed to init debugfs\n");
-1
drivers/gpu/drm/radeon/radeon_object.c
··· 145 145 146 146 size = ALIGN(size, PAGE_SIZE); 147 147 148 - rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; 149 148 if (kernel) { 150 149 type = ttm_bo_type_kernel; 151 150 } else if (sg) {
+3 -2
drivers/gpu/drm/radeon/radeon_ttm.c
··· 707 707 /* No others user of address space so set it to 0 */ 708 708 r = ttm_bo_device_init(&rdev->mman.bdev, 709 709 rdev->mman.bo_global_ref.ref.object, 710 - &radeon_bo_driver, DRM_FILE_PAGE_OFFSET, 710 + &radeon_bo_driver, 711 + rdev->ddev->anon_inode->i_mapping, 712 + DRM_FILE_PAGE_OFFSET, 711 713 rdev->need_dma32); 712 714 if (r) { 713 715 DRM_ERROR("failed initializing buffer object driver(%d).\n", r); ··· 750 748 } 751 749 DRM_INFO("radeon: %uM of GTT memory ready.\n", 752 750 (unsigned)(rdev->mc.gtt_size / (1024 * 1024))); 753 - rdev->mman.bdev.dev_mapping = rdev->ddev->dev_mapping; 754 751 755 752 r = radeon_ttm_debugfs_init(rdev); 756 753 if (r) {
+2 -1
drivers/gpu/drm/ttm/ttm_bo.c
··· 1451 1451 int ttm_bo_device_init(struct ttm_bo_device *bdev, 1452 1452 struct ttm_bo_global *glob, 1453 1453 struct ttm_bo_driver *driver, 1454 + struct address_space *mapping, 1454 1455 uint64_t file_page_offset, 1455 1456 bool need_dma32) 1456 1457 { ··· 1473 1472 0x10000000); 1474 1473 INIT_DELAYED_WORK(&bdev->wq, ttm_bo_delayed_workqueue); 1475 1474 INIT_LIST_HEAD(&bdev->ddestroy); 1476 - bdev->dev_mapping = NULL; 1475 + bdev->dev_mapping = mapping; 1477 1476 bdev->glob = glob; 1478 1477 bdev->need_dma32 = need_dma32; 1479 1478 bdev->val_seq = 0;
+3 -2
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 722 722 723 723 ret = ttm_bo_device_init(&dev_priv->bdev, 724 724 dev_priv->bo_global_ref.ref.object, 725 - &vmw_bo_driver, VMWGFX_FILE_PAGE_OFFSET, 725 + &vmw_bo_driver, 726 + dev->anon_inode->i_mapping, 727 + VMWGFX_FILE_PAGE_OFFSET, 726 728 false); 727 729 if (unlikely(ret != 0)) { 728 730 DRM_ERROR("Failed initializing TTM buffer object driver.\n"); ··· 971 969 goto out_no_shman; 972 970 973 971 file_priv->driver_priv = vmw_fp; 974 - dev_priv->bdev.dev_mapping = dev->dev_mapping; 975 972 976 973 return 0; 977 974
+1
fs/dcache.c
··· 3112 3112 end = ERR_PTR(-ENAMETOOLONG); 3113 3113 return end; 3114 3114 } 3115 + EXPORT_SYMBOL(simple_dname); 3115 3116 3116 3117 /* 3117 3118 * Write full pathname from the root of the filesystem into the buffer.
+1 -1
include/drm/drmP.h
··· 1091 1091 struct device *dev; /**< Device structure of bus-device */ 1092 1092 struct drm_driver *driver; /**< DRM driver managing the device */ 1093 1093 void *dev_private; /**< DRM driver private data */ 1094 - struct address_space *dev_mapping; /**< Private addr-space just for the device */ 1095 1094 struct drm_minor *control; /**< Control node */ 1096 1095 struct drm_minor *primary; /**< Primary node */ 1097 1096 struct drm_minor *render; /**< Render node */ 1098 1097 atomic_t unplugged; /**< Flag whether dev is dead */ 1098 + struct inode *anon_inode; /**< inode for private address-space */ 1099 1099 /*@} */ 1100 1100 1101 1101 /** \name Locks */
+3 -3
include/drm/drm_vma_manager.h
··· 221 221 * @file_mapping: Address space to unmap @node from 222 222 * 223 223 * Unmap all userspace mappings for a given offset node. The mappings must be 224 - * associated with the @file_mapping address-space. If no offset exists or 225 - * the address-space is invalid, nothing is done. 224 + * associated with the @file_mapping address-space. If no offset exists 225 + * nothing is done. 226 226 * 227 227 * This call is unlocked. The caller must guarantee that drm_vma_offset_remove() 228 228 * is not called on this node concurrently. ··· 230 230 static inline void drm_vma_node_unmap(struct drm_vma_offset_node *node, 231 231 struct address_space *file_mapping) 232 232 { 233 - if (file_mapping && drm_vma_node_has_offset(node)) 233 + if (drm_vma_node_has_offset(node)) 234 234 unmap_mapping_range(file_mapping, 235 235 drm_vma_node_offset_addr(node), 236 236 drm_vma_node_size(node) << PAGE_SHIFT, 1);
+2
include/drm/ttm/ttm_bo_driver.h
··· 747 747 * @bdev: A pointer to a struct ttm_bo_device to initialize. 748 748 * @glob: A pointer to an initialized struct ttm_bo_global. 749 749 * @driver: A pointer to a struct ttm_bo_driver set up by the caller. 750 + * @mapping: The address space to use for this bo. 750 751 * @file_page_offset: Offset into the device address space that is available 751 752 * for buffer data. This ensures compatibility with other users of the 752 753 * address space. ··· 759 758 extern int ttm_bo_device_init(struct ttm_bo_device *bdev, 760 759 struct ttm_bo_global *glob, 761 760 struct ttm_bo_driver *driver, 761 + struct address_space *mapping, 762 762 uint64_t file_page_offset, bool need_dma32); 763 763 764 764 /**