aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/virtio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-17 13:37:56 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-17 13:37:56 -0500
commit9f3e15129902bca9d8e296c165345f158bac94eb (patch)
tree45c6715462029e90802962a55f4e1baad1ef09ca /drivers/virtio
parent2efda9042d76fcab0fb87b7ee8d84da52bf122b0 (diff)
parent5a10b7dbf904bfe01bb9fcc6298f7df09eed77d5 (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.c57
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
43static int oom_pages = OOM_VBALLOON_DEFAULT_PAGES;
44module_param(oom_pages, int, S_IRUSR | S_IWUSR);
45MODULE_PARM_DESC(oom_pages, "pages to free on OOM");
39 46
40struct virtio_balloon 47struct 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
76static struct virtio_device_id id_table[] = { 86static 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
171static void leak_balloon(struct virtio_balloon *vb, size_t num) 181static 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
200static inline void update_stat(struct virtio_balloon *vb, int idx, 213static 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 */
316static 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
290static int balloon(void *_vballoon) 335static 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
454out_del_vqs: 505out_del_vqs:
506 unregister_oom_notifier(&vb->nb);
507out_oom_notify:
455 vdev->config->del_vqs(vdev); 508 vdev->config->del_vqs(vdev);
456out_free_vb: 509out_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)
515static unsigned int features[] = { 569static 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
520static struct virtio_driver virtio_balloon_driver = { 575static struct virtio_driver virtio_balloon_driver = {