34 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
36 #include <linux/types.h>
37 #include <linux/kernel.h>
39 #include <linux/sched.h>
40 #include <linux/module.h>
44 #include <asm/hypervisor.h>
62 #define VMW_BALLOON_NOSLEEP_ALLOC_MAX 16384U
68 #define VMW_BALLOON_RATE_ALLOC_MIN 512U
69 #define VMW_BALLOON_RATE_ALLOC_MAX 2048U
70 #define VMW_BALLOON_RATE_ALLOC_INC 16U
75 #define VMW_BALLOON_RATE_FREE_MIN 512U
76 #define VMW_BALLOON_RATE_FREE_MAX 16384U
77 #define VMW_BALLOON_RATE_FREE_INC 16U
83 #define VMW_BALLOON_SLOW_CYCLES 4
90 #define VMW_PAGE_ALLOC_NOSLEEP (__GFP_HIGHMEM|__GFP_NOWARN)
99 #define VMW_PAGE_ALLOC_CANSLEEP (GFP_HIGHUSER)
102 #define VMW_BALLOON_YIELD_THRESHOLD 1024
105 #define VMW_BALLOON_MAX_REFUSED 16
110 #define VMW_BALLOON_HV_PORT 0x5670
111 #define VMW_BALLOON_HV_MAGIC 0x456c6d6f
112 #define VMW_BALLOON_PROTOCOL_VERSION 2
113 #define VMW_BALLOON_GUEST_ID 1
115 #define VMW_BALLOON_CMD_START 0
116 #define VMW_BALLOON_CMD_GET_TARGET 1
117 #define VMW_BALLOON_CMD_LOCK 2
118 #define VMW_BALLOON_CMD_UNLOCK 3
119 #define VMW_BALLOON_CMD_GUEST_ID 4
122 #define VMW_BALLOON_SUCCESS 0
123 #define VMW_BALLOON_FAILURE -1
124 #define VMW_BALLOON_ERROR_CMD_INVALID 1
125 #define VMW_BALLOON_ERROR_PPN_INVALID 2
126 #define VMW_BALLOON_ERROR_PPN_LOCKED 3
127 #define VMW_BALLOON_ERROR_PPN_UNLOCKED 4
128 #define VMW_BALLOON_ERROR_PPN_PINNED 5
129 #define VMW_BALLOON_ERROR_PPN_NOTNEEDED 6
130 #define VMW_BALLOON_ERROR_RESET 7
131 #define VMW_BALLOON_ERROR_BUSY 8
133 #define VMWARE_BALLOON_CMD(cmd, data, result) \
135 unsigned long __stat, __dummy1, __dummy2; \
136 __asm__ __volatile__ ("inl (%%dx)" : \
141 "0"(VMW_BALLOON_HV_MAGIC), \
142 "1"(VMW_BALLOON_CMD_##cmd), \
143 "2"(VMW_BALLOON_HV_PORT), \
150 #ifdef CONFIG_DEBUG_FS
151 struct vmballoon_stats {
156 unsigned int alloc_fail;
157 unsigned int sleep_alloc;
158 unsigned int sleep_alloc_fail;
159 unsigned int refused_alloc;
160 unsigned int refused_free;
165 unsigned int lock_fail;
167 unsigned int unlock_fail;
169 unsigned int target_fail;
171 unsigned int start_fail;
172 unsigned int guest_type;
173 unsigned int guest_type_fail;
176 #define STATS_INC(stat) (stat)++
178 #define STATS_INC(stat)
204 #ifdef CONFIG_DEBUG_FS
206 struct vmballoon_stats
stats;
223 static bool vmballoon_send_start(
struct vmballoon *
b)
233 pr_debug(
"%s - failed, hv returns %ld\n", __func__, status);
238 static bool vmballoon_check_status(
struct vmballoon *b,
unsigned long status)
259 static bool vmballoon_send_guest_id(
struct vmballoon *b)
267 if (vmballoon_check_status(b, status))
270 pr_debug(
"%s - failed, hv returns %ld\n", __func__, status);
278 static bool vmballoon_send_get_target(
struct vmballoon *b,
u32 *new_target)
294 limit32 = (
u32)limit;
295 if (limit != limit32)
302 if (vmballoon_check_status(b, status)) {
307 pr_debug(
"%s - failed, hv returns %ld\n", __func__, status);
317 static int vmballoon_send_lock_page(
struct vmballoon *b,
unsigned long pfn,
318 unsigned int *hv_status)
330 if (vmballoon_check_status(b, status))
333 pr_debug(
"%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
342 static bool vmballoon_send_unlock_page(
struct vmballoon *b,
unsigned long pfn)
354 if (vmballoon_check_status(b, status))
357 pr_debug(
"%s - ppn %lx, hv returns %ld\n", __func__, pfn, status);
368 static void vmballoon_pop(
struct vmballoon *b)
371 unsigned int count = 0;
391 static void vmballoon_reset(
struct vmballoon *b)
396 if (vmballoon_send_start(b)) {
398 if (!vmballoon_send_guest_id(b))
399 pr_err(
"failed to send guest ID to the host\n");
409 static int vmballoon_reserve_page(
struct vmballoon *b,
bool can_sleep)
413 unsigned int hv_status;
433 locked = vmballoon_send_lock_page(b,
page_to_pfn(page), &hv_status);
452 }
while (locked != 0);
468 static int vmballoon_release_page(
struct vmballoon *b,
struct page *page)
470 if (!vmballoon_send_unlock_page(b,
page_to_pfn(page)))
489 static void vmballoon_release_refused_pages(
struct vmballoon *b)
507 static void vmballoon_inflate(
struct vmballoon *b)
512 unsigned int allocations = 0;
514 bool alloc_can_sleep =
false;
541 pr_debug(
"%s - goal: %d, no-sleep rate: %d, sleep rate: %d\n",
544 for (i = 0; i < goal; i++) {
546 error = vmballoon_reserve_page(b, alloc_can_sleep);
557 if (alloc_can_sleep) {
581 alloc_can_sleep =
true;
609 vmballoon_release_refused_pages(b);
615 static void vmballoon_deflate(
struct vmballoon *b)
631 error = vmballoon_release_page(b, page);
666 if (vmballoon_send_get_target(b, &target)) {
670 if (b->
size < target)
671 vmballoon_inflate(b);
672 else if (b->
size > target)
673 vmballoon_deflate(b);
687 #ifdef CONFIG_DEBUG_FS
692 struct vmballoon_stats *
stats = &b->stats;
696 "target: %8d pages\n"
697 "current: %8d pages\n",
702 "rateNoSleepAlloc: %8d pages/sec\n"
703 "rateSleepAlloc: %8d pages/sec\n"
704 "rateFree: %8d pages/sec\n",
711 "start: %8u (%4u failed)\n"
712 "guestType: %8u (%4u failed)\n"
713 "lock: %8u (%4u failed)\n"
714 "unlock: %8u (%4u failed)\n"
715 "target: %8u (%4u failed)\n"
716 "primNoSleepAlloc: %8u (%4u failed)\n"
717 "primCanSleepAlloc: %8u (%4u failed)\n"
722 stats->start, stats->start_fail,
723 stats->guest_type, stats->guest_type_fail,
724 stats->lock, stats->lock_fail,
725 stats->unlock, stats->unlock_fail,
726 stats->target, stats->target_fail,
727 stats->alloc, stats->alloc_fail,
728 stats->sleep_alloc, stats->sleep_alloc_fail,
730 stats->refused_alloc, stats->refused_free);
742 .open = vmballoon_debug_open,
753 &vmballoon_debug_fops);
754 if (IS_ERR(b->dbg_entry)) {
755 error = PTR_ERR(b->dbg_entry);
756 pr_err(
"failed to create debugfs entry, error: %d\n", error);
770 static inline int vmballoon_debugfs_init(
struct vmballoon *b)
775 static inline void vmballoon_debugfs_exit(
struct vmballoon *b)
781 static int __init vmballoon_init(
void)
792 INIT_LIST_HEAD(&balloon.pages);
793 INIT_LIST_HEAD(&balloon.refused_pages);
804 if (!vmballoon_send_start(&balloon)) {
805 pr_err(
"failed to send start command to the host\n");
809 if (!vmballoon_send_guest_id(&balloon)) {
810 pr_err(
"failed to send guest ID to the host\n");
814 error = vmballoon_debugfs_init(&balloon);
824 static void __exit vmballoon_exit(
void)
828 vmballoon_debugfs_exit(&balloon);
835 vmballoon_send_start(&balloon);
836 vmballoon_pop(&balloon);