linux/drivers/virtio/virtio_balloon.c

// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Virtio balloon implementation, inspired by Dor Laor and Marcelo
 * Tosatti's implementations.
 *
 *  Copyright 2008 Rusty Russell IBM Corporation
 */

#include <linux/virtio.h>
#include <linux/virtio_balloon.h>
#include <linux/swap.h>
#include <linux/workqueue.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/balloon_compaction.h>
#include <linux/oom.h>
#include <linux/wait.h>
#include <linux/mm.h>
#include <linux/page_reporting.h>

/*
 * Balloon device works in 4K page units.  So each page is pointed to by
 * multiple balloon pages.  All memory counters in this driver are in balloon
 * page units.
 */
#define VIRTIO_BALLOON_PAGES_PER_PAGE
#define VIRTIO_BALLOON_ARRAY_PFNS_MAX
/* Maximum number of (4k) pages to deflate on OOM notifications. */
#define VIRTIO_BALLOON_OOM_NR_PAGES
#define VIRTIO_BALLOON_OOM_NOTIFY_PRIORITY

#define VIRTIO_BALLOON_FREE_PAGE_ALLOC_FLAG
/* The order of free page blocks to report to host */
#define VIRTIO_BALLOON_HINT_BLOCK_ORDER
/* The size of a free page block in bytes */
#define VIRTIO_BALLOON_HINT_BLOCK_BYTES
#define VIRTIO_BALLOON_HINT_BLOCK_PAGES

enum virtio_balloon_vq {};

enum virtio_balloon_config_read {};

struct virtio_balloon {};

#define VIRTIO_BALLOON_WAKEUP_SIGNAL_ADJUST
#define VIRTIO_BALLOON_WAKEUP_SIGNAL_STATS

static const struct virtio_device_id id_table[] =;

static u32 page_to_balloon_pfn(struct page *page)
{}

static void start_wakeup_event(struct virtio_balloon *vb, u32 mask)
{}

static void process_wakeup_event(struct virtio_balloon *vb, u32 mask)
{}

static void finish_wakeup_event(struct virtio_balloon *vb)
{}

static void balloon_ack(struct virtqueue *vq)
{}

static void tell_host(struct virtio_balloon *vb, struct virtqueue *vq)
{}

static int virtballoon_free_page_report(struct page_reporting_dev_info *pr_dev_info,
				   struct scatterlist *sg, unsigned int nents)
{}

static void set_page_pfns(struct virtio_balloon *vb,
			  __virtio32 pfns[], struct page *page)
{}

static unsigned int fill_balloon(struct virtio_balloon *vb, size_t num)
{}

static void release_pages_balloon(struct virtio_balloon *vb,
				 struct list_head *pages)
{}

static unsigned int leak_balloon(struct virtio_balloon *vb, size_t num)
{}

static inline void update_stat(struct virtio_balloon *vb, int idx,
			       u16 tag, u64 val)
{}

#define pages_to_bytes(x)

#ifdef CONFIG_VM_EVENT_COUNTERS
/* Return the number of entries filled by vm events */
static inline unsigned int update_balloon_vm_stats(struct virtio_balloon *vb)
{}
#else /* CONFIG_VM_EVENT_COUNTERS */
static inline unsigned int update_balloon_vm_stats(struct virtio_balloon *vb)
{
	return 0;
}
#endif /* CONFIG_VM_EVENT_COUNTERS */

static unsigned int update_balloon_stats(struct virtio_balloon *vb)
{}

/*
 * While most virtqueues communicate guest-initiated requests to the hypervisor,
 * the stats queue operates in reverse.  The driver initializes the virtqueue
 * with a single buffer.  From that point forward, all conversations consist of
 * a hypervisor request (a call to this function) which directs us to refill
 * the virtqueue with a fresh stats buffer.  Since stats collection can sleep,
 * we delegate the job to a freezable workqueue that will do the actual work via
 * stats_handle_request().
 */
static void stats_request(struct virtqueue *vq)
{}

static void stats_handle_request(struct virtio_balloon *vb)
{}

static inline s64 towards_target(struct virtio_balloon *vb)
{}

/* Gives back @num_to_return blocks of free pages to mm. */
static unsigned long return_free_pages_to_mm(struct virtio_balloon *vb,
					     unsigned long num_to_return)
{}

static void virtio_balloon_queue_free_page_work(struct virtio_balloon *vb)
{}

static void start_update_balloon_size(struct virtio_balloon *vb)
{}

static void virtballoon_changed(struct virtio_device *vdev)
{}

static void update_balloon_size(struct virtio_balloon *vb)
{}

static void update_balloon_stats_func(struct work_struct *work)
{}

static void update_balloon_size_func(struct work_struct *work)
{}

static int init_vqs(struct virtio_balloon *vb)
{}

static u32 virtio_balloon_cmd_id_received(struct virtio_balloon *vb)
{}

static int send_cmd_id_start(struct virtio_balloon *vb)
{}

static int send_cmd_id_stop(struct virtio_balloon *vb)
{}

static int get_free_page_and_send(struct virtio_balloon *vb)
{}

static int send_free_pages(struct virtio_balloon *vb)
{}

static void virtio_balloon_report_free_page(struct virtio_balloon *vb)
{}

static void report_free_page_func(struct work_struct *work)
{}

#ifdef CONFIG_BALLOON_COMPACTION
/*
 * virtballoon_migratepage - perform the balloon page migration on behalf of
 *			     a compaction thread.     (called under page lock)
 * @vb_dev_info: the balloon device
 * @newpage: page that will replace the isolated page after migration finishes.
 * @page   : the isolated (old) page that is about to be migrated to newpage.
 * @mode   : compaction mode -- not used for balloon page migration.
 *
 * After a ballooned page gets isolated by compaction procedures, this is the
 * function that performs the page migration on behalf of a compaction thread
 * The page migration for virtio balloon is done in a simple swap fashion which
 * follows these two macro steps:
 *  1) insert newpage into vb->pages list and update the host about it;
 *  2) update the host about the old page removed from vb->pages list;
 *
 * This function preforms the balloon page migration task.
 * Called through movable_operations->migrate_page
 */
static int virtballoon_migratepage(struct balloon_dev_info *vb_dev_info,
		struct page *newpage, struct page *page, enum migrate_mode mode)
{}
#endif /* CONFIG_BALLOON_COMPACTION */

static unsigned long shrink_free_pages(struct virtio_balloon *vb,
				       unsigned long pages_to_free)
{}

static unsigned long virtio_balloon_shrinker_scan(struct shrinker *shrinker,
						  struct shrink_control *sc)
{}

static unsigned long virtio_balloon_shrinker_count(struct shrinker *shrinker,
						   struct shrink_control *sc)
{}

static int virtio_balloon_oom_notify(struct notifier_block *nb,
				     unsigned long dummy, void *parm)
{}

static void virtio_balloon_unregister_shrinker(struct virtio_balloon *vb)
{}

static int virtio_balloon_register_shrinker(struct virtio_balloon *vb)
{}

static int virtballoon_probe(struct virtio_device *vdev)
{}

static void remove_common(struct virtio_balloon *vb)
{}

static void virtballoon_remove(struct virtio_device *vdev)
{}

#ifdef CONFIG_PM_SLEEP
static int virtballoon_freeze(struct virtio_device *vdev)
{}

static int virtballoon_restore(struct virtio_device *vdev)
{}
#endif

static int virtballoon_validate(struct virtio_device *vdev)
{}

static unsigned int features[] =;

static struct virtio_driver virtio_balloon_driver =;

module_virtio_driver();
MODULE_DEVICE_TABLE(virtio, id_table);
MODULE_DESCRIPTION();
MODULE_LICENSE();