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.. > + 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? 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