Lines Matching +full:config +full:- +full:host

12  * the COPYING file in the top-level directory.
22 #include "hw/mem/pc-dimm.h"
23 #include "hw/qdev-properties.h"
26 #include "hw/virtio/virtio-balloon.h"
27 #include "system/address-spaces.h"
29 #include "qapi/qapi-events-machine.h"
32 #include "qemu/error-report.h"
35 #include "hw/virtio/virtio-bus.h"
36 #include "hw/virtio/virtio-access.h"
47 if (!pbp->bitmap) { in virtio_balloon_pbp_free()
50 g_free(pbp->bitmap); in virtio_balloon_pbp_free()
51 pbp->bitmap = NULL; in virtio_balloon_pbp_free()
58 pbp->base_gpa = base_gpa; in virtio_balloon_pbp_alloc()
59 pbp->bitmap = bitmap_new(subpages); in virtio_balloon_pbp_alloc()
65 return pbp->base_gpa == base_gpa; in virtio_balloon_pbp_matches()
89 * host address? */ in balloon_inflate_page()
105 * We've put a piece of a larger host page into the balloon - we in balloon_inflate_page()
106 * need to keep track until we have a whole host page to in balloon_inflate_page()
114 base_gpa = memory_region_get_ram_addr(mr) + mr_offset - in balloon_inflate_page()
115 (rb_offset - rb_aligned_offset); in balloon_inflate_page()
117 if (pbp->bitmap && !virtio_balloon_pbp_matches(pbp, base_gpa)) { in balloon_inflate_page()
118 /* We've partially ballooned part of a host page, but now in balloon_inflate_page()
124 if (!pbp->bitmap) { in balloon_inflate_page()
128 set_bit((rb_offset - rb_aligned_offset) / BALLOON_PAGE_SIZE, in balloon_inflate_page()
129 pbp->bitmap); in balloon_inflate_page()
131 if (bitmap_full(pbp->bitmap, subpages)) { in balloon_inflate_page()
132 /* We've accumulated a full host page, we can actually discard in balloon_inflate_page()
154 * host address? */ in balloon_deflate_page()
158 host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1)); in balloon_deflate_page()
160 /* When a page is deflated, we hint the whole host page it lives in balloon_deflate_page()
172 * non-NULL name declared here, since these are used
176 [VIRTIO_BALLOON_S_SWAP_IN] = "stat-swap-in",
177 [VIRTIO_BALLOON_S_SWAP_OUT] = "stat-swap-out",
178 [VIRTIO_BALLOON_S_MAJFLT] = "stat-major-faults",
179 [VIRTIO_BALLOON_S_MINFLT] = "stat-minor-faults",
180 [VIRTIO_BALLOON_S_MEMFREE] = "stat-free-memory",
182 [VIRTIO_BALLOON_S_MEMTOT] = "stat-total-memory",
183 [VIRTIO_BALLOON_S_AVAIL] = "stat-available-memory",
184 [VIRTIO_BALLOON_S_CACHES] = "stat-disk-caches",
185 [VIRTIO_BALLOON_S_HTLB_PGALLOC] = "stat-htlb-pgalloc",
186 [VIRTIO_BALLOON_S_HTLB_PGFAIL] = "stat-htlb-pgfail",
188 [VIRTIO_BALLOON_S_OOM_KILL] = "stat-oom-kills",
189 [VIRTIO_BALLOON_S_ALLOC_STALL] = "stat-alloc-stalls",
190 [VIRTIO_BALLOON_S_ASYNC_SCAN] = "stat-async-scans",
191 [VIRTIO_BALLOON_S_DIRECT_SCAN] = "stat-direct-scans",
192 [VIRTIO_BALLOON_S_ASYNC_RECLAIM] = "stat-async-reclaims",
194 [VIRTIO_BALLOON_S_DIRECT_RECLAIM] = "stat-direct-reclaims",
199 * reset_stats - Mark all items in the stats array as unset
202 * updating to a set of newly-generated stats. This will ensure that no
209 for (i = 0; i < VIRTIO_BALLOON_S_NR; dev->stats[i++] = -1); in reset_stats()
220 return s->stats_poll_interval > 0; in balloon_stats_enabled()
226 timer_free(s->stats_timer); in balloon_stats_destroy_timer()
227 s->stats_timer = NULL; in balloon_stats_destroy_timer()
228 s->stats_poll_interval = 0; in balloon_stats_destroy_timer()
234 timer_mod(s->stats_timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + secs * 1000); in balloon_stats_change_timer()
242 if (s->stats_vq_elem == NULL || !balloon_stats_supported(s)) { in balloon_stats_poll_cb()
243 /* re-schedule */ in balloon_stats_poll_cb()
244 balloon_stats_change_timer(s, s->stats_poll_interval); in balloon_stats_poll_cb()
248 virtqueue_push(s->svq, s->stats_vq_elem, 0); in balloon_stats_poll_cb()
249 virtio_notify(vdev, s->svq); in balloon_stats_poll_cb()
250 g_free(s->stats_vq_elem); in balloon_stats_poll_cb()
251 s->stats_vq_elem = NULL; in balloon_stats_poll_cb()
264 if (!visit_type_int(v, "last-update", &s->stats_last_update, errp)) { in balloon_stats_get_all()
272 if (!visit_type_uint64(v, balloon_stat_names[i], &s->stats[i], errp)) { in balloon_stats_get_all()
292 visit_type_int(v, name, &s->stats_poll_interval, errp); in balloon_stats_get_poll_interval()
316 if (value == s->stats_poll_interval) { in balloon_stats_set_poll_interval()
328 s->stats_poll_interval = value; in balloon_stats_set_poll_interval()
334 g_assert(s->stats_timer == NULL); in balloon_stats_set_poll_interval()
335 s->stats_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, balloon_stats_poll_cb, s); in balloon_stats_set_poll_interval()
336 s->stats_poll_interval = value; in balloon_stats_set_poll_interval()
353 * expecting it to retain a non-zero value. in virtio_balloon_handle_report()
355 if (virtio_balloon_inhibited() || dev->poison_val) { in virtio_balloon_handle_report()
359 for (i = 0; i < elem->in_num; i++) { in virtio_balloon_handle_report()
360 void *addr = elem->in_sg[i].iov_base; in virtio_balloon_handle_report()
361 size_t size = elem->in_sg[i].iov_len; in virtio_balloon_handle_report()
378 trace_virtio_balloon_bad_addr(elem->in_addr[i]); in virtio_balloon_handle_report()
417 while (iov_to_buf(elem->out_sg, elem->out_num, offset, &pfn, 4) == 4) { in virtio_balloon_handle_output()
441 if (vq == s->ivq) { in virtio_balloon_handle_output()
444 } else if (vq == s->dvq) { in virtio_balloon_handle_output()
472 if (s->stats_vq_elem != NULL) { in virtio_balloon_receive_stats()
474 virtqueue_push(vq, s->stats_vq_elem, 0); in virtio_balloon_receive_stats()
476 g_free(s->stats_vq_elem); in virtio_balloon_receive_stats()
479 s->stats_vq_elem = elem; in virtio_balloon_receive_stats()
487 while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat)) in virtio_balloon_receive_stats()
494 s->stats[tag] = val; in virtio_balloon_receive_stats()
496 s->stats_vq_offset = offset; in virtio_balloon_receive_stats()
497 s->stats_last_update = g_get_real_time() / G_USEC_PER_SEC; in virtio_balloon_receive_stats()
501 balloon_stats_change_timer(s, s->stats_poll_interval); in virtio_balloon_receive_stats()
509 qemu_bh_schedule(s->free_page_bh); in virtio_balloon_handle_free_page_vq()
516 VirtQueue *vq = dev->free_page_vq; in get_free_page_hints()
520 while (dev->block_iothread) { in get_free_page_hints()
521 qemu_cond_wait(&dev->free_page_cond, &dev->free_page_lock); in get_free_page_hints()
529 if (elem->out_num) { in get_free_page_hints()
531 size_t size = iov_to_buf(elem->out_sg, elem->out_num, 0, in get_free_page_hints()
540 if (dev->free_page_hint_status == FREE_PAGE_HINT_S_REQUESTED && in get_free_page_hints()
541 id == dev->free_page_hint_cmd_id) { in get_free_page_hints()
542 dev->free_page_hint_status = FREE_PAGE_HINT_S_START; in get_free_page_hints()
543 } else if (dev->free_page_hint_status == FREE_PAGE_HINT_S_START) { in get_free_page_hints()
548 dev->free_page_hint_status = FREE_PAGE_HINT_S_STOP; in get_free_page_hints()
552 if (elem->in_num && dev->free_page_hint_status == FREE_PAGE_HINT_S_START) { in get_free_page_hints()
553 for (i = 0; i < elem->in_num; i++) { in get_free_page_hints()
554 qemu_guest_free_page_hint(elem->in_sg[i].iov_base, in get_free_page_hints()
555 elem->in_sg[i].iov_len); in get_free_page_hints()
569 VirtQueue *vq = dev->free_page_vq; in virtio_ballloon_get_free_page_hints()
573 qemu_mutex_lock(&dev->free_page_lock); in virtio_ballloon_get_free_page_hints()
576 qemu_mutex_unlock(&dev->free_page_lock); in virtio_ballloon_get_free_page_hints()
583 dev->free_page_hint_status == FREE_PAGE_HINT_S_START); in virtio_ballloon_get_free_page_hints()
599 qemu_mutex_lock(&s->free_page_lock); in virtio_balloon_free_page_start()
601 if (s->free_page_hint_cmd_id == UINT_MAX) { in virtio_balloon_free_page_start()
602 s->free_page_hint_cmd_id = VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN; in virtio_balloon_free_page_start()
604 s->free_page_hint_cmd_id++; in virtio_balloon_free_page_start()
607 s->free_page_hint_status = FREE_PAGE_HINT_S_REQUESTED; in virtio_balloon_free_page_start()
608 qemu_mutex_unlock(&s->free_page_lock); in virtio_balloon_free_page_start()
617 if (s->free_page_hint_status != FREE_PAGE_HINT_S_STOP) { in virtio_balloon_free_page_stop()
623 qemu_mutex_lock(&s->free_page_lock); in virtio_balloon_free_page_stop()
628 s->free_page_hint_status = FREE_PAGE_HINT_S_STOP; in virtio_balloon_free_page_stop()
629 qemu_mutex_unlock(&s->free_page_lock); in virtio_balloon_free_page_stop()
638 if (s->free_page_hint_status != FREE_PAGE_HINT_S_DONE) { in virtio_balloon_free_page_done()
640 qemu_mutex_lock(&s->free_page_lock); in virtio_balloon_free_page_done()
641 s->free_page_hint_status = FREE_PAGE_HINT_S_DONE; in virtio_balloon_free_page_done()
642 qemu_mutex_unlock(&s->free_page_lock); in virtio_balloon_free_page_done()
676 switch (pnd->reason) { in virtio_balloon_free_page_hint_notify()
681 if (vdev->vm_running) { in virtio_balloon_free_page_hint_notify()
700 virtio_error(vdev, "%s: %d reason unknown", __func__, pnd->reason); in virtio_balloon_free_page_hint_notify()
708 uint64_t features = s->host_features; in virtio_balloon_config_size()
710 if (s->qemu_4_0_config_size) { in virtio_balloon_config_size()
725 struct virtio_balloon_config config = {}; in virtio_balloon_get_config() local
727 config.num_pages = cpu_to_le32(dev->num_pages); in virtio_balloon_get_config()
728 config.actual = cpu_to_le32(dev->actual); in virtio_balloon_get_config()
729 config.poison_val = cpu_to_le32(dev->poison_val); in virtio_balloon_get_config()
731 if (dev->free_page_hint_status == FREE_PAGE_HINT_S_REQUESTED) { in virtio_balloon_get_config()
732 config.free_page_hint_cmd_id = in virtio_balloon_get_config()
733 cpu_to_le32(dev->free_page_hint_cmd_id); in virtio_balloon_get_config()
734 } else if (dev->free_page_hint_status == FREE_PAGE_HINT_S_STOP) { in virtio_balloon_get_config()
735 config.free_page_hint_cmd_id = in virtio_balloon_get_config()
737 } else if (dev->free_page_hint_status == FREE_PAGE_HINT_S_DONE) { in virtio_balloon_get_config()
738 config.free_page_hint_cmd_id = in virtio_balloon_get_config()
742 trace_virtio_balloon_get_config(config.num_pages, config.actual); in virtio_balloon_get_config()
743 memcpy(config_data, &config, virtio_balloon_config_size(dev)); in virtio_balloon_get_config()
749 if (machine->device_memory) { in get_current_ram_size()
750 return machine->ram_size + machine->device_memory->dimm_size; in get_current_ram_size()
752 return machine->ram_size; in get_current_ram_size()
768 struct virtio_balloon_config config; in virtio_balloon_set_config() local
769 uint32_t oldactual = dev->actual; in virtio_balloon_set_config()
772 memcpy(&config, config_data, virtio_balloon_config_size(dev)); in virtio_balloon_set_config()
773 dev->actual = le32_to_cpu(config.actual); in virtio_balloon_set_config()
774 if (dev->actual != oldactual) { in virtio_balloon_set_config()
775 qapi_event_send_balloon_change(vm_ram_size - in virtio_balloon_set_config()
776 ((ram_addr_t) dev->actual << VIRTIO_BALLOON_PFN_SHIFT)); in virtio_balloon_set_config()
778 dev->poison_val = 0; in virtio_balloon_set_config()
780 dev->poison_val = le32_to_cpu(config.poison_val); in virtio_balloon_set_config()
782 trace_virtio_balloon_set_config(dev->actual, oldactual); in virtio_balloon_set_config()
789 f |= dev->host_features; in virtio_balloon_get_features()
798 info->actual = get_current_ram_size() - ((uint64_t) dev->actual << in virtio_balloon_stat()
812 dev->num_pages = (vm_ram_size - target) >> VIRTIO_BALLOON_PFN_SHIFT; in virtio_balloon_to_target()
815 trace_virtio_balloon_to_target(target, dev->num_pages); in virtio_balloon_to_target()
823 balloon_stats_change_timer(s, s->stats_poll_interval); in virtio_balloon_post_load_device()
829 .name = "virtio-balloon-device/free-page-report",
841 .name = "virtio-balloon-device/page-poison",
852 .name = "virtio-balloon-device",
885 if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT) && in virtio_balloon_device_realize()
886 !s->iothread) { in virtio_balloon_device_realize()
887 error_setg(errp, "'free-page-hint' requires 'iothread' to be set"); in virtio_balloon_device_realize()
892 s->ivq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output); in virtio_balloon_device_realize()
893 s->dvq = virtio_add_queue(vdev, 128, virtio_balloon_handle_output); in virtio_balloon_device_realize()
894 s->svq = virtio_add_queue(vdev, 128, virtio_balloon_receive_stats); in virtio_balloon_device_realize()
896 if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_FREE_PAGE_HINT)) { in virtio_balloon_device_realize()
897 s->free_page_vq = virtio_add_queue(vdev, VIRTQUEUE_MAX_SIZE, in virtio_balloon_device_realize()
899 precopy_add_notifier(&s->free_page_hint_notify); in virtio_balloon_device_realize()
901 object_ref(OBJECT(s->iothread)); in virtio_balloon_device_realize()
902 s->free_page_bh = aio_bh_new_guarded(iothread_get_aio_context(s->iothread), in virtio_balloon_device_realize()
904 &dev->mem_reentrancy_guard); in virtio_balloon_device_realize()
907 if (virtio_has_feature(s->host_features, VIRTIO_BALLOON_F_REPORTING)) { in virtio_balloon_device_realize()
908 s->reporting_vq = virtio_add_queue(vdev, 32, in virtio_balloon_device_realize()
913 s->stats_last_update = 0; in virtio_balloon_device_realize()
923 if (s->free_page_bh) { in virtio_balloon_device_unrealize()
924 qemu_bh_delete(s->free_page_bh); in virtio_balloon_device_unrealize()
925 object_unref(OBJECT(s->iothread)); in virtio_balloon_device_unrealize()
927 precopy_remove_notifier(&s->free_page_hint_notify); in virtio_balloon_device_unrealize()
932 virtio_delete_queue(s->ivq); in virtio_balloon_device_unrealize()
933 virtio_delete_queue(s->dvq); in virtio_balloon_device_unrealize()
934 virtio_delete_queue(s->svq); in virtio_balloon_device_unrealize()
935 if (s->free_page_vq) { in virtio_balloon_device_unrealize()
936 virtio_delete_queue(s->free_page_vq); in virtio_balloon_device_unrealize()
938 if (s->reporting_vq) { in virtio_balloon_device_unrealize()
939 virtio_delete_queue(s->reporting_vq); in virtio_balloon_device_unrealize()
952 if (s->stats_vq_elem != NULL) { in virtio_balloon_device_reset()
953 virtqueue_unpop(s->svq, s->stats_vq_elem, 0); in virtio_balloon_device_reset()
954 g_free(s->stats_vq_elem); in virtio_balloon_device_reset()
955 s->stats_vq_elem = NULL; in virtio_balloon_device_reset()
958 s->poison_val = 0; in virtio_balloon_device_reset()
965 if (!s->stats_vq_elem && vdev->vm_running && in virtio_balloon_set_status()
966 (status & VIRTIO_CONFIG_S_DRIVER_OK) && virtqueue_rewind(s->svq, 1)) { in virtio_balloon_set_status()
969 virtio_balloon_receive_stats(vdev, s->svq); in virtio_balloon_set_status()
977 if (vdev->vm_running && s->block_iothread) { in virtio_balloon_set_status()
978 qemu_mutex_lock(&s->free_page_lock); in virtio_balloon_set_status()
979 s->block_iothread = false; in virtio_balloon_set_status()
980 qemu_cond_signal(&s->free_page_cond); in virtio_balloon_set_status()
981 qemu_mutex_unlock(&s->free_page_lock); in virtio_balloon_set_status()
985 if (!vdev->vm_running) { in virtio_balloon_set_status()
986 qemu_mutex_lock(&s->free_page_lock); in virtio_balloon_set_status()
987 s->block_iothread = true; in virtio_balloon_set_status()
988 qemu_mutex_unlock(&s->free_page_lock); in virtio_balloon_set_status()
997 return &s->reset_state; in virtio_balloon_get_reset_state()
1005 * When waking up from standby/suspend-to-ram, do not reset stats. in virtio_balloon_reset_enter()
1012 s->stats_last_update = 0; in virtio_balloon_reset_enter()
1019 qemu_mutex_init(&s->free_page_lock); in virtio_balloon_instance_init()
1020 qemu_cond_init(&s->free_page_cond); in virtio_balloon_instance_init()
1021 s->free_page_hint_cmd_id = VIRTIO_BALLOON_FREE_PAGE_HINT_CMD_ID_MIN; in virtio_balloon_instance_init()
1022 s->free_page_hint_notify.notify = virtio_balloon_free_page_hint_notify; in virtio_balloon_instance_init()
1024 object_property_add(obj, "guest-stats", "guest statistics", in virtio_balloon_instance_init()
1027 object_property_add(obj, "guest-stats-polling-interval", "int", in virtio_balloon_instance_init()
1034 .name = "virtio-balloon",
1044 DEFINE_PROP_BIT("deflate-on-oom", VirtIOBalloon, host_features,
1046 DEFINE_PROP_BIT("free-page-hint", VirtIOBalloon, host_features,
1048 DEFINE_PROP_BIT("page-poison", VirtIOBalloon, host_features,
1050 DEFINE_PROP_BIT("free-page-reporting", VirtIOBalloon, host_features,
1052 /* QEMU 4.0 accidentally changed the config size even when free-page-hint
1056 DEFINE_PROP_BOOL("qemu-4-0-config-size", VirtIOBalloon,
1069 dc->vmsd = &vmstate_virtio_balloon; in virtio_balloon_class_init()
1070 set_bit(DEVICE_CATEGORY_MISC, dc->categories); in virtio_balloon_class_init()
1071 vdc->realize = virtio_balloon_device_realize; in virtio_balloon_class_init()
1072 vdc->unrealize = virtio_balloon_device_unrealize; in virtio_balloon_class_init()
1073 vdc->reset = virtio_balloon_device_reset; in virtio_balloon_class_init()
1074 vdc->get_config = virtio_balloon_get_config; in virtio_balloon_class_init()
1075 vdc->set_config = virtio_balloon_set_config; in virtio_balloon_class_init()
1076 vdc->get_features = virtio_balloon_get_features; in virtio_balloon_class_init()
1077 vdc->set_status = virtio_balloon_set_status; in virtio_balloon_class_init()
1078 vdc->vmsd = &vmstate_virtio_balloon_device; in virtio_balloon_class_init()
1080 rc->get_state = virtio_balloon_get_reset_state; in virtio_balloon_class_init()
1081 rc->phases.enter = virtio_balloon_reset_enter; in virtio_balloon_class_init()