From: Owen Smith Date: Tue, 15 Dec 2015 11:30:18 +0000 (+0000) Subject: BSOD if initial balloon thread has not completed within 20 minutes X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=be94a72a2d2c0b3849cebafe5e919cd4f7a52797;p=people%2Fpauldu%2Fxenbus.git BSOD if initial balloon thread has not completed within 20 minutes Since there is no way of reporting balloon failures to the toolstack, the only way of stopping a VM from attempting to balloon indefinitely is to BSOD after a large timeout. Signed-off-by: Owen Smith Largely cosmetic changes (comments and #defines). Signed-off-by: Paul Durrant --- diff --git a/src/xenbus/fdo.c b/src/xenbus/fdo.c index 9c9e380..da5cdcc 100644 --- a/src/xenbus/fdo.c +++ b/src/xenbus/fdo.c @@ -1532,9 +1532,9 @@ loop: return STATUS_SUCCESS; } -#define TIME_US(_us) ((_us) * 10) -#define TIME_MS(_ms) (TIME_US((_ms) * 1000)) -#define TIME_S(_s) (TIME_MS((_s) * 1000)) +#define TIME_US(_us) ((_us) * 10ll) +#define TIME_MS(_ms) (TIME_US((_ms) * 1000ll)) +#define TIME_S(_s) (TIME_MS((_s) * 1000ll)) #define TIME_RELATIVE(_t) (-(_t)) static FORCEINLINE NTSTATUS @@ -3251,7 +3251,8 @@ FdoFilterCmPartialResourceList( } } -#define BALLOON_PAUSE 60 +#define BALLOON_WARN_TIMEOUT 10 +#define BALLOON_BUGCHECK_TIMEOUT 1200 static NTSTATUS FdoStartDevice( @@ -3356,29 +3357,38 @@ not_active: goto fail8; if (Fdo->BalloonInterface.Interface.Context != NULL) { - BOOLEAN Warned; + LARGE_INTEGER Timeout; ASSERT(__FdoIsActive(Fdo)); - Warned = FALSE; - - for (;;) { - LARGE_INTEGER Timeout; - - Timeout.QuadPart = TIME_RELATIVE(TIME_S(BALLOON_PAUSE)); + // + // Balloon inflation should complete within a reasonable + // time (otherwise the target is probably unreasonable). + // + Timeout.QuadPart = TIME_RELATIVE(TIME_S(BALLOON_WARN_TIMEOUT)); + + status = KeWaitForSingleObject(&Fdo->BalloonEvent, + Executive, + KernelMode, + FALSE, + &Timeout); + if (status == STATUS_TIMEOUT) { + Warning("waiting for balloon\n"); + + // + // If inflation does not complete after a lengthy timeout + // then it is unlikely that it ever will. In this case we + // cause a bugcheck. + // + Timeout.QuadPart = TIME_RELATIVE(TIME_S((BALLOON_BUGCHECK_TIMEOUT - BALLOON_WARN_TIMEOUT))); status = KeWaitForSingleObject(&Fdo->BalloonEvent, - Executive, - KernelMode, - FALSE, - &Timeout); - if (status != STATUS_TIMEOUT) - break; - - if (!Warned) { - Warning("waiting for balloon\n"); - Warned = TRUE; - } + Executive, + KernelMode, + FALSE, + &Timeout); + if (status == STATUS_TIMEOUT) + BUG("BALLOON INFLATION TIMEOUT\n"); } }