diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-17 13:37:56 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-12-17 13:37:56 -0500 |
commit | 9f3e15129902bca9d8e296c165345f158bac94eb (patch) | |
tree | 45c6715462029e90802962a55f4e1baad1ef09ca /drivers/virtio | |
parent | 2efda9042d76fcab0fb87b7ee8d84da52bf122b0 (diff) | |
parent | 5a10b7dbf904bfe01bb9fcc6298f7df09eed77d5 (diff) |
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'
Diffstat (limited to 'drivers/virtio')
-rw-r--r-- | drivers/virtio/virtio_balloon.c | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c index c9703d4d6f67..50c5f42d7a9f 100644 --- a/drivers/virtio/virtio_balloon.c +++ b/drivers/virtio/virtio_balloon.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/balloon_compaction.h> | 30 | #include <linux/balloon_compaction.h> |
31 | #include <linux/oom.h> | ||
31 | 32 | ||
32 | /* | 33 | /* |
33 | * Balloon device works in 4K page units. So each page is pointed to by | 34 | * Balloon device works in 4K page units. So each page is pointed to by |
@@ -36,6 +37,12 @@ | |||
36 | */ | 37 | */ |
37 | #define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) | 38 | #define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT) |
38 | #define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256 | 39 | #define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256 |
40 | #define OOM_VBALLOON_DEFAULT_PAGES 256 | ||
41 | #define VIRTBALLOON_OOM_NOTIFY_PRIORITY 80 | ||
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"); | ||
39 | 46 | ||
40 | struct virtio_balloon | 47 | struct virtio_balloon |
41 | { | 48 | { |
@@ -71,6 +78,9 @@ struct virtio_balloon | |||
71 | /* Memory statistics */ | 78 | /* Memory statistics */ |
72 | int need_stats_update; | 79 | int need_stats_update; |
73 | struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR]; | 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 | static struct virtio_device_id id_table[] = { | 86 | static struct virtio_device_id id_table[] = { |
@@ -168,8 +178,9 @@ static void release_pages_by_pfn(const u32 pfns[], unsigned int num) | |||
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 | struct page *page; | 184 | struct page *page; |
174 | struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; | 185 | struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; |
175 | 186 | ||
@@ -186,6 +197,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) | |||
186 | vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; | 197 | vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; |
187 | } | 198 | } |
188 | 199 | ||
200 | num_freed_pages = vb->num_pfns; | ||
189 | /* | 201 | /* |
190 | * Note that if | 202 | * Note that if |
191 | * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); | 203 | * virtio_has_feature(vdev, VIRTIO_BALLOON_F_MUST_TELL_HOST); |
@@ -195,6 +207,7 @@ static void leak_balloon(struct virtio_balloon *vb, size_t num) | |||
195 | tell_host(vb, vb->deflate_vq); | 207 | tell_host(vb, vb->deflate_vq); |
196 | mutex_unlock(&vb->balloon_lock); | 208 | mutex_unlock(&vb->balloon_lock); |
197 | release_pages_by_pfn(vb->pfns, vb->num_pfns); | 209 | release_pages_by_pfn(vb->pfns, vb->num_pfns); |
210 | return num_freed_pages; | ||
198 | } | 211 | } |
199 | 212 | ||
200 | static inline void update_stat(struct virtio_balloon *vb, int idx, | 213 | static inline void update_stat(struct virtio_balloon *vb, int idx, |
@@ -287,6 +300,38 @@ static void update_balloon_size(struct virtio_balloon *vb) | |||
287 | &actual); | 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 | static int balloon(void *_vballoon) | 335 | static int balloon(void *_vballoon) |
291 | { | 336 | { |
292 | struct virtio_balloon *vb = _vballoon; | 337 | struct virtio_balloon *vb = _vballoon; |
@@ -443,6 +488,12 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
443 | if (err) | 488 | if (err) |
444 | goto out_free_vb; | 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 | vb->thread = kthread_run(balloon, vb, "vballoon"); | 497 | vb->thread = kthread_run(balloon, vb, "vballoon"); |
447 | if (IS_ERR(vb->thread)) { | 498 | if (IS_ERR(vb->thread)) { |
448 | err = PTR_ERR(vb->thread); | 499 | err = PTR_ERR(vb->thread); |
@@ -452,6 +503,8 @@ static int virtballoon_probe(struct virtio_device *vdev) | |||
452 | return 0; | 503 | return 0; |
453 | 504 | ||
454 | out_del_vqs: | 505 | out_del_vqs: |
506 | unregister_oom_notifier(&vb->nb); | ||
507 | out_oom_notify: | ||
455 | vdev->config->del_vqs(vdev); | 508 | vdev->config->del_vqs(vdev); |
456 | out_free_vb: | 509 | out_free_vb: |
457 | kfree(vb); | 510 | kfree(vb); |
@@ -476,6 +529,7 @@ static void virtballoon_remove(struct virtio_device *vdev) | |||
476 | { | 529 | { |
477 | struct virtio_balloon *vb = vdev->priv; | 530 | struct virtio_balloon *vb = vdev->priv; |
478 | 531 | ||
532 | unregister_oom_notifier(&vb->nb); | ||
479 | kthread_stop(vb->thread); | 533 | kthread_stop(vb->thread); |
480 | remove_common(vb); | 534 | remove_common(vb); |
481 | kfree(vb); | 535 | kfree(vb); |
@@ -515,6 +569,7 @@ static int virtballoon_restore(struct virtio_device *vdev) | |||
515 | static unsigned int features[] = { | 569 | static unsigned int features[] = { |
516 | VIRTIO_BALLOON_F_MUST_TELL_HOST, | 570 | VIRTIO_BALLOON_F_MUST_TELL_HOST, |
517 | VIRTIO_BALLOON_F_STATS_VQ, | 571 | VIRTIO_BALLOON_F_STATS_VQ, |
572 | VIRTIO_BALLOON_F_DEFLATE_ON_OOM, | ||
518 | }; | 573 | }; |
519 | 574 | ||
520 | static struct virtio_driver virtio_balloon_driver = { | 575 | static struct virtio_driver virtio_balloon_driver = { |