Commit 9f3e15129902bca9d8e296c165345f158bac94eb

Authored by Linus Torvalds

Merge tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux

Pull virtio updates from Rusty Russell:
 "A balloon enhancement, and a minor race-on-module-unload theoretical
  bug which doesn't merit cc: stable.

  All the exciting stuff went via MST this cycle"

* tag 'virtio-next-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux:
  virtio_balloon: free some memory from balloon on OOM
  virtio_balloon: return the amount of freed memory from leak_balloon()
  virtio_blk: fix race at module removal
  virtio: Fix comment typo 'CONFIG_S_FAILED'

Showing 3 changed files Side-by-side Diff

drivers/virtio/virtio_balloon.c
... ... @@ -28,6 +28,7 @@
28 28 #include <linux/slab.h>
29 29 #include <linux/module.h>
30 30 #include <linux/balloon_compaction.h>
  31 +#include <linux/oom.h>
31 32  
32 33 /*
33 34 * Balloon device works in 4K page units. So each page is pointed to by
34 35  
... ... @@ -36,7 +37,13 @@
36 37 */
37 38 #define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
38 39 #define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256
  40 +#define OOM_VBALLOON_DEFAULT_PAGES 256
  41 +#define VIRTBALLOON_OOM_NOTIFY_PRIORITY 80
39 42  
  43 +static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES;
  44 +module_param(oom_pages, int, S_IRUSR | S_IWUSR);
  45 +MODULE_PARM_DESC(oom_pages, "pages to free on OOM");
  46 +
40 47 struct virtio_balloon
41 48 {
42 49 struct virtio_device *vdev;
... ... @@ -71,6 +78,9 @@
71 78 /* Memory statistics */
72 79 int need_stats_update;
73 80 struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
  81 +
  82 + /* To register callback in oom notifier call chain */
  83 + struct notifier_block nb;
74 84 };
75 85  
76 86 static struct virtio_device_id id_table[] = {
77 87  
... ... @@ -168,8 +178,9 @@
168 178 }
169 179 }
170 180  
171   -static void leak_balloon(struct virtio_balloon *vb, size_t num)
  181 +static unsigned leak_balloon(struct virtio_balloon *vb, size_t num)
172 182 {
  183 + unsigned num_freed_pages;
173 184 struct page *page;
174 185 struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info;
175 186  
... ... @@ -186,6 +197,7 @@
186 197 vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE;
187 198 }
188 199  
  200 + num_freed_pages = vb->num_pfns;
189 201 /*
190 202 * Note that if
191 203 * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST);
... ... @@ -195,6 +207,7 @@
195 207 tell_host(vb, vb->deflate_vq);
196 208 mutex_unlock(&vb->balloon_lock);
197 209 release_pages_by_pfn(vb->pfns, vb->num_pfns);
  210 + return num_freed_pages;
198 211 }
199 212  
200 213 static inline void update_stat(struct virtio_balloon *vb, int idx,
... ... @@ -287,6 +300,38 @@
287 300 &actual);
288 301 }
289 302  
  303 +/*
  304 + * virtballoon_oom_notify - release pages when system is under severe
  305 + * memory pressure (called from out_of_memory())
  306 + * @self : notifier block struct
  307 + * @dummy: not used
  308 + * @parm : returned - number of freed pages
  309 + *
  310 + * The balancing of memory by use of the virtio balloon should not cause
  311 + * the termination of processes while there are pages in the balloon.
  312 + * If virtio balloon manages to release some memory, it will make the
  313 + * system return and retry the allocation that forced the OOM killer
  314 + * to run.
  315 + */
  316 +static int virtballoon_oom_notify(struct notifier_block *self,
  317 + unsigned long dummy, void *parm)
  318 +{
  319 + struct virtio_balloon *vb;
  320 + unsigned long *freed;
  321 + unsigned num_freed_pages;
  322 +
  323 + vb = container_of(self, struct virtio_balloon, nb);
  324 + if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
  325 + return NOTIFY_OK;
  326 +
  327 + freed = parm;
  328 + num_freed_pages = leak_balloon(vb, oom_pages);
  329 + update_balloon_size(vb);
  330 + *freed += num_freed_pages;
  331 +
  332 + return NOTIFY_OK;
  333 +}
  334 +
290 335 static int balloon(void *_vballoon)
291 336 {
292 337 struct virtio_balloon *vb = _vballoon;
... ... @@ -443,6 +488,12 @@
443 488 if (err)
444 489 goto out_free_vb;
445 490  
  491 + vb->nb.notifier_call = virtballoon_oom_notify;
  492 + vb->nb.priority = VIRTBALLOON_OOM_NOTIFY_PRIORITY;
  493 + err = register_oom_notifier(&vb->nb);
  494 + if (err < 0)
  495 + goto out_oom_notify;
  496 +
446 497 vb->thread = kthread_run(balloon, vb, "vballoon");
447 498 if (IS_ERR(vb->thread)) {
448 499 err = PTR_ERR(vb->thread);
... ... @@ -452,6 +503,8 @@
452 503 return 0;
453 504  
454 505 out_del_vqs:
  506 + unregister_oom_notifier(&vb->nb);
  507 +out_oom_notify:
455 508 vdev->config->del_vqs(vdev);
456 509 out_free_vb:
457 510 kfree(vb);
... ... @@ -476,6 +529,7 @@
476 529 {
477 530 struct virtio_balloon *vb = vdev->priv;
478 531  
  532 + unregister_oom_notifier(&vb->nb);
479 533 kthread_stop(vb->thread);
480 534 remove_common(vb);
481 535 kfree(vb);
... ... @@ -515,6 +569,7 @@
515 569 static unsigned int features[] = {
516 570 VIRTIO_BALLOON_F_MUST_TELL_HOST,
517 571 VIRTIO_BALLOON_F_STATS_VQ,
  572 + VIRTIO_BALLOON_F_DEFLATE_ON_OOM,
518 573 };
519 574  
520 575 static struct virtio_driver virtio_balloon_driver = {
include/linux/virtio.h
... ... @@ -81,7 +81,7 @@
81 81 /**
82 82 * virtio_device - representation of a device using virtio
83 83 * @index: unique position on the virtio bus
84   - * @failed: saved value for CONFIG_S_FAILED bit (for restore)
  84 + * @failed: saved value for VIRTIO_CONFIG_S_FAILED bit (for restore)
85 85 * @config_enabled: configuration change reporting enabled
86 86 * @config_change_pending: configuration change reported while disabled
87 87 * @config_lock: protects configuration change reporting
include/uapi/linux/virtio_balloon.h
... ... @@ -31,6 +31,7 @@
31 31 /* The feature bitmap for virtio balloon */
32 32 #define VIRTIO_BALLOON_F_MUST_TELL_HOST 0 /* Tell before reclaiming pages */
33 33 #define VIRTIO_BALLOON_F_STATS_VQ 1 /* Memory Stats virtqueue */
  34 +#define VIRTIO_BALLOON_F_DEFLATE_ON_OOM 2 /* Deflate balloon on OOM */
34 35  
35 36 /* Size of a PFN in the balloon interface. */
36 37 #define VIRTIO_BALLOON_PFN_SHIFT 12