Commit 9f3e15129902bca9d8e296c165345f158bac94eb
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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 |