aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_gem.c
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2014-05-25 06:59:47 -0400
committerDavid Herrmann <dh.herrmann@gmail.com>2014-07-07 18:29:53 -0400
commit0cdbe8ac696b5399327f972a1c91263c1a44f1d9 (patch)
tree7ba5705585c5de981a11e41935cd66ad88ce285c /drivers/gpu/drm/drm_gem.c
parentab5a60c3ee41ff22304e2bcf63c151aa2851df0c (diff)
drm/gem: remove misleading gfp parameter to get_pages()
drm_gem_get_pages() currently allows passing a 'gfp' parameter that is passed to shmem combined with mapping_gfp_mask(). Given that the default mapping_gfp_mask() is GFP_HIGHUSER, it is _very_ unlikely that anyone will ever make use of that parameter. In fact, all drivers currently pass redundant flags or 0. This patch removes the 'gfp' parameter. The only reason to keep it is to remove flags like __GFP_WAIT. But in its current form, it can only be used to add flags. So to remove __GFP_WAIT, you'd have to drop it from the mapping_gfp_mask, which again is stupid as this mask is used by shmem-core for other allocations, too. If any driver ever requires that parameter, we can introduce a new helper that takes the raw 'gfp' parameter. The caller'd be responsible to combine it with mapping_gfp_mask() in a suitable way. The current drm_gem_get_pages() helper would then simply use mapping_gfp_mask() and call the new helper. This is what shmem_read_mapping_pages{_gfp,} does right now. Moreover, the gfp-zone flag-usage is not obvious: If you pass a modified zone, shmem core will WARN() or even BUG(). In other words, the following must be true for 'gfp' passed to shmem_read_mapping_pages_gfp(): gfp_zone(mapping_gfp_mask(mapping)) == gfp_zone(gfp) Add a comment to drm_gem_read_pages() explaining that constraint. Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/drm_gem.c')
-rw-r--r--drivers/gpu/drm/drm_gem.c29
1 files changed, 20 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index f7d71190aad5..6adee4c2afc0 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -441,18 +441,31 @@ EXPORT_SYMBOL(drm_gem_create_mmap_offset);
441 * drm_gem_get_pages - helper to allocate backing pages for a GEM object 441 * drm_gem_get_pages - helper to allocate backing pages for a GEM object
442 * from shmem 442 * from shmem
443 * @obj: obj in question 443 * @obj: obj in question
444 * @gfpmask: gfp mask of requested pages 444 *
445 * This reads the page-array of the shmem-backing storage of the given gem
446 * object. An array of pages is returned. If a page is not allocated or
447 * swapped-out, this will allocate/swap-in the required pages. Note that the
448 * whole object is covered by the page-array and pinned in memory.
449 *
450 * Use drm_gem_put_pages() to release the array and unpin all pages.
451 *
452 * This uses the GFP-mask set on the shmem-mapping (see mapping_set_gfp_mask()).
453 * If you require other GFP-masks, you have to do those allocations yourself.
454 *
455 * Note that you are not allowed to change gfp-zones during runtime. That is,
456 * shmem_read_mapping_page_gfp() must be called with the same gfp_zone(gfp) as
457 * set during initialization. If you have special zone constraints, set them
458 * after drm_gem_init_object() via mapping_set_gfp_mask(). shmem-core takes care
459 * to keep pages in the required zone during swap-in.
445 */ 460 */
446struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask) 461struct page **drm_gem_get_pages(struct drm_gem_object *obj)
447{ 462{
448 struct inode *inode;
449 struct address_space *mapping; 463 struct address_space *mapping;
450 struct page *p, **pages; 464 struct page *p, **pages;
451 int i, npages; 465 int i, npages;
452 466
453 /* This is the shared memory object that backs the GEM resource */ 467 /* This is the shared memory object that backs the GEM resource */
454 inode = file_inode(obj->filp); 468 mapping = file_inode(obj->filp)->i_mapping;
455 mapping = inode->i_mapping;
456 469
457 /* We already BUG_ON() for non-page-aligned sizes in 470 /* We already BUG_ON() for non-page-aligned sizes in
458 * drm_gem_object_init(), so we should never hit this unless 471 * drm_gem_object_init(), so we should never hit this unless
@@ -466,10 +479,8 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
466 if (pages == NULL) 479 if (pages == NULL)
467 return ERR_PTR(-ENOMEM); 480 return ERR_PTR(-ENOMEM);
468 481
469 gfpmask |= mapping_gfp_mask(mapping);
470
471 for (i = 0; i < npages; i++) { 482 for (i = 0; i < npages; i++) {
472 p = shmem_read_mapping_page_gfp(mapping, i, gfpmask); 483 p = shmem_read_mapping_page(mapping, i);
473 if (IS_ERR(p)) 484 if (IS_ERR(p))
474 goto fail; 485 goto fail;
475 pages[i] = p; 486 pages[i] = p;
@@ -479,7 +490,7 @@ struct page **drm_gem_get_pages(struct drm_gem_object *obj, gfp_t gfpmask)
479 * __GFP_DMA32 to be set in mapping_gfp_mask(inode->i_mapping) 490 * __GFP_DMA32 to be set in mapping_gfp_mask(inode->i_mapping)
480 * so shmem can relocate pages during swapin if required. 491 * so shmem can relocate pages during swapin if required.
481 */ 492 */
482 BUG_ON((gfpmask & __GFP_DMA32) && 493 BUG_ON((mapping_gfp_mask(mapping) & __GFP_DMA32) &&
483 (page_to_pfn(p) >= 0x00100000UL)); 494 (page_to_pfn(p) >= 0x00100000UL));
484 } 495 }
485 496