aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel De Graaf <dgdegra@tycho.nsa.gov>2011-02-03 12:18:59 -0500
committerKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>2011-02-14 14:08:49 -0500
commitef91082e90491ac99343a13f9aeff4669835c6cc (patch)
treed5b293c5e27225f6631c402f36ccdb9ebac25d1b
parent100b33c8bd8a3235fd0b7948338d6cbb3db3c63d (diff)
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: Daniel De Graaf <dgdegra@tycho.nsa.gov> Signed-off-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
-rw-r--r--drivers/xen/gntdev.c50
1 files changed, 14 insertions, 36 deletions
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index 1e31cdcdae1e..23d208a219fa 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -45,15 +45,15 @@ MODULE_AUTHOR("Derek G. Murray <Derek.Murray@cl.cam.ac.uk>, "
45 "Gerd Hoffmann <kraxel@redhat.com>"); 45 "Gerd Hoffmann <kraxel@redhat.com>");
46MODULE_DESCRIPTION("User-space granted page access driver"); 46MODULE_DESCRIPTION("User-space granted page access driver");
47 47
48static int limit = 1024; 48static int limit = 1024*1024;
49module_param(limit, int, 0644); 49module_param(limit, int, 0644);
50MODULE_PARM_DESC(limit, "Maximum number of grants that may be mapped at " 50MODULE_PARM_DESC(limit, "Maximum number of grants that may be mapped by "
51 "once by a gntdev instance"); 51 "the gntdev device");
52
53static atomic_t pages_mapped = ATOMIC_INIT(0);
52 54
53struct gntdev_priv { 55struct gntdev_priv {
54 struct list_head maps; 56 struct list_head maps;
55 uint32_t used;
56 uint32_t limit;
57 /* lock protects maps from concurrent changes */ 57 /* lock protects maps from concurrent changes */
58 spinlock_t lock; 58 spinlock_t lock;
59 struct mm_struct *mm; 59 struct mm_struct *mm;
@@ -82,9 +82,7 @@ static void gntdev_print_maps(struct gntdev_priv *priv,
82#ifdef DEBUG 82#ifdef DEBUG
83 struct grant_map *map; 83 struct grant_map *map;
84 84
85 pr_debug("maps list (priv %p, usage %d/%d)\n", 85 pr_debug("%s: maps list (priv %p)\n", __func__, priv);
86 priv, priv->used, priv->limit);
87
88 list_for_each_entry(map, &priv->maps, next) 86 list_for_each_entry(map, &priv->maps, next)
89 pr_debug(" index %2d, count %2d %s\n", 87 pr_debug(" index %2d, count %2d %s\n",
90 map->index, map->count, 88 map->index, map->count,
@@ -121,9 +119,6 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
121 add->count = count; 119 add->count = count;
122 add->priv = priv; 120 add->priv = priv;
123 121
124 if (add->count + priv->used > priv->limit)
125 goto err;
126
127 return add; 122 return add;
128 123
129err: 124err:
@@ -154,7 +149,6 @@ static void gntdev_add_map(struct gntdev_priv *priv, struct grant_map *add)
154 list_add_tail(&add->next, &priv->maps); 149 list_add_tail(&add->next, &priv->maps);
155 150
156done: 151done:
157 priv->used += add->count;
158 gntdev_print_maps(priv, "[new]", add->index); 152 gntdev_print_maps(priv, "[new]", add->index);
159} 153}
160 154
@@ -200,7 +194,7 @@ static int gntdev_del_map(struct grant_map *map)
200 if (map->unmap_ops[i].handle) 194 if (map->unmap_ops[i].handle)
201 return -EBUSY; 195 return -EBUSY;
202 196
203 map->priv->used -= map->count; 197 atomic_sub(map->count, &pages_mapped);
204 list_del(&map->next); 198 list_del(&map->next);
205 return 0; 199 return 0;
206} 200}
@@ -386,7 +380,6 @@ static int gntdev_open(struct inode *inode, struct file *flip)
386 380
387 INIT_LIST_HEAD(&priv->maps); 381 INIT_LIST_HEAD(&priv->maps);
388 spin_lock_init(&priv->lock); 382 spin_lock_init(&priv->lock);
389 priv->limit = limit;
390 383
391 priv->mm = get_task_mm(current); 384 priv->mm = get_task_mm(current);
392 if (!priv->mm) { 385 if (!priv->mm) {
@@ -443,19 +436,24 @@ static long gntdev_ioctl_map_grant_ref(struct gntdev_priv *priv,
443 pr_debug("priv %p, add %d\n", priv, op.count); 436 pr_debug("priv %p, add %d\n", priv, op.count);
444 if (unlikely(op.count <= 0)) 437 if (unlikely(op.count <= 0))
445 return -EINVAL; 438 return -EINVAL;
446 if (unlikely(op.count > priv->limit))
447 return -EINVAL;
448 439
449 err = -ENOMEM; 440 err = -ENOMEM;
450 map = gntdev_alloc_map(priv, op.count); 441 map = gntdev_alloc_map(priv, op.count);
451 if (!map) 442 if (!map)
452 return err; 443 return err;
444
453 if (copy_from_user(map->grants, &u->refs, 445 if (copy_from_user(map->grants, &u->refs,
454 sizeof(map->grants[0]) * op.count) != 0) { 446 sizeof(map->grants[0]) * op.count) != 0) {
455 gntdev_free_map(map); 447 gntdev_free_map(map);
456 return err; 448 return err;
457 } 449 }
458 450
451 if (unlikely(atomic_add_return(op.count, &pages_mapped) > limit)) {
452 pr_debug("can't map: over limit\n");
453 gntdev_free_map(map);
454 return err;
455 }
456
459 spin_lock(&priv->lock); 457 spin_lock(&priv->lock);
460 gntdev_add_map(priv, map); 458 gntdev_add_map(priv, map);
461 op.index = map->index << PAGE_SHIFT; 459 op.index = map->index << PAGE_SHIFT;
@@ -518,23 +516,6 @@ static long gntdev_ioctl_get_offset_for_vaddr(struct gntdev_priv *priv,
518 return 0; 516 return 0;
519} 517}
520 518
521static long gntdev_ioctl_set_max_grants(struct gntdev_priv *priv,
522 struct ioctl_gntdev_set_max_grants __user *u)
523{
524 struct ioctl_gntdev_set_max_grants op;
525
526 if (copy_from_user(&op, u, sizeof(op)) != 0)
527 return -EFAULT;
528 pr_debug("priv %p, limit %d\n", priv, op.count);
529 if (op.count > limit)
530 return -E2BIG;
531
532 spin_lock(&priv->lock);
533 priv->limit = op.count;
534 spin_unlock(&priv->lock);
535 return 0;
536}
537
538static long gntdev_ioctl(struct file *flip, 519static long gntdev_ioctl(struct file *flip,
539 unsigned int cmd, unsigned long arg) 520 unsigned int cmd, unsigned long arg)
540{ 521{
@@ -551,9 +532,6 @@ static long gntdev_ioctl(struct file *flip,
551 case IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR: 532 case IOCTL_GNTDEV_GET_OFFSET_FOR_VADDR:
552 return gntdev_ioctl_get_offset_for_vaddr(priv, ptr); 533 return gntdev_ioctl_get_offset_for_vaddr(priv, ptr);
553 534
554 case IOCTL_GNTDEV_SET_MAX_GRANTS:
555 return gntdev_ioctl_set_max_grants(priv, ptr);
556
557 default: 535 default:
558 pr_debug("priv %p, unknown cmd %x\n", priv, cmd); 536 pr_debug("priv %p, unknown cmd %x\n", priv, cmd);
559 return -ENOIOCTLCMD; 537 return -ENOIOCTLCMD;