On Sat, Jan 31, 2015 at 11:02:05AM -0500, Rob Clark wrote: > On Fri, Jan 30, 2015 at 1:05 PM, Zach Reizner <zachr@xxxxxxxxxx> wrote: > > This patch implements the virtual GEM driver with PRIME sharing which > > allows vgem to import a gem object from other drivers for the purpose > > of mmap-ing them to userspace. The mmap is done using the mmap > > operation exported by other drivers. > > > > v2: remove platform_device and do not attach to dma bufs > > > > Reviewed-by: Stéphane Marchesin <marcheu@xxxxxxxxxxxx> > > Signed-off-by: Adam Jackson <ajax@xxxxxxxxxx> > > Signed-off-by: Ben Widawsky <ben@xxxxxxxxxxxx> > > Signed-off-by: Zach Reizner <zachr@xxxxxxxxxx> > > couple small suggestions/comments below, but with those addressed, > > Reviewed-by: Rob Clark <robdclark@xxxxxxxxx> > > > --- > > drivers/gpu/drm/Kconfig | 9 + > > drivers/gpu/drm/Makefile | 1 + > > drivers/gpu/drm/vgem/Makefile | 4 + > > drivers/gpu/drm/vgem/vgem_dma_buf.c | 96 +++++++++ > > drivers/gpu/drm/vgem/vgem_drv.c | 390 ++++++++++++++++++++++++++++++++++++ > > drivers/gpu/drm/vgem/vgem_drv.h | 57 ++++++ > > 6 files changed, 557 insertions(+) > > create mode 100644 drivers/gpu/drm/vgem/Makefile > > create mode 100644 drivers/gpu/drm/vgem/vgem_dma_buf.c > > create mode 100644 drivers/gpu/drm/vgem/vgem_drv.c > > create mode 100644 drivers/gpu/drm/vgem/vgem_drv.h > > > > [snip] > > > diff --git a/drivers/gpu/drm/vgem/vgem_drv.c b/drivers/gpu/drm/vgem/vgem_drv.c > > new file mode 100644 > > index 0000000..e20f4a4 > > --- /dev/null > > +++ b/drivers/gpu/drm/vgem/vgem_drv.c > > @@ -0,0 +1,390 @@ > > +/* > > + * Copyright 2011 Red Hat, Inc. > > + * Copyright © 2014 The Chromium OS Authors > > + * > > + * Permission is hereby granted, free of charge, to any person obtaining a > > + * copy of this software and associated documentation files (the "Software") > > + * to deal in the software without restriction, including without limitation > > + * on the rights to use, copy, modify, merge, publish, distribute, sub > > + * license, and/or sell copies of the Software, and to permit persons to whom > > + * them Software is furnished to do so, subject to the following conditions: > > + * > > + * The above copyright notice and this permission notice (including the next > > + * paragraph) shall be included in all copies or substantial portions of the > > + * Software. > > + * > > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTIBILITY, > > + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL > > + * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER > > + * IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF OR IN > > + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > > + * > > + * Authors: > > + * Adam Jackson <ajax@xxxxxxxxxx> > > + * Ben Widawsky <ben@xxxxxxxxxxxx> > > + */ > > + > > +/** > > + * This is vgem, a (non-hardware-backed) GEM service. This is used by Mesa's > > + * software renderer and the X server for efficient buffer sharing. > > + */ > > + > > +#include <linux/module.h> > > +#include <linux/ramfs.h> > > +#include <linux/shmem_fs.h> > > +#include <linux/dma-buf.h> > > +#include "vgem_drv.h" > > + > > +#define DRIVER_NAME "vgem" > > +#define DRIVER_DESC "Virtual GEM provider" > > +#define DRIVER_DATE "20120112" > > +#define DRIVER_MAJOR 1 > > +#define DRIVER_MINOR 0 > > + > > +void vgem_gem_put_pages(struct drm_vgem_gem_object *obj) > > +{ > > + int num_pages = obj->base.size / PAGE_SIZE; > > + int i; > > + > > + for (i = 0; i < num_pages; i++) { > > + if (obj->pages[i] == NULL) > > + break; > > seems like other than this break statement, you could use > drm_gem_put_pages().. not entirely sure why you'd encounter a null > page, but if there is a legit reason for that, then just add the check > in drm_gem_put_pages() (plus maybe a comment) and use that.. > First, this code predated drm_gem_put_pages, so it was probably just an oversight that a consolidated function existed. As for the NULL, it's because the cleanup of failed vgem get_pages() just calls vgem put_pages() (you can't have sparsely populated entries, but the last n pointers can be NULL). If the helpers just dtrt, then it should use that. > > + page_cache_release(obj->pages[i]); > > + } > > + > > + drm_free_large(obj->pages); > > + obj->pages = NULL; > > +} > > + > > +static void vgem_gem_free_object(struct drm_gem_object *obj) > > +{ > > + struct drm_vgem_gem_object *vgem_obj = to_vgem_bo(obj); > > + > > + drm_gem_free_mmap_offset(obj); > > + > > + if (vgem_obj->use_dma_buf && obj->dma_buf) { > > + dma_buf_put(obj->dma_buf); > > + obj->dma_buf = NULL; > > + } > > + > > + drm_gem_object_release(obj); > > + > > + if (vgem_obj->pages) > > + vgem_gem_put_pages(vgem_obj); > > + > > + vgem_obj->pages = NULL; > > + > > + kfree(vgem_obj); > > +} > > + > > +int vgem_gem_get_pages(struct drm_vgem_gem_object *obj) > > +{ > > + struct address_space *mapping; > > + gfp_t gfpmask = GFP_KERNEL; > > + int num_pages, i, ret = 0; > > + > > + if (obj->pages || obj->use_dma_buf) > > + return 0; > > + > > + num_pages = obj->base.size / PAGE_SIZE; > > + obj->pages = drm_malloc_ab(num_pages, sizeof(struct page *)); > > + if (obj->pages == NULL) > > + return -ENOMEM; > > + > > + mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; > > again, seems like you could use drm_gem_get_pages().. although you get > the mapping in a slightly different way.. not sure if that was > intentional? > Again, this predates the helpers :D My original patches on top of ajax were from Feb. 2012. Helpers seem like the right thing to do now. > BR, > -R > > > + gfpmask |= mapping_gfp_mask(mapping); > > + > > + for (i = 0; i < num_pages; i++) { > > + struct page *page; > > + obj->pages[i] = NULL; > > + page = shmem_read_mapping_page_gfp(mapping, i, gfpmask); > > + if (IS_ERR(page)) { > > + ret = PTR_ERR(page); > > + goto err_out; > > + } > > + obj->pages[i] = page; > > + } > > + > > + return ret; > > + > > +err_out: > > + vgem_gem_put_pages(obj); > > + return ret; > > +} > > + _______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/dri-devel