Skip to content

Commit 835a6a6

Browse files
committed
virtio-balloon: Revert "virtio-balloon: Switch back to OOM handler for VIRTIO_BALLOON_F_DEFLATE_ON_OOM"
This reverts commit 5a6b4cc. It has been queued properly in the akpm tree, this version is just creating conflicts. Signed-off-by: Michael S. Tsirkin <[email protected]>
1 parent c9b9f5f commit 835a6a6

File tree

1 file changed

+63
-44
lines changed

1 file changed

+63
-44
lines changed

drivers/virtio/virtio_balloon.c

Lines changed: 63 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
#include <linux/slab.h>
1515
#include <linux/module.h>
1616
#include <linux/balloon_compaction.h>
17-
#include <linux/oom.h>
1817
#include <linux/wait.h>
1918
#include <linux/mm.h>
2019
#include <linux/mount.h>
@@ -28,9 +27,7 @@
2827
*/
2928
#define VIRTIO_BALLOON_PAGES_PER_PAGE (unsigned)(PAGE_SIZE >> VIRTIO_BALLOON_PFN_SHIFT)
3029
#define VIRTIO_BALLOON_ARRAY_PFNS_MAX 256
31-
/* Maximum number of (4k) pages to deflate on OOM notifications. */
32-
#define VIRTIO_BALLOON_OOM_NR_PAGES 256
33-
#define VIRTIO_BALLOON_OOM_NOTIFY_PRIORITY 80
30+
#define VIRTBALLOON_OOM_NOTIFY_PRIORITY 80
3431

3532
#define VIRTIO_BALLOON_FREE_PAGE_ALLOC_FLAG (__GFP_NORETRY | __GFP_NOWARN | \
3633
__GFP_NOMEMALLOC)
@@ -115,11 +112,8 @@ struct virtio_balloon {
115112
/* Memory statistics */
116113
struct virtio_balloon_stat stats[VIRTIO_BALLOON_S_NR];
117114

118-
/* Shrinker to return free pages - VIRTIO_BALLOON_F_FREE_PAGE_HINT */
115+
/* To register a shrinker to shrink memory upon memory pressure */
119116
struct shrinker shrinker;
120-
121-
/* OOM notifier to deflate on OOM - VIRTIO_BALLOON_F_DEFLATE_ON_OOM */
122-
struct notifier_block oom_nb;
123117
};
124118

125119
static struct virtio_device_id id_table[] = {
@@ -794,36 +788,77 @@ static unsigned long shrink_free_pages(struct virtio_balloon *vb,
794788
return blocks_freed * VIRTIO_BALLOON_HINT_BLOCK_PAGES;
795789
}
796790

791+
static unsigned long leak_balloon_pages(struct virtio_balloon *vb,
792+
unsigned long pages_to_free)
793+
{
794+
return leak_balloon(vb, pages_to_free * VIRTIO_BALLOON_PAGES_PER_PAGE) /
795+
VIRTIO_BALLOON_PAGES_PER_PAGE;
796+
}
797+
798+
static unsigned long shrink_balloon_pages(struct virtio_balloon *vb,
799+
unsigned long pages_to_free)
800+
{
801+
unsigned long pages_freed = 0;
802+
803+
/*
804+
* One invocation of leak_balloon can deflate at most
805+
* VIRTIO_BALLOON_ARRAY_PFNS_MAX balloon pages, so we call it
806+
* multiple times to deflate pages till reaching pages_to_free.
807+
*/
808+
while (vb->num_pages && pages_freed < pages_to_free)
809+
pages_freed += leak_balloon_pages(vb,
810+
pages_to_free - pages_freed);
811+
812+
update_balloon_size(vb);
813+
814+
return pages_freed;
815+
}
816+
797817
static unsigned long virtio_balloon_shrinker_scan(struct shrinker *shrinker,
798818
struct shrink_control *sc)
799819
{
820+
unsigned long pages_to_free, pages_freed = 0;
800821
struct virtio_balloon *vb = container_of(shrinker,
801822
struct virtio_balloon, shrinker);
802823

803-
return shrink_free_pages(vb, sc->nr_to_scan);
824+
pages_to_free = sc->nr_to_scan;
825+
826+
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
827+
pages_freed = shrink_free_pages(vb, pages_to_free);
828+
829+
if (pages_freed >= pages_to_free)
830+
return pages_freed;
831+
832+
pages_freed += shrink_balloon_pages(vb, pages_to_free - pages_freed);
833+
834+
return pages_freed;
804835
}
805836

806837
static unsigned long virtio_balloon_shrinker_count(struct shrinker *shrinker,
807838
struct shrink_control *sc)
808839
{
809840
struct virtio_balloon *vb = container_of(shrinker,
810841
struct virtio_balloon, shrinker);
842+
unsigned long count;
843+
844+
count = vb->num_pages / VIRTIO_BALLOON_PAGES_PER_PAGE;
845+
count += vb->num_free_page_blocks * VIRTIO_BALLOON_HINT_BLOCK_PAGES;
811846

812-
return vb->num_free_page_blocks * VIRTIO_BALLOON_HINT_BLOCK_PAGES;
847+
return count;
813848
}
814849

815-
static int virtio_balloon_oom_notify(struct notifier_block *nb,
816-
unsigned long dummy, void *parm)
850+
static void virtio_balloon_unregister_shrinker(struct virtio_balloon *vb)
817851
{
818-
struct virtio_balloon *vb = container_of(nb,
819-
struct virtio_balloon, oom_nb);
820-
unsigned long *freed = parm;
852+
unregister_shrinker(&vb->shrinker);
853+
}
821854

822-
*freed += leak_balloon(vb, VIRTIO_BALLOON_OOM_NR_PAGES) /
823-
VIRTIO_BALLOON_PAGES_PER_PAGE;
824-
update_balloon_size(vb);
855+
static int virtio_balloon_register_shrinker(struct virtio_balloon *vb)
856+
{
857+
vb->shrinker.scan_objects = virtio_balloon_shrinker_scan;
858+
vb->shrinker.count_objects = virtio_balloon_shrinker_count;
859+
vb->shrinker.seeks = DEFAULT_SEEKS;
825860

826-
return NOTIFY_OK;
861+
return register_shrinker(&vb->shrinker);
827862
}
828863

829864
static int virtballoon_probe(struct virtio_device *vdev)
@@ -900,35 +935,22 @@ static int virtballoon_probe(struct virtio_device *vdev)
900935
virtio_cwrite(vb->vdev, struct virtio_balloon_config,
901936
poison_val, &poison_val);
902937
}
903-
904-
/*
905-
* We're allowed to reuse any free pages, even if they are
906-
* still to be processed by the host.
907-
*/
908-
vb->shrinker.scan_objects = virtio_balloon_shrinker_scan;
909-
vb->shrinker.count_objects = virtio_balloon_shrinker_count;
910-
vb->shrinker.seeks = DEFAULT_SEEKS;
911-
err = register_shrinker(&vb->shrinker);
938+
}
939+
/*
940+
* We continue to use VIRTIO_BALLOON_F_DEFLATE_ON_OOM to decide if a
941+
* shrinker needs to be registered to relieve memory pressure.
942+
*/
943+
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) {
944+
err = virtio_balloon_register_shrinker(vb);
912945
if (err)
913946
goto out_del_balloon_wq;
914947
}
915-
if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) {
916-
vb->oom_nb.notifier_call = virtio_balloon_oom_notify;
917-
vb->oom_nb.priority = VIRTIO_BALLOON_OOM_NOTIFY_PRIORITY;
918-
err = register_oom_notifier(&vb->oom_nb);
919-
if (err < 0)
920-
goto out_unregister_shrinker;
921-
}
922-
923948
virtio_device_ready(vdev);
924949

925950
if (towards_target(vb))
926951
virtballoon_changed(vdev);
927952
return 0;
928953

929-
out_unregister_shrinker:
930-
if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
931-
unregister_shrinker(&vb->shrinker);
932954
out_del_balloon_wq:
933955
if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
934956
destroy_workqueue(vb->balloon_wq);
@@ -967,11 +989,8 @@ static void virtballoon_remove(struct virtio_device *vdev)
967989
{
968990
struct virtio_balloon *vb = vdev->priv;
969991

970-
if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
971-
unregister_oom_notifier(&vb->oom_nb);
972-
if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
973-
unregister_shrinker(&vb->shrinker);
974-
992+
if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM))
993+
virtio_balloon_unregister_shrinker(vb);
975994
spin_lock_irq(&vb->stop_update_lock);
976995
vb->stop_update = true;
977996
spin_unlock_irq(&vb->stop_update_lock);

0 commit comments

Comments
 (0)