Commit ef91082e authored by Daniel De Graaf's avatar Daniel De Graaf Committed by Konrad Rzeszutek Wilk

xen-gntdev: Change page limit to be global instead of per-open

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.

Xen tools changeset 22768:f8d801e5573e is needed to eliminate the
error this change produces in xc_gnttab_set_max_grants.
Signed-off-by: default avatarDaniel De Graaf <dgdegra@tycho.nsa.gov>
Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
parent 100b33c8
...@@ -45,15 +45,15 @@ MODULE_AUTHOR("Derek G. Murray <Derek.Murray@cl.cam.ac.uk>, " ...@@ -45,15 +45,15 @@ MODULE_AUTHOR("Derek G. Murray <Derek.Murray@cl.cam.ac.uk>, "
"Gerd Hoffmann <kraxel@redhat.com>"); "Gerd Hoffmann <kraxel@redhat.com>");
MODULE_DESCRIPTION("User-space granted page access driver"); MODULE_DESCRIPTION("User-space granted page access driver");
static int limit = 1024; static int limit = 1024*1024;
module_param(limit, int, 0644); module_param(limit, int, 0644);
MODULE_PARM_DESC(limit, "Maximum number of grants that may be mapped at " MODULE_PARM_DESC(limit, "Maximum number of grants that may be mapped by "
"once by a gntdev instance"); "the gntdev device");
static atomic_t pages_mapped = ATOMIC_INIT(0);
struct gntdev_priv { struct gntdev_priv {
struct list_head maps; struct list_head maps;
uint32_t used;
uint32_t limit;
/* lock protects maps from concurrent changes */ /* lock protects maps from concurrent changes */
spinlock_t lock; spinlock_t lock;
struct mm_struct *mm; struct mm_struct *mm;
...@@ -82,9 +82,7 @@ static void gntdev_print_maps(struct gntdev_priv *priv, ...@@ -82,9 +82,7 @@ static void gntdev_print_maps(struct gntdev_priv *priv,
#ifdef DEBUG #ifdef DEBUG
struct grant_map *map; struct grant_map *map;
pr_debug("maps list (priv %p, usage %d/%d)\n", pr_debug("%s: maps list (priv %p)\n", __func__, priv);
priv, priv->used, priv->limit);
list_for_each_entry(map, &priv->maps, next) list_for_each_entry(map, &priv->maps, next)
pr_debug(" index %2d, count %2d %s\n", pr_debug(" index %2d, count %2d %s\n",
map->index, map->count, map->index, map->count,
...@@ -121,9 +119,6 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count) ...@@ -121,9 +119,6 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
add->count = count; add->count = count;
add->priv = priv; add->priv = priv;
if (add->count + priv->used > priv->limit)
goto err;
return add; return add;
err: err:
...@@ -154,7 +149,6 @@ static void gntdev_add_map(struct gntdev_priv *priv, struct grant_map *add) ...@@ -154,7 +149,6 @@ static void gntdev_add_map(struct gntdev_priv *priv, struct grant_map *add)
list_add_tail(&add->next, &priv->maps); list_add_tail(&add->next, &priv->maps);
done: done:
priv->used += add->count;
gntdev_print_maps(priv, "[new]", add->index); gntdev_print_maps(priv, "[new]", add->index);
} }
...@@ -200,7 +194,7 @@ static int gntdev_del_map(struct grant_map *map) ...@@ -200,7 +194,7 @@ static int gntdev_del_map(struct grant_map *map)
if (map->unmap_ops[i].handle) if (map->unmap_ops[i].handle)
return -EBUSY; return -EBUSY;
map->priv->used -= map->count; atomic_sub(map->count, &pages_mapped);
list_del(&map->next); list_del(&map->next);
return 0; return 0;
} }
...@@ -386,7 +380,6 @@ static int gntdev_open(struct inode *inode, struct file *flip) ...@@ -386,7 +380,6 @@ static int gntdev_open(struct inode *inode, struct file *flip)
INIT_LIST_HEAD(&priv->maps); INIT_LIST_HEAD(&priv->maps);
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
priv->limit = limit;
priv->mm = get_task_mm(current); priv->mm = get_task_mm(current);
if (!priv->mm) { if (!priv->mm) {
...@@ -443,19 +436,24 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv, ...@@ -443,19 +436,24 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv,
pr_debug("priv %p, add %d\n", priv, op.count); pr_debug("priv %p, add %d\n", priv, op.count);
if (unlikely(op.count <= 0)) if (unlikely(op.count <= 0))
return -EINVAL; return -EINVAL;
if (unlikely(op.count > priv->limit))
return -EINVAL;
err = -ENOMEM; err = -ENOMEM;
map = gntdev_alloc_map(priv, op.count); map = gntdev_alloc_map(priv, op.count);
if (!map) if (!map)
return err; return err;
if (copy_from_user(map->grants, &u->refs, if (copy_from_user(map->grants, &u->refs,
sizeof(map->grants[0]) * op.count) != 0) { sizeof(map->grants[0]) * op.count) != 0) {
gntdev_free_map(map); gntdev_free_map(map);
return err; return err;
} }
if (unlikely(atomic_add_return(op.count, &pages_mapped) > limit)) {
pr_debug("can't map: over limit\n");
gntdev_free_map(map);
return err;
}
spin_lock(&priv->lock); spin_lock(&priv->lock);
gntdev_add_map(priv, map); gntdev_add_map(priv, map);
op.index = map->index << PAGE_SHIFT; op.index = map->index << PAGE_SHIFT;
...@@ -518,23 +516,6 @@ static long gntdev_ioctl_get_offset_for_vaddr(struct gntdev_priv *priv, ...@@ -518,23 +516,6 @@ static long gntdev_ioctl_get_offset_for_vaddr(struct gntdev_priv *priv,
return 0; 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;
pr_debug("priv %p, limit %d\n", priv, op.count);
if (op.count > limit)
return -E2BIG;
spin_lock(&priv->lock);
priv->limit = op.count;
spin_unlock(&priv->lock);
return 0;
}
static long gntdev_ioctl(struct file *flip, static long gntdev_ioctl(struct file *flip,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
...@@ -551,9 +532,6 @@ static long gntdev_ioctl(struct file *flip, ...@@ -551,9 +532,6 @@ static long gntdev_ioctl(struct file *flip,
case IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR: case IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR:
return gntdev_ioctl_get_offset_for_vaddr(priv, ptr); return gntdev_ioctl_get_offset_for_vaddr(priv, ptr);
case IOCTL_GNTDEV_SET_MAX_GRANTS:
return gntdev_ioctl_set_max_grants(priv, ptr);
default: default:
pr_debug("priv %p, unknown cmd %x\n", priv, cmd); pr_debug("priv %p, unknown cmd %x\n", priv, cmd);
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment