From patchwork Thu May 24 00:13:35 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: William Kennington X-Patchwork-Id: 919473 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 40rqhr0HJZz9s1B for ; Thu, 24 May 2018 10:17:48 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=reject dis=none) header.from=google.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="YlwoqwSj"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 40rqhq4hz5zF1F0 for ; Thu, 24 May 2018 10:17:47 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="YlwoqwSj"; dkim-atps=neutral X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=flex--wak.bounces.google.com (client-ip=2607:f8b0:4001:c06::249; helo=mail-io0-x249.google.com; envelope-from=34gmgwwmkb98xblhpphmf.dpntljcppumjtut.pambct.psh@flex--wak.bounces.google.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="YlwoqwSj"; dkim-atps=neutral Received: from mail-io0-x249.google.com (mail-io0-x249.google.com [IPv6:2607:f8b0:4001:c06::249]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 40rqd658HqzF1H5 for ; Thu, 24 May 2018 10:14:28 +1000 (AEST) Received: by mail-io0-x249.google.com with SMTP id w1-v6so166283iod.1 for ; Wed, 23 May 2018 17:14:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=mime-version:date:in-reply-to:message-id:references:subject:from:to :cc; bh=ftwlXVycVA9UU/qzwRWWU9qdvZg8Uw/lnodIy7qj9Gs=; b=YlwoqwSj2cREK10PQWVRm6joDa4zWnXoiLjViH+jG+POhf7G5NbQ8slb0y1zCMpcPH RD5fyzGQV7jyBfDoSiR0KN5k5nQXiXXDEDEftwXJ6sUp8bOZ7bfadZl9rxKg76EVG9g9 srQONryWWlUihpgyPOedFQhDMBszrH+hkt09iO5neNHeBs6i7CTvQVxDv7Vc6+bme3n2 hzs0akDkUjZC9MJ8hRCifYTbQbOVdvrEg02surMT9c9hQtWLY2o3fGT7p4QSFcYnW4pL iFwufs61myr72OOUWelCROU5m2j3gi8wko0/qY7sR21a26Jbgw92B3bYwj3ZlOBFhjZm mzuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:date:in-reply-to:message-id :references:subject:from:to:cc; bh=ftwlXVycVA9UU/qzwRWWU9qdvZg8Uw/lnodIy7qj9Gs=; b=N3oOewjKTkVcDwP0sLOiDs1pYsjxvxObBclqtCenFjCQrcpmhr94VOSNpJ01bwW/0r 28hf2chGH/LQDIyPwYNdE9eBmit4NatJDB43RZouAJPvDjyXL8W0SkFHBY1vbCi4tr2e utyggnUE4Jksd3eMUR3w/KhhLpmCytLlnbhaOQ4rvpOGINryi/LrOLz8eUtgsNkNqekv CXxi3KeWda295WU/Tirrn9lL4FKSGlUlqiMfsGmpYk6MxtZPzisYTL5NNkN/7Sm/ym02 qR6oUcmvgQ0FIujjuUSi+AhichCL2e3D2TmsIpwbxWScxP4AeHn9hMFk8oakrqQBRzfE h0eA== X-Gm-Message-State: ALKqPwcxph/IQ8Zg3HQKVffwjgO6KFm8O0PqpnBbaX8OlZg2Jh64svEh LuxRMUC+vgTpJOwj7V+YFRsXv/y5FDQ42gxrfJvD0ZDgh9PX/k0bl7m4uBWy2XmJBv1JA2Zc6Mu woVHHqY/x5gohg7OV8p7CaZ1tWU55mE/oG/XsEsaBIM+xldXDXQlIze15 X-Google-Smtp-Source: AB8JxZotWk2uu7RUCH3a9pVsmnHn5EP1AohL7jW2iz0zrSta2L6CZ/h4ysnm0gbeW98/7zSjPMefOmk= MIME-Version: 1.0 X-Received: by 2002:a24:e4d:: with SMTP id 74-v6mr3451606ite.24.1527120866752; Wed, 23 May 2018 17:14:26 -0700 (PDT) Date: Wed, 23 May 2018 17:13:35 -0700 In-Reply-To: <20180524001335.15457-1-wak@google.com> Message-Id: <20180524001335.15457-10-wak@google.com> References: <20180524001335.15457-1-wak@google.com> X-Mailer: git-send-email 2.17.0 From: "William A. Kennington III" To: skiboot@lists.ozlabs.org, alistair@popple.id.au, jk@ozlabs.org Subject: [Skiboot] [PATCH 9/9] ipmi-watchdog: Support handling re-initialization X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" Watchdog resets can return an error code from the BMC indicating that the BMC watchdog was not initialized. Currently we abort skiboot due to a missing error handler. This patch implements handling re-initialization for the watchdog, automatically saving the last watchdog set values and re-issuing them if needed. Signed-off-by: William A. Kennington III --- hw/ipmi/ipmi-watchdog.c | 47 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/hw/ipmi/ipmi-watchdog.c b/hw/ipmi/ipmi-watchdog.c index 1472a8ea1..105270f5e 100644 --- a/hw/ipmi/ipmi-watchdog.c +++ b/hw/ipmi/ipmi-watchdog.c @@ -34,8 +34,13 @@ #define WDT_RESET_ACTION 0x01 #define WDT_NO_ACTION 0x00 +/* IPMI defined custom completion codes for the watchdog */ +#define WDT_CC_OK 0x00 +#define WDT_CC_NOT_INITIALIZED 0x80 + /* Flags used for IPMI callbacks */ #define WDT_SET_DO_RESET 0x01 +#define WDT_RESET_NO_REINIT 0x01 /* How long to set the overall watchdog timeout for. In units of * 100ms. If the timer is not reset within this time the watchdog @@ -52,14 +57,23 @@ static struct timer wdt_timer; static bool wdt_stopped; static bool wdt_ticking; +/* Saved values from the last watchdog set action */ +static uint8_t last_action; +static uint16_t last_count; +static uint8_t last_pretimeout; + static void reset_wdt(struct timer *t, void *data, uint64_t now); static void set_wdt_complete(struct ipmi_msg *msg) { const uintptr_t flags = (uintptr_t)msg->user_data; - if (flags & WDT_SET_DO_RESET) - reset_wdt(NULL, NULL, 0); + if (flags & WDT_SET_DO_RESET) { + /* Make sure the reset action does not create a loop and + * perform a reset in the case where the BMC send an + * uninitialized error. */ + reset_wdt(NULL, (void *)WDT_RESET_NO_REINIT, 0); + } ipmi_free_msg(msg); } @@ -73,6 +87,12 @@ static void set_wdt(uint8_t action, uint16_t count, uint8_t pretimeout, if (do_reset) completion_flags |= WDT_SET_DO_RESET; + /* Save the values prior to issuing the set operation so that we can + * re-initialize the watchdog in error cases. */ + last_action = action; + last_count = count; + last_pretimeout = pretimeout; + ipmi_msg = ipmi_mkmsg(IPMI_DEFAULT_INTERFACE, IPMI_SET_WDT, set_wdt_complete, NULL, NULL, 6, 0); if (!ipmi_msg) { @@ -94,7 +114,21 @@ static void set_wdt(uint8_t action, uint16_t count, uint8_t pretimeout, static void reset_wdt_complete(struct ipmi_msg *msg) { - const uint64_t reset_delay_ms = (WDT_TIMEOUT - WDT_MARGIN) * 100; + const uintptr_t flags = (uintptr_t)msg->user_data; + uint64_t reset_delay_ms = (WDT_TIMEOUT - WDT_MARGIN) * 100; + + if (msg->cc == WDT_CC_NOT_INITIALIZED && + !(flags & WDT_RESET_NO_REINIT)) { + /* If our timer was not initialized on the BMC side, we should + * perform a single attempt to set it up again. */ + set_wdt(last_action, last_count, last_pretimeout, true, true); + } else if (msg->cc != WDT_CC_OK) { + /* Use a short (10s) timeout before performing the next reset + * if we encounter an unknown error. This makes sure that we + * are able to reset and re-initialize the timer since it might + * expire. */ + reset_delay_ms = 10 * 1000; + } /* If we are inside of skiboot we need to periodically restart the * timer. Reschedule a reset so it happens before the timeout. */ @@ -114,6 +148,7 @@ static struct ipmi_msg *wdt_reset_mkmsg(void) prerror("Unable to allocate reset wdt message\n"); return NULL; } + ipmi_msg->error = reset_wdt_complete; return ipmi_msg; } @@ -126,13 +161,15 @@ static void sync_reset_wdt(void) ipmi_queue_msg_sync(ipmi_msg); } -static void reset_wdt(struct timer *t __unused, void *data __unused, +static void reset_wdt(struct timer *t __unused, void *data, uint64_t now __unused) { struct ipmi_msg *ipmi_msg; - if ((ipmi_msg = wdt_reset_mkmsg())) + if ((ipmi_msg = wdt_reset_mkmsg())) { + ipmi_msg->user_data = data; ipmi_queue_msg_head(ipmi_msg); + } } void ipmi_wdt_stop(void)