[PATCH 2/3] vmw_balloon: exit if initalization fails

From: Nadav Amit
Date: Tue Sep 13 2022 - 14:11:51 EST


From: Nadav Amit <namit@xxxxxxxxxx>

In certain VMware hypervisor variants the balloon might not be
supported. In such cases initialization would fail, but resources would
keep being unnecessarily wasted. The balloon driver would retry
reinitialization every second for no reason.

Initialize the balloon once during init, before starting the worker. If
initialization fails, put out a message and fail gracefully.

Signed-off-by: Nadav Amit <namit@xxxxxxxxxx>
---
drivers/misc/vmw_balloon.c | 37 ++++++++++++++++++++++++-------------
1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/drivers/misc/vmw_balloon.c b/drivers/misc/vmw_balloon.c
index 7fa91983c567..762442b9ece8 100644
--- a/drivers/misc/vmw_balloon.c
+++ b/drivers/misc/vmw_balloon.c
@@ -1416,7 +1416,7 @@ static void vmballoon_pop(struct vmballoon *b)
* is not empty) and then restarting protocol. This operation normally
* happens when host responds with VMW_BALLOON_ERROR_RESET to a command.
*/
-static void vmballoon_reset(struct vmballoon *b)
+static int vmballoon_reset(struct vmballoon *b)
{
int error;

@@ -1427,11 +1427,13 @@ static void vmballoon_reset(struct vmballoon *b)
/* free all pages, skipping monitor unlock */
vmballoon_pop(b);

- if (vmballoon_send_start(b, VMW_BALLOON_CAPABILITIES))
+ error = vmballoon_send_start(b, VMW_BALLOON_CAPABILITIES);
+ if (error)
goto unlock;

if ((b->capabilities & VMW_BALLOON_BATCHED_CMDS) != 0) {
- if (vmballoon_init_batching(b)) {
+ error = vmballoon_init_batching(b);
+ if (error) {
/*
* We failed to initialize batching, inform the monitor
* about it by sending a null capability.
@@ -1448,8 +1450,7 @@ static void vmballoon_reset(struct vmballoon *b)
vmballoon_stats_gen_inc(b, VMW_BALLOON_STAT_RESET);
WRITE_ONCE(b->reset_required, false);

- error = vmballoon_vmci_init(b);
- if (error)
+ if (vmballoon_vmci_init(b))
pr_err_once("failed to initialize vmci doorbell\n");

if (vmballoon_send_guest_id(b))
@@ -1457,6 +1458,7 @@ static void vmballoon_reset(struct vmballoon *b)

unlock:
up_write(&b->conf_sem);
+ return error;
}

/**
@@ -1879,6 +1881,23 @@ static int __init vmballoon_init(void)
if (x86_hyper_type != X86_HYPER_VMWARE)
return -ENODEV;

+ INIT_LIST_HEAD(&balloon.huge_pages);
+ spin_lock_init(&balloon.comm_lock);
+ init_rwsem(&balloon.conf_sem);
+ balloon.vmci_doorbell = VMCI_INVALID_HANDLE;
+ balloon.batch_page = NULL;
+ balloon.page = NULL;
+ balloon.reset_required = true;
+
+ /*
+ * Reset the balloon to check that it is indeed supported.
+ */
+ error = vmballoon_reset(&balloon);
+ if (error) {
+ pr_err("memory ballooning is disabled");
+ goto fail;
+ }
+
INIT_DELAYED_WORK(&balloon.dwork, vmballoon_work);

error = vmballoon_register_shrinker(&balloon);
@@ -1892,14 +1911,6 @@ static int __init vmballoon_init(void)
balloon_devinfo_init(&balloon.b_dev_info);
vmballoon_compaction_init(&balloon);

- INIT_LIST_HEAD(&balloon.huge_pages);
- spin_lock_init(&balloon.comm_lock);
- init_rwsem(&balloon.conf_sem);
- balloon.vmci_doorbell = VMCI_INVALID_HANDLE;
- balloon.batch_page = NULL;
- balloon.page = NULL;
- balloon.reset_required = true;
-
queue_delayed_work(system_freezable_wq, &balloon.dwork, 0);

vmballoon_debugfs_init(&balloon);
--
2.25.1