Lines Matching full:vb
103 struct virtio_balloon *vb = vq->vdev->priv; in balloon_ack() local
105 wake_up(&vb->acked); in balloon_ack()
108 static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq) in tell_host() argument
113 sg_init_one(&sg, vb->pfns, sizeof(vb->pfns[0]) * vb->num_pfns); in tell_host()
116 virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL); in tell_host()
120 wait_event(vb->acked, virtqueue_get_buf(vq, &len)); in tell_host()
124 static void set_page_pfns(struct virtio_balloon *vb, in set_page_pfns() argument
136 pfns[i] = cpu_to_virtio32(vb->vdev, in set_page_pfns()
140 static unsigned fill_balloon(struct virtio_balloon *vb, size_t num) in fill_balloon() argument
148 num = min(num, ARRAY_SIZE(vb->pfns)); in fill_balloon()
155 dev_info_ratelimited(&vb->vdev->dev, in fill_balloon()
166 mutex_lock(&vb->balloon_lock); in fill_balloon()
168 vb->num_pfns = 0; in fill_balloon()
171 balloon_page_enqueue(&vb->vb_dev_info, page); in fill_balloon()
173 set_page_pfns(vb, vb->pfns + vb->num_pfns, page); in fill_balloon()
174 vb->num_pages += VIRTIO_BALLOON_PAGES_PER_PAGE; in fill_balloon()
175 if (!virtio_has_feature(vb->vdev, in fill_balloon()
178 vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE; in fill_balloon()
181 num_allocated_pages = vb->num_pfns; in fill_balloon()
183 if (vb->num_pfns != 0) in fill_balloon()
184 tell_host(vb, vb->inflate_vq); in fill_balloon()
185 mutex_unlock(&vb->balloon_lock); in fill_balloon()
190 static void release_pages_balloon(struct virtio_balloon *vb, in release_pages_balloon() argument
196 if (!virtio_has_feature(vb->vdev, in release_pages_balloon()
204 static unsigned leak_balloon(struct virtio_balloon *vb, size_t num) in leak_balloon() argument
208 struct balloon_dev_info *vb_dev_info = &vb->vb_dev_info; in leak_balloon()
212 num = min(num, ARRAY_SIZE(vb->pfns)); in leak_balloon()
214 mutex_lock(&vb->balloon_lock); in leak_balloon()
216 num = min(num, (size_t)vb->num_pages); in leak_balloon()
217 for (vb->num_pfns = 0; vb->num_pfns < num; in leak_balloon()
218 vb->num_pfns += VIRTIO_BALLOON_PAGES_PER_PAGE) { in leak_balloon()
222 set_page_pfns(vb, vb->pfns + vb->num_pfns, page); in leak_balloon()
224 vb->num_pages -= VIRTIO_BALLOON_PAGES_PER_PAGE; in leak_balloon()
227 num_freed_pages = vb->num_pfns; in leak_balloon()
233 if (vb->num_pfns != 0) in leak_balloon()
234 tell_host(vb, vb->deflate_vq); in leak_balloon()
235 release_pages_balloon(vb, &pages); in leak_balloon()
236 mutex_unlock(&vb->balloon_lock); in leak_balloon()
240 static inline void update_stat(struct virtio_balloon *vb, int idx, in update_stat() argument
244 vb->stats[idx].tag = cpu_to_virtio16(vb->vdev, tag); in update_stat()
245 vb->stats[idx].val = cpu_to_virtio64(vb->vdev, val); in update_stat()
250 static unsigned int update_balloon_stats(struct virtio_balloon *vb) in update_balloon_stats() argument
265 update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_IN, in update_balloon_stats()
267 update_stat(vb, idx++, VIRTIO_BALLOON_S_SWAP_OUT, in update_balloon_stats()
269 update_stat(vb, idx++, VIRTIO_BALLOON_S_MAJFLT, events[PGMAJFAULT]); in update_balloon_stats()
270 update_stat(vb, idx++, VIRTIO_BALLOON_S_MINFLT, events[PGFAULT]); in update_balloon_stats()
272 update_stat(vb, idx++, VIRTIO_BALLOON_S_HTLB_PGALLOC, in update_balloon_stats()
274 update_stat(vb, idx++, VIRTIO_BALLOON_S_HTLB_PGFAIL, in update_balloon_stats()
278 update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMFREE, in update_balloon_stats()
280 update_stat(vb, idx++, VIRTIO_BALLOON_S_MEMTOT, in update_balloon_stats()
282 update_stat(vb, idx++, VIRTIO_BALLOON_S_AVAIL, in update_balloon_stats()
284 update_stat(vb, idx++, VIRTIO_BALLOON_S_CACHES, in update_balloon_stats()
301 struct virtio_balloon *vb = vq->vdev->priv; in stats_request() local
303 spin_lock(&vb->stop_update_lock); in stats_request()
304 if (!vb->stop_update) in stats_request()
305 queue_work(system_freezable_wq, &vb->update_balloon_stats_work); in stats_request()
306 spin_unlock(&vb->stop_update_lock); in stats_request()
309 static void stats_handle_request(struct virtio_balloon *vb) in stats_handle_request() argument
315 num_stats = update_balloon_stats(vb); in stats_handle_request()
317 vq = vb->stats_vq; in stats_handle_request()
320 sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats); in stats_handle_request()
321 virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL); in stats_handle_request()
327 struct virtio_balloon *vb = vdev->priv; in virtballoon_changed() local
330 spin_lock_irqsave(&vb->stop_update_lock, flags); in virtballoon_changed()
331 if (!vb->stop_update) in virtballoon_changed()
332 queue_work(system_freezable_wq, &vb->update_balloon_size_work); in virtballoon_changed()
333 spin_unlock_irqrestore(&vb->stop_update_lock, flags); in virtballoon_changed()
336 static inline s64 towards_target(struct virtio_balloon *vb) in towards_target() argument
341 virtio_cread(vb->vdev, struct virtio_balloon_config, num_pages, in towards_target()
345 if (!virtio_has_feature(vb->vdev, VIRTIO_F_VERSION_1)) in towards_target()
349 return target - vb->num_pages; in towards_target()
352 static void update_balloon_size(struct virtio_balloon *vb) in update_balloon_size() argument
354 u32 actual = vb->num_pages; in update_balloon_size()
357 if (!virtio_has_feature(vb->vdev, VIRTIO_F_VERSION_1)) in update_balloon_size()
360 virtio_cwrite(vb->vdev, struct virtio_balloon_config, actual, in update_balloon_size()
366 struct virtio_balloon *vb; in update_balloon_stats_func() local
368 vb = container_of(work, struct virtio_balloon, in update_balloon_stats_func()
370 stats_handle_request(vb); in update_balloon_stats_func()
375 struct virtio_balloon *vb; in update_balloon_size_func() local
378 vb = container_of(work, struct virtio_balloon, in update_balloon_size_func()
380 diff = towards_target(vb); in update_balloon_size_func()
383 diff -= fill_balloon(vb, diff); in update_balloon_size_func()
385 diff += leak_balloon(vb, -diff); in update_balloon_size_func()
386 update_balloon_size(vb); in update_balloon_size_func()
392 static int init_vqs(struct virtio_balloon *vb) in init_vqs() argument
403 nvqs = virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ) ? 3 : 2; in init_vqs()
404 err = virtio_find_vqs(vb->vdev, nvqs, vqs, callbacks, names, NULL); in init_vqs()
408 vb->inflate_vq = vqs[0]; in init_vqs()
409 vb->deflate_vq = vqs[1]; in init_vqs()
410 if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) { in init_vqs()
413 vb->stats_vq = vqs[2]; in init_vqs()
419 num_stats = update_balloon_stats(vb); in init_vqs()
421 sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats); in init_vqs()
422 err = virtqueue_add_outbuf(vb->stats_vq, &sg, 1, vb, in init_vqs()
425 dev_warn(&vb->vdev->dev, "%s: add stat_vq failed\n", in init_vqs()
429 virtqueue_kick(vb->stats_vq); in init_vqs()
447 * 1) insert newpage into vb->pages list and update the host about it;
448 * 2) update the host about the old page removed from vb->pages list;
456 struct virtio_balloon *vb = container_of(vb_dev_info, in virtballoon_migratepage() local
468 if (!mutex_trylock(&vb->balloon_lock)) in virtballoon_migratepage()
478 if (!virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM) && in virtballoon_migratepage()
490 vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE; in virtballoon_migratepage()
491 set_page_pfns(vb, vb->pfns, newpage); in virtballoon_migratepage()
492 tell_host(vb, vb->inflate_vq); in virtballoon_migratepage()
498 vb->num_pfns = VIRTIO_BALLOON_PAGES_PER_PAGE; in virtballoon_migratepage()
499 set_page_pfns(vb, vb->pfns, page); in virtballoon_migratepage()
500 tell_host(vb, vb->deflate_vq); in virtballoon_migratepage()
502 mutex_unlock(&vb->balloon_lock); in virtballoon_migratepage()
532 struct virtio_balloon *vb = container_of(shrinker, in virtio_balloon_shrinker_scan() local
542 while (vb->num_pages && pages_to_free) { in virtio_balloon_shrinker_scan()
544 pages_freed += leak_balloon(vb, pages_to_free); in virtio_balloon_shrinker_scan()
546 update_balloon_size(vb); in virtio_balloon_shrinker_scan()
554 struct virtio_balloon *vb = container_of(shrinker, in virtio_balloon_shrinker_count() local
557 return vb->num_pages / VIRTIO_BALLOON_PAGES_PER_PAGE; in virtio_balloon_shrinker_count()
560 static void virtio_balloon_unregister_shrinker(struct virtio_balloon *vb) in virtio_balloon_unregister_shrinker() argument
562 unregister_shrinker(&vb->shrinker); in virtio_balloon_unregister_shrinker()
565 static int virtio_balloon_register_shrinker(struct virtio_balloon *vb) in virtio_balloon_register_shrinker() argument
567 vb->shrinker.scan_objects = virtio_balloon_shrinker_scan; in virtio_balloon_register_shrinker()
568 vb->shrinker.count_objects = virtio_balloon_shrinker_count; in virtio_balloon_register_shrinker()
569 vb->shrinker.seeks = DEFAULT_SEEKS; in virtio_balloon_register_shrinker()
571 return register_shrinker(&vb->shrinker); in virtio_balloon_register_shrinker()
576 struct virtio_balloon *vb; in virtballoon_probe() local
585 vdev->priv = vb = kzalloc(sizeof(*vb), GFP_KERNEL); in virtballoon_probe()
586 if (!vb) { in virtballoon_probe()
591 INIT_WORK(&vb->update_balloon_stats_work, update_balloon_stats_func); in virtballoon_probe()
592 INIT_WORK(&vb->update_balloon_size_work, update_balloon_size_func); in virtballoon_probe()
593 spin_lock_init(&vb->stop_update_lock); in virtballoon_probe()
594 mutex_init(&vb->balloon_lock); in virtballoon_probe()
595 init_waitqueue_head(&vb->acked); in virtballoon_probe()
596 vb->vdev = vdev; in virtballoon_probe()
598 balloon_devinfo_init(&vb->vb_dev_info); in virtballoon_probe()
600 err = init_vqs(vb); in virtballoon_probe()
611 vb->vb_dev_info.migratepage = virtballoon_migratepage; in virtballoon_probe()
612 vb->vb_dev_info.inode = alloc_anon_inode(balloon_mnt->mnt_sb); in virtballoon_probe()
613 if (IS_ERR(vb->vb_dev_info.inode)) { in virtballoon_probe()
614 err = PTR_ERR(vb->vb_dev_info.inode); in virtballoon_probe()
618 vb->vb_dev_info.inode->i_mapping->a_ops = &balloon_aops; in virtballoon_probe()
624 if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) { in virtballoon_probe()
625 err = virtio_balloon_register_shrinker(vb); in virtballoon_probe()
631 if (towards_target(vb)) in virtballoon_probe()
638 kfree(vb); in virtballoon_probe()
643 static void remove_common(struct virtio_balloon *vb) in remove_common() argument
646 while (vb->num_pages) in remove_common()
647 leak_balloon(vb, vb->num_pages); in remove_common()
648 update_balloon_size(vb); in remove_common()
651 vb->vdev->config->reset(vb->vdev); in remove_common()
653 vb->vdev->config->del_vqs(vb->vdev); in remove_common()
658 struct virtio_balloon *vb = vdev->priv; in virtballoon_remove() local
660 if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_DEFLATE_ON_OOM)) in virtballoon_remove()
661 virtio_balloon_unregister_shrinker(vb); in virtballoon_remove()
662 spin_lock_irq(&vb->stop_update_lock); in virtballoon_remove()
663 vb->stop_update = true; in virtballoon_remove()
664 spin_unlock_irq(&vb->stop_update_lock); in virtballoon_remove()
665 cancel_work_sync(&vb->update_balloon_size_work); in virtballoon_remove()
666 cancel_work_sync(&vb->update_balloon_stats_work); in virtballoon_remove()
668 remove_common(vb); in virtballoon_remove()
670 if (vb->vb_dev_info.inode) in virtballoon_remove()
671 iput(vb->vb_dev_info.inode); in virtballoon_remove()
675 kfree(vb); in virtballoon_remove()
681 struct virtio_balloon *vb = vdev->priv; in virtballoon_freeze() local
687 remove_common(vb); in virtballoon_freeze()
693 struct virtio_balloon *vb = vdev->priv; in virtballoon_restore() local
702 if (towards_target(vb)) in virtballoon_restore()
704 update_balloon_size(vb); in virtballoon_restore()