aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/xen
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/xen')
-rw-r--r--drivers/xen/balloon.c12
-rw-r--r--drivers/xen/events.c10
-rw-r--r--drivers/xen/gntdev.c39
-rw-r--r--drivers/xen/grant-table.c6
-rw-r--r--drivers/xen/xen-selfballoon.c67
-rw-r--r--drivers/xen/xenbus/xenbus_probe_backend.c2
6 files changed, 114 insertions, 22 deletions
diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
index fc43b53651d7..5876e1ae6c2d 100644
--- a/drivers/xen/balloon.c
+++ b/drivers/xen/balloon.c
@@ -501,20 +501,24 @@ EXPORT_SYMBOL_GPL(balloon_set_new_target);
501 * alloc_xenballooned_pages - get pages that have been ballooned out 501 * alloc_xenballooned_pages - get pages that have been ballooned out
502 * @nr_pages: Number of pages to get 502 * @nr_pages: Number of pages to get
503 * @pages: pages returned 503 * @pages: pages returned
504 * @highmem: highmem or lowmem pages
504 * @return 0 on success, error otherwise 505 * @return 0 on success, error otherwise
505 */ 506 */
506int alloc_xenballooned_pages(int nr_pages, struct page** pages) 507int alloc_xenballooned_pages(int nr_pages, struct page **pages, bool highmem)
507{ 508{
508 int pgno = 0; 509 int pgno = 0;
509 struct page* page; 510 struct page* page;
510 mutex_lock(&balloon_mutex); 511 mutex_lock(&balloon_mutex);
511 while (pgno < nr_pages) { 512 while (pgno < nr_pages) {
512 page = balloon_retrieve(true); 513 page = balloon_retrieve(highmem);
513 if (page) { 514 if (page && PageHighMem(page) == highmem) {
514 pages[pgno++] = page; 515 pages[pgno++] = page;
515 } else { 516 } else {
516 enum bp_state st; 517 enum bp_state st;
517 st = decrease_reservation(nr_pages - pgno, GFP_HIGHUSER); 518 if (page)
519 balloon_append(page);
520 st = decrease_reservation(nr_pages - pgno,
521 highmem ? GFP_HIGHUSER : GFP_USER);
518 if (st != BP_DONE) 522 if (st != BP_DONE)
519 goto out_undo; 523 goto out_undo;
520 } 524 }
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index 7523719bf8a4..212a5c871bf4 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -432,7 +432,8 @@ static int __must_check xen_allocate_irq_dynamic(void)
432 432
433 irq = irq_alloc_desc_from(first, -1); 433 irq = irq_alloc_desc_from(first, -1);
434 434
435 xen_irq_init(irq); 435 if (irq >= 0)
436 xen_irq_init(irq);
436 437
437 return irq; 438 return irq;
438} 439}
@@ -713,7 +714,7 @@ int xen_bind_pirq_msi_to_irq(struct pci_dev *dev, struct msi_desc *msidesc,
713 mutex_lock(&irq_mapping_update_lock); 714 mutex_lock(&irq_mapping_update_lock);
714 715
715 irq = xen_allocate_irq_dynamic(); 716 irq = xen_allocate_irq_dynamic();
716 if (irq == -1) 717 if (irq < 0)
717 goto out; 718 goto out;
718 719
719 irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq, 720 irq_set_chip_and_handler_name(irq, &xen_pirq_chip, handle_edge_irq,
@@ -729,7 +730,7 @@ out:
729error_irq: 730error_irq:
730 mutex_unlock(&irq_mapping_update_lock); 731 mutex_unlock(&irq_mapping_update_lock);
731 xen_free_irq(irq); 732 xen_free_irq(irq);
732 return -1; 733 return ret;
733} 734}
734#endif 735#endif
735 736
@@ -779,7 +780,7 @@ int xen_irq_from_pirq(unsigned pirq)
779 mutex_lock(&irq_mapping_update_lock); 780 mutex_lock(&irq_mapping_update_lock);
780 781
781 list_for_each_entry(info, &xen_irq_list_head, list) { 782 list_for_each_entry(info, &xen_irq_list_head, list) {
782 if (info == NULL || info->type != IRQT_PIRQ) 783 if (info->type != IRQT_PIRQ)
783 continue; 784 continue;
784 irq = info->irq; 785 irq = info->irq;
785 if (info->u.pirq.pirq == pirq) 786 if (info->u.pirq.pirq == pirq)
@@ -1670,6 +1671,7 @@ void __init xen_init_IRQ(void)
1670 1671
1671 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), 1672 evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq),
1672 GFP_KERNEL); 1673 GFP_KERNEL);
1674 BUG_ON(!evtchn_to_irq);
1673 for (i = 0; i < NR_EVENT_CHANNELS; i++) 1675 for (i = 0; i < NR_EVENT_CHANNELS; i++)
1674 evtchn_to_irq[i] = -1; 1676 evtchn_to_irq[i] = -1;
1675 1677
diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c
index f914b26cf0c2..880798aae2f2 100644
--- a/drivers/xen/gntdev.c
+++ b/drivers/xen/gntdev.c
@@ -83,6 +83,7 @@ struct grant_map {
83 struct ioctl_gntdev_grant_ref *grants; 83 struct ioctl_gntdev_grant_ref *grants;
84 struct gnttab_map_grant_ref *map_ops; 84 struct gnttab_map_grant_ref *map_ops;
85 struct gnttab_unmap_grant_ref *unmap_ops; 85 struct gnttab_unmap_grant_ref *unmap_ops;
86 struct gnttab_map_grant_ref *kmap_ops;
86 struct page **pages; 87 struct page **pages;
87}; 88};
88 89
@@ -116,19 +117,22 @@ static struct grant_map *gntdev_alloc_map(struct gntdev_priv *priv, int count)
116 add->grants = kzalloc(sizeof(add->grants[0]) * count, GFP_KERNEL); 117 add->grants = kzalloc(sizeof(add->grants[0]) * count, GFP_KERNEL);
117 add->map_ops = kzalloc(sizeof(add->map_ops[0]) * count, GFP_KERNEL); 118 add->map_ops = kzalloc(sizeof(add->map_ops[0]) * count, GFP_KERNEL);
118 add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL); 119 add->unmap_ops = kzalloc(sizeof(add->unmap_ops[0]) * count, GFP_KERNEL);
120 add->kmap_ops = kzalloc(sizeof(add->kmap_ops[0]) * count, GFP_KERNEL);
119 add->pages = kzalloc(sizeof(add->pages[0]) * count, GFP_KERNEL); 121 add->pages = kzalloc(sizeof(add->pages[0]) * count, GFP_KERNEL);
120 if (NULL == add->grants || 122 if (NULL == add->grants ||
121 NULL == add->map_ops || 123 NULL == add->map_ops ||
122 NULL == add->unmap_ops || 124 NULL == add->unmap_ops ||
125 NULL == add->kmap_ops ||
123 NULL == add->pages) 126 NULL == add->pages)
124 goto err; 127 goto err;
125 128
126 if (alloc_xenballooned_pages(count, add->pages)) 129 if (alloc_xenballooned_pages(count, add->pages, false /* lowmem */))
127 goto err; 130 goto err;
128 131
129 for (i = 0; i < count; i++) { 132 for (i = 0; i < count; i++) {
130 add->map_ops[i].handle = -1; 133 add->map_ops[i].handle = -1;
131 add->unmap_ops[i].handle = -1; 134 add->unmap_ops[i].handle = -1;
135 add->kmap_ops[i].handle = -1;
132 } 136 }
133 137
134 add->index = 0; 138 add->index = 0;
@@ -142,6 +146,7 @@ err:
142 kfree(add->grants); 146 kfree(add->grants);
143 kfree(add->map_ops); 147 kfree(add->map_ops);
144 kfree(add->unmap_ops); 148 kfree(add->unmap_ops);
149 kfree(add->kmap_ops);
145 kfree(add); 150 kfree(add);
146 return NULL; 151 return NULL;
147} 152}
@@ -243,10 +248,35 @@ static int map_grant_pages(struct grant_map *map)
243 gnttab_set_unmap_op(&map->unmap_ops[i], addr, 248 gnttab_set_unmap_op(&map->unmap_ops[i], addr,
244 map->flags, -1 /* handle */); 249 map->flags, -1 /* handle */);
245 } 250 }
251 } else {
252 /*
253 * Setup the map_ops corresponding to the pte entries pointing
254 * to the kernel linear addresses of the struct pages.
255 * These ptes are completely different from the user ptes dealt
256 * with find_grant_ptes.
257 */
258 for (i = 0; i < map->count; i++) {
259 unsigned level;
260 unsigned long address = (unsigned long)
261 pfn_to_kaddr(page_to_pfn(map->pages[i]));
262 pte_t *ptep;
263 u64 pte_maddr = 0;
264 BUG_ON(PageHighMem(map->pages[i]));
265
266 ptep = lookup_address(address, &level);
267 pte_maddr = arbitrary_virt_to_machine(ptep).maddr;
268 gnttab_set_map_op(&map->kmap_ops[i], pte_maddr,
269 map->flags |
270 GNTMAP_host_map |
271 GNTMAP_contains_pte,
272 map->grants[i].ref,
273 map->grants[i].domid);
274 }
246 } 275 }
247 276
248 pr_debug("map %d+%d\n", map->index, map->count); 277 pr_debug("map %d+%d\n", map->index, map->count);
249 err = gnttab_map_refs(map->map_ops, map->pages, map->count); 278 err = gnttab_map_refs(map->map_ops, use_ptemod ? map->kmap_ops : NULL,
279 map->pages, map->count);
250 if (err) 280 if (err)
251 return err; 281 return err;
252 282
@@ -462,13 +492,11 @@ static int gntdev_release(struct inode *inode, struct file *flip)
462 492
463 pr_debug("priv %p\n", priv); 493 pr_debug("priv %p\n", priv);
464 494
465 spin_lock(&priv->lock);
466 while (!list_empty(&priv->maps)) { 495 while (!list_empty(&priv->maps)) {
467 map = list_entry(priv->maps.next, struct grant_map, next); 496 map = list_entry(priv->maps.next, struct grant_map, next);
468 list_del(&map->next); 497 list_del(&map->next);
469 gntdev_put_map(map); 498 gntdev_put_map(map);
470 } 499 }
471 spin_unlock(&priv->lock);
472 500
473 if (use_ptemod) 501 if (use_ptemod)
474 mmu_notifier_unregister(&priv->mn, priv->mm); 502 mmu_notifier_unregister(&priv->mn, priv->mm);
@@ -532,10 +560,11 @@ static long gntdev_ioctl_unmap_grant_ref(struct gntdev_priv *priv,
532 map = gntdev_find_map_index(priv, op.index >> PAGE_SHIFT, op.count); 560 map = gntdev_find_map_index(priv, op.index >> PAGE_SHIFT, op.count);
533 if (map) { 561 if (map) {
534 list_del(&map->next); 562 list_del(&map->next);
535 gntdev_put_map(map);
536 err = 0; 563 err = 0;
537 } 564 }
538 spin_unlock(&priv->lock); 565 spin_unlock(&priv->lock);
566 if (map)
567 gntdev_put_map(map);
539 return err; 568 return err;
540} 569}
541 570
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
index 4f44b347b24a..8c71ab801756 100644
--- a/drivers/xen/grant-table.c
+++ b/drivers/xen/grant-table.c
@@ -448,7 +448,8 @@ unsigned int gnttab_max_grant_frames(void)
448EXPORT_SYMBOL_GPL(gnttab_max_grant_frames); 448EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
449 449
450int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops, 450int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
451 struct page **pages, unsigned int count) 451 struct gnttab_map_grant_ref *kmap_ops,
452 struct page **pages, unsigned int count)
452{ 453{
453 int i, ret; 454 int i, ret;
454 pte_t *pte; 455 pte_t *pte;
@@ -488,8 +489,7 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
488 */ 489 */
489 return -EOPNOTSUPP; 490 return -EOPNOTSUPP;
490 } 491 }
491 ret = m2p_add_override(mfn, pages[i], 492 ret = m2p_add_override(mfn, pages[i], &kmap_ops[i]);
492 map_ops[i].flags & GNTMAP_contains_pte);
493 if (ret) 493 if (ret)
494 return ret; 494 return ret;
495 } 495 }
diff --git a/drivers/xen/xen-selfballoon.c b/drivers/xen/xen-selfballoon.c
index 6ea852e25162..d93c70857e03 100644
--- a/drivers/xen/xen-selfballoon.c
+++ b/drivers/xen/xen-selfballoon.c
@@ -68,6 +68,8 @@
68 */ 68 */
69 69
70#include <linux/kernel.h> 70#include <linux/kernel.h>
71#include <linux/bootmem.h>
72#include <linux/swap.h>
71#include <linux/mm.h> 73#include <linux/mm.h>
72#include <linux/mman.h> 74#include <linux/mman.h>
73#include <linux/module.h> 75#include <linux/module.h>
@@ -93,6 +95,15 @@ static unsigned int selfballoon_uphysteresis __read_mostly = 1;
93/* In HZ, controls frequency of worker invocation. */ 95/* In HZ, controls frequency of worker invocation. */
94static unsigned int selfballoon_interval __read_mostly = 5; 96static unsigned int selfballoon_interval __read_mostly = 5;
95 97
98/*
99 * Minimum usable RAM in MB for selfballooning target for balloon.
100 * If non-zero, it is added to totalreserve_pages and self-ballooning
101 * will not balloon below the sum. If zero, a piecewise linear function
102 * is calculated as a minimum and added to totalreserve_pages. Note that
103 * setting this value indiscriminately may cause OOMs and crashes.
104 */
105static unsigned int selfballoon_min_usable_mb;
106
96static void selfballoon_process(struct work_struct *work); 107static void selfballoon_process(struct work_struct *work);
97static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process); 108static DECLARE_DELAYED_WORK(selfballoon_worker, selfballoon_process);
98 109
@@ -189,20 +200,23 @@ static int __init xen_selfballooning_setup(char *s)
189__setup("selfballooning", xen_selfballooning_setup); 200__setup("selfballooning", xen_selfballooning_setup);
190#endif /* CONFIG_FRONTSWAP */ 201#endif /* CONFIG_FRONTSWAP */
191 202
203#define MB2PAGES(mb) ((mb) << (20 - PAGE_SHIFT))
204
192/* 205/*
193 * Use current balloon size, the goal (vm_committed_as), and hysteresis 206 * Use current balloon size, the goal (vm_committed_as), and hysteresis
194 * parameters to set a new target balloon size 207 * parameters to set a new target balloon size
195 */ 208 */
196static void selfballoon_process(struct work_struct *work) 209static void selfballoon_process(struct work_struct *work)
197{ 210{
198 unsigned long cur_pages, goal_pages, tgt_pages; 211 unsigned long cur_pages, goal_pages, tgt_pages, floor_pages;
212 unsigned long useful_pages;
199 bool reset_timer = false; 213 bool reset_timer = false;
200 214
201 if (xen_selfballooning_enabled) { 215 if (xen_selfballooning_enabled) {
202 cur_pages = balloon_stats.current_pages; 216 cur_pages = totalram_pages;
203 tgt_pages = cur_pages; /* default is no change */ 217 tgt_pages = cur_pages; /* default is no change */
204 goal_pages = percpu_counter_read_positive(&vm_committed_as) + 218 goal_pages = percpu_counter_read_positive(&vm_committed_as) +
205 balloon_stats.current_pages - totalram_pages; 219 totalreserve_pages;
206#ifdef CONFIG_FRONTSWAP 220#ifdef CONFIG_FRONTSWAP
207 /* allow space for frontswap pages to be repatriated */ 221 /* allow space for frontswap pages to be repatriated */
208 if (frontswap_selfshrinking && frontswap_enabled) 222 if (frontswap_selfshrinking && frontswap_enabled)
@@ -217,7 +231,26 @@ static void selfballoon_process(struct work_struct *work)
217 ((goal_pages - cur_pages) / 231 ((goal_pages - cur_pages) /
218 selfballoon_uphysteresis); 232 selfballoon_uphysteresis);
219 /* else if cur_pages == goal_pages, no change */ 233 /* else if cur_pages == goal_pages, no change */
220 balloon_set_new_target(tgt_pages); 234 useful_pages = max_pfn - totalreserve_pages;
235 if (selfballoon_min_usable_mb != 0)
236 floor_pages = totalreserve_pages +
237 MB2PAGES(selfballoon_min_usable_mb);
238 /* piecewise linear function ending in ~3% slope */
239 else if (useful_pages < MB2PAGES(16))
240 floor_pages = max_pfn; /* not worth ballooning */
241 else if (useful_pages < MB2PAGES(64))
242 floor_pages = totalreserve_pages + MB2PAGES(16) +
243 ((useful_pages - MB2PAGES(16)) >> 1);
244 else if (useful_pages < MB2PAGES(512))
245 floor_pages = totalreserve_pages + MB2PAGES(40) +
246 ((useful_pages - MB2PAGES(40)) >> 3);
247 else /* useful_pages >= MB2PAGES(512) */
248 floor_pages = totalreserve_pages + MB2PAGES(99) +
249 ((useful_pages - MB2PAGES(99)) >> 5);
250 if (tgt_pages < floor_pages)
251 tgt_pages = floor_pages;
252 balloon_set_new_target(tgt_pages +
253 balloon_stats.current_pages - totalram_pages);
221 reset_timer = true; 254 reset_timer = true;
222 } 255 }
223#ifdef CONFIG_FRONTSWAP 256#ifdef CONFIG_FRONTSWAP
@@ -340,6 +373,31 @@ static ssize_t store_selfballoon_uphys(struct sys_device *dev,
340static SYSDEV_ATTR(selfballoon_uphysteresis, S_IRUGO | S_IWUSR, 373static SYSDEV_ATTR(selfballoon_uphysteresis, S_IRUGO | S_IWUSR,
341 show_selfballoon_uphys, store_selfballoon_uphys); 374 show_selfballoon_uphys, store_selfballoon_uphys);
342 375
376SELFBALLOON_SHOW(selfballoon_min_usable_mb, "%d\n",
377 selfballoon_min_usable_mb);
378
379static ssize_t store_selfballoon_min_usable_mb(struct sys_device *dev,
380 struct sysdev_attribute *attr,
381 const char *buf,
382 size_t count)
383{
384 unsigned long val;
385 int err;
386
387 if (!capable(CAP_SYS_ADMIN))
388 return -EPERM;
389 err = strict_strtoul(buf, 10, &val);
390 if (err || val == 0)
391 return -EINVAL;
392 selfballoon_min_usable_mb = val;
393 return count;
394}
395
396static SYSDEV_ATTR(selfballoon_min_usable_mb, S_IRUGO | S_IWUSR,
397 show_selfballoon_min_usable_mb,
398 store_selfballoon_min_usable_mb);
399
400
343#ifdef CONFIG_FRONTSWAP 401#ifdef CONFIG_FRONTSWAP
344SELFBALLOON_SHOW(frontswap_selfshrinking, "%d\n", frontswap_selfshrinking); 402SELFBALLOON_SHOW(frontswap_selfshrinking, "%d\n", frontswap_selfshrinking);
345 403
@@ -421,6 +479,7 @@ static struct attribute *selfballoon_attrs[] = {
421 &attr_selfballoon_interval.attr, 479 &attr_selfballoon_interval.attr,
422 &attr_selfballoon_downhysteresis.attr, 480 &attr_selfballoon_downhysteresis.attr,
423 &attr_selfballoon_uphysteresis.attr, 481 &attr_selfballoon_uphysteresis.attr,
482 &attr_selfballoon_min_usable_mb.attr,
424#ifdef CONFIG_FRONTSWAP 483#ifdef CONFIG_FRONTSWAP
425 &attr_frontswap_selfshrinking.attr, 484 &attr_frontswap_selfshrinking.attr,
426 &attr_frontswap_hysteresis.attr, 485 &attr_frontswap_hysteresis.attr,
diff --git a/drivers/xen/xenbus/xenbus_probe_backend.c b/drivers/xen/xenbus/xenbus_probe_backend.c
index 60adf919d78d..32417b5064fd 100644
--- a/drivers/xen/xenbus/xenbus_probe_backend.c
+++ b/drivers/xen/xenbus/xenbus_probe_backend.c
@@ -104,8 +104,6 @@ static int xenbus_uevent_backend(struct device *dev,
104 104
105 xdev = to_xenbus_device(dev); 105 xdev = to_xenbus_device(dev);
106 bus = container_of(xdev->dev.bus, struct xen_bus_type, bus); 106 bus = container_of(xdev->dev.bus, struct xen_bus_type, bus);
107 if (xdev == NULL)
108 return -ENODEV;
109 107
110 if (add_uevent_var(env, "MODALIAS=xen-backend:%s", xdev->devicetype)) 108 if (add_uevent_var(env, "MODALIAS=xen-backend:%s", xdev->devicetype))
111 return -ENOMEM; 109 return -ENOMEM;