{
int rc = 0;
uint32_t target_memkb = 0;
+ uint64_t current_memkb, prev_memkb;
libxl_dominfo info;
+ rc = libxl_get_memory_target(ctx, domid, &target_memkb);
+ if (rc < 0)
+ return rc;
+
libxl_dominfo_init(&info);
+ prev_memkb = UINT64_MAX;
do {
- wait_secs--;
sleep(1);
- rc = libxl_get_memory_target(ctx, domid, &target_memkb);
- if (rc < 0)
- goto out;
-
libxl_dominfo_dispose(&info);
libxl_dominfo_init(&info);
rc = libxl_domain_info(ctx, &info, domid);
if (rc < 0)
goto out;
- } while (wait_secs > 0 && (info.current_memkb + info.outstanding_memkb) > target_memkb);
- if ((info.current_memkb + info.outstanding_memkb) <= target_memkb)
+ current_memkb = info.current_memkb + info.outstanding_memkb;
+
+ if (current_memkb > prev_memkb)
+ {
+ rc = ERROR_FAIL;
+ goto out;
+ }
+ else if (current_memkb == prev_memkb)
+ wait_secs--;
+ /* if current_memkb < prev_memkb loop for free as progress has
+ * been made */
+
+ prev_memkb = current_memkb;
+ } while (wait_secs > 0 && current_memkb > target_memkb);
+
+ if (current_memkb <= target_memkb)
rc = 0;
else
rc = ERROR_FAIL;
int libxl_get_free_memory(libxl_ctx *ctx, uint32_t *memkb);
/* wait for a given amount of memory to be free in the system */
int libxl_wait_for_free_memory(libxl_ctx *ctx, uint32_t domid, uint32_t memory_kb, int wait_secs);
-/* wait for the memory target of a domain to be reached */
+/*
+ * Wait for the memory target of a domain to be reached. Does not
+ * decrement wait_secs if the domain is making progress toward reaching
+ * the target. If the domain is not making progress, wait_secs is
+ * decremented. If the timeout expires before the target is reached, the
+ * function returns ERROR_FAIL.
+ *
+ * Older versions of this function (Xen 4.5 and older), decremented
+ * wait_secs even if the domain was making progress, resulting in far
+ * lower overall wait times. To make sure that your calling routine
+ * works with new and old implementations of the function, pass enough
+ * time for the guest to reach its target as an argument.
+ */
int libxl_wait_for_memory_target(libxl_ctx *ctx, uint32_t domid, int wait_secs);
int libxl_vncviewer_exec(libxl_ctx *ctx, uint32_t domid, int autopass);
else if (rc != ERROR_NOMEM)
return rc;
- /* the memory target has been reached but the free memory is still
- * not enough: loop over again */
+ /* wait until dom0 reaches its target, as long as we are making
+ * progress */
rc = libxl_wait_for_memory_target(ctx, 0, 1);
if (rc < 0)
return rc;