From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel De Graaf Subject: [PATCH 2/7] xen-gntdev: Change page limit to be global instead of per-open Date: Thu, 16 Dec 2010 19:17:38 -0500 Message-ID: <1292545063-32107-3-git-send-email-dgdegra@tycho.nsa.gov> References: <1292545063-32107-1-git-send-email-dgdegra@tycho.nsa.gov> Return-path: In-Reply-To: <1292545063-32107-1-git-send-email-dgdegra@tycho.nsa.gov> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: Daniel De Graaf , jeremy@goop.org, Ian.Campbell@citrix.com List-Id: xen-devel@lists.xenproject.org Because there is no limitation on how many times a user can open a given device file, an per-file-description limit on the number of pages granted offers little to no benefit. Change to a global limit and remove the ioctl() as the parameter can now be changed via sysfs. Signed-off-by: Daniel De Graaf --- drivers/xen/gntdev.c | 48 ++++++++++++++---------------------------------- 1 files changed, 14 insertions(+), 34 deletions(-) diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c index 387c5f1..7e21592 100644 --- a/drivers/xen/gntdev.c +++ b/drivers/xen/gntdev.c @@ -45,13 +45,12 @@ MODULE_DESCRIPTION("User-space granted page access driver"); static int debug = 0; module_param(debug, int, 0644); -static int limit = 1024; +static int limit = 1024*1024; module_param(limit, int, 0644); +static atomic_t pages_mapped = ATOMIC_INIT(0); struct gntdev_priv { struct list_head maps; - uint32_t used; - uint32_t limit; spinlock_t lock; struct mm_struct *mm; struct mmu_notifier mn; @@ -78,8 +77,8 @@ static void gntdev_print_maps(struct gntdev_priv *priv, { struct grant_map *map; - printk("%s: maps list (priv %p, usage %d/%d)\n", - __FUNCTION__, priv, priv->used, priv->limit); + printk("%s: maps list (priv %p)\n", + __FUNCTION__, priv); list_for_each_entry(map, &priv->maps, next) printk(" index %2d, count %2d %s\n", map->index, map->count, @@ -115,9 +114,6 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) add->count = count; add->priv = priv; - if (add->count + priv->used > priv->limit) - goto err; - return add; err: @@ -148,7 +144,6 @@ static void gntdev_add_map(struct gntdev_priv *priv, struct grant_map *add) list_add_tail(&add->next, &priv->maps); done: - priv->used += add->count; if (debug) gntdev_print_maps(priv, "[new]", add->index); } @@ -195,7 +190,7 @@ static int gntdev_del_map(struct grant_map *map) if (map->unmap_ops[i].handle) return -EBUSY; - map->priv->used -= map->count; + atomic_sub(map->count, &pages_mapped); list_del(&map->next); return 0; } @@ -386,7 +381,6 @@ static int gntdev_open(struct inode *inode, struct file *flip) INIT_LIST_HEAD(&priv->maps); spin_lock_init(&priv->lock); - priv->limit = limit; priv->mm = get_task_mm(current); if (!priv->mm) { @@ -442,19 +436,26 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv, op.count); if (unlikely(op.count <= 0)) return -EINVAL; - if (unlikely(op.count > priv->limit)) - return -EINVAL; err = -ENOMEM; map = gntdev_alloc_map(priv, op.count); if (!map) return err; + if (copy_from_user(map->grants, &u->refs, sizeof(map->grants[0]) * op.count) != 0) { gntdev_free_map(map); return err; } + if (unlikely(atomic_add_return(op.count, &pages_mapped) > limit)) + { + if (debug) + printk("%s: can't map: over limit\n", __FUNCTION__); + gntdev_free_map(map); + return err; + } + spin_lock(&priv->lock); gntdev_add_map(priv, map); op.index = map->index << PAGE_SHIFT; @@ -521,24 +522,6 @@ static long gntdev_ioctl_get_offset_for_vaddr(struct gntdev_priv *priv, return 0; } -static long gntdev_ioctl_set_max_grants(struct gntdev_priv *priv, - struct ioctl_gntdev_set_max_grants __user *u) -{ - struct ioctl_gntdev_set_max_grants op; - - if (copy_from_user(&op, u, sizeof(op)) != 0) - return -EFAULT; - if (debug) - printk("%s: priv %p, limit %d\n", __FUNCTION__, priv, op.count); - if (op.count > limit) - return -EINVAL; - - spin_lock(&priv->lock); - priv->limit = op.count; - spin_unlock(&priv->lock); - return 0; -} - static long gntdev_ioctl(struct file *flip, unsigned int cmd, unsigned long arg) { @@ -555,9 +538,6 @@ static long gntdev_ioctl(struct file *flip, case IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR: return gntdev_ioctl_get_offset_for_vaddr(priv, ptr); - case IOCTL_GNTDEV_SET_MAX_GRANTS: - return gntdev_ioctl_set_max_grants(priv, ptr); - default: if (debug) printk("%s: priv %p, unknown cmd %x\n", -- 1.7.2.3