From patchwork Wed Aug 17 08:51:30 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerald Yang X-Patchwork-Id: 1667148 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical.com header.i=@canonical.com header.a=rsa-sha256 header.s=20210705 header.b=KzaUfZGj; dkim-atps=neutral Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4M71wy2vngz1ygj for ; Wed, 17 Aug 2022 18:52:18 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1oOEmS-0000MQ-Pr; Wed, 17 Aug 2022 08:52:04 +0000 Received: from smtp-relay-internal-1.internal ([10.131.114.114] helo=smtp-relay-internal-1.canonical.com) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1oOEmP-0000L8-OC for kernel-team@lists.ubuntu.com; Wed, 17 Aug 2022 08:52:01 +0000 Received: from mail-pj1-f71.google.com (mail-pj1-f71.google.com [209.85.216.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-1.canonical.com (Postfix) with ESMTPS id 7E7D93F46B for ; Wed, 17 Aug 2022 08:52:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20210705; t=1660726321; bh=OSh6RBx2UPdYrPu+pLx83OWcHN+3ihEUeQxogZBZYnI=; h=From:To:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=KzaUfZGjheWnbRS1ody/jaTiSgKZ1Nw4XV0tbzPihqA5EOAknNzjBeJd9l9FQ39eZ /nvv3+MQazZh5vXL7ynkPZraJxieURC/hpoNBpWOoxW0hcG5feWVipov2Zyn9pGIlm f/oGO804CPV+cwGz9XLDlmgtMmOFZGP70+ArgWLgl9U+bE/tz0E7Z1g5GEt719Nei3 bwitc30ztQiVr8DW+gxvPlctkGeFoOjvrnvW/cOkAffU9p0tqz57Jsg0J5+iCmyXp0 xOaj4SZmxV+ie6dV/i+Pjrtm91Q53ZqofNnz9LHQeSThR5gd8YjTyDsVNGdbPrqday OTyICUUH9KYKQ== Received: by mail-pj1-f71.google.com with SMTP id ng1-20020a17090b1a8100b001f4f9f69d48so858800pjb.4 for ; Wed, 17 Aug 2022 01:52:01 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc; bh=OSh6RBx2UPdYrPu+pLx83OWcHN+3ihEUeQxogZBZYnI=; b=B2Tr74lC8Y/+ApNuKICiiRSQSxI/8FQbBpZwoFZFFavhONqHyOTbzGVqJPv87X2QT5 dVNNwJbhYErg4MSJz36qzjIfq5+eggET11uU/Kebxo10JSJbDKJtZKuO0b7widOQ3gYO fkjvunOJMBoofdYsNcK3LisSwJfJUWTgkaDawhvW09aReDt2+KBPw4icTE4ysOmy766w 08ju9wbJSGf9JkI0jsIahk+9EJimmYQLFKgyJNkCFTBTGFgOS9PYPmQZS/ao1O/kHceo tM9m9evIaFLecqwrvWv0SbpJpyt8yyxGIxcPAQzU9G4qSA2LpRmSUoYcBaQ4wXQLWSfk 4PNQ== X-Gm-Message-State: ACgBeo3XjebY/kmfEpfbTEErsa/R5oySC+dxn7gbJ2m5xTGUM27pQBz1 ++XpIBLickoFU/KxsYhRZXEbUYka5GWdjKUg6SfT9NL27yigSEDyR6kNx/2e23C681ri/cRsmKp Ip5RT+d0T8nrQFSDAudpcDaiAnZjreDu9oI7tvZVgng== X-Received: by 2002:a65:4bc6:0:b0:428:90d4:b410 with SMTP id p6-20020a654bc6000000b0042890d4b410mr11956444pgr.529.1660726319935; Wed, 17 Aug 2022 01:51:59 -0700 (PDT) X-Google-Smtp-Source: AA6agR6elUEGuFaqDrP7BjZwe4MHuEEz8DOiFo2JcU8nCv0N+/zaLZRwa99F8HMQWrv1lLYOJQDvlQ== X-Received: by 2002:a65:4bc6:0:b0:428:90d4:b410 with SMTP id p6-20020a654bc6000000b0042890d4b410mr11956432pgr.529.1660726319497; Wed, 17 Aug 2022 01:51:59 -0700 (PDT) Received: from localhost.localdomain (220-135-31-21.hinet-ip.hinet.net. [220.135.31.21]) by smtp.gmail.com with ESMTPSA id s90-20020a17090a69e300b001f522180d46sm1001033pjj.8.2022.08.17.01.51.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 17 Aug 2022 01:51:59 -0700 (PDT) From: Gerald Yang To: kernel-team@lists.ubuntu.com Subject: [SRU][jammy/linux-aws][kinetic/linux-aws][PATCH 03/20] UBUNTU: SAUCE: xenbus: add freeze/thaw/restore callbacks support Date: Wed, 17 Aug 2022 16:51:30 +0800 Message-Id: <20220817085150.2078055-5-gerald.yang@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20220817085150.2078055-1-gerald.yang@canonical.com> References: <20220817085150.2078055-1-gerald.yang@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Munehisa Kamata BugLink: https://bugs.launchpad.net/bugs/1968062 Since commit b3e96c0c7562 ("xen: use freeze/restore/thaw PM events for suspend/resume/chkpt"), xenbus uses PMSG_FREEZE, PMSG_THAW and PMSG_RESTORE events for Xen suspend. However, they're actually assigned to xenbus_dev_suspend(), xenbus_dev_cancel() and xenbus_dev_resume() respectively, and only suspend and resume callbacks are supported at driver level. To support PM suspend and PM hibernation, modify the bus level PM callbacks to invoke not only device driver's suspend/resume but also freeze/thaw/restore. Note that we'll use freeze/restore callbacks even for PM suspend whereas suspend/resume callbacks are normally used in the case, becausae the existing xenbus device drivers already have suspend/resume callbacks specifically designed for Xen suspend. So we can allow the device drivers to keep the existing callbacks wihtout modification. Signed-off-by: Munehisa Kamata Signed-off-by: Anchal Agarwal Reviewed-by: Munehisa Kamata Reviewed-by: Eduardo Valentin CR: https://cr.amazon.com/r/8273200/ (cherry picked from commit 4f60b62df39c3a7f5cddf7b7a24f168af665d877 amazon-5.15.y/mainline) Signed-off-by: Gerald Yang Signed-off-by: Matthew Ruffell --- drivers/xen/xenbus/xenbus_probe.c | 99 ++++++++++++++++++++++++++----- include/xen/xenbus.h | 3 + 2 files changed, 86 insertions(+), 16 deletions(-) diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c index fe360c33ce71..5b0eba3b44fe 100644 --- a/drivers/xen/xenbus/xenbus_probe.c +++ b/drivers/xen/xenbus/xenbus_probe.c @@ -50,6 +50,7 @@ #include #include #include +#include #include #include @@ -663,26 +664,47 @@ int xenbus_dev_suspend(struct device *dev) struct xenbus_driver *drv; struct xenbus_device *xdev = container_of(dev, struct xenbus_device, dev); + int (*cb)(struct xenbus_device *) = NULL; + bool xen_suspend = xen_suspend_mode_is_xen_suspend(); DPRINTK("%s", xdev->nodename); if (dev->driver == NULL) return 0; drv = to_xenbus_driver(dev->driver); - if (drv->suspend) - err = drv->suspend(xdev); - if (err) - dev_warn(dev, "suspend failed: %i\n", err); + + if (xen_suspend) + cb = drv->suspend; + else + cb = drv->freeze; + + if (cb) + err = cb(xdev); + + if (err) { + dev_warn(dev, "%s failed: %i\n", xen_suspend ? + "suspend" : "freeze", err); + return err; + } + + if (!xen_suspend) { + /* Forget otherend since this can become stale after restore */ + free_otherend_watch(xdev); + free_otherend_details(xdev); + } + return 0; } EXPORT_SYMBOL_GPL(xenbus_dev_suspend); int xenbus_dev_resume(struct device *dev) { - int err; + int err = 0; struct xenbus_driver *drv; struct xenbus_device *xdev = container_of(dev, struct xenbus_device, dev); + int (*cb)(struct xenbus_device *) = NULL; + bool xen_suspend = xen_suspend_mode_is_xen_suspend(); DPRINTK("%s", xdev->nodename); @@ -691,23 +713,32 @@ int xenbus_dev_resume(struct device *dev) drv = to_xenbus_driver(dev->driver); err = talk_to_otherend(xdev); if (err) { - dev_warn(dev, "resume (talk_to_otherend) failed: %i\n", err); + dev_warn(dev, "%s (talk_to_otherend) failed: %i\n", + xen_suspend ? "resume" : "restore", err); return err; } - xdev->state = XenbusStateInitialising; + if (xen_suspend) + xdev->state = XenbusStateInitialising; - if (drv->resume) { - err = drv->resume(xdev); - if (err) { - dev_warn(dev, "resume failed: %i\n", err); - return err; - } + if (xen_suspend) + cb = drv->resume; + else + cb = drv->restore; + + if (cb) + err = cb(xdev); + + if (err) { + dev_warn(dev, "%s failed: %i\n", + xen_suspend ? "resume" : "restore", err); + return err; } err = watch_otherend(xdev); if (err) { - dev_warn(dev, "resume (watch_otherend) failed: %d\n", err); + dev_warn(dev, "%s (watch_otherend) failed: %d.\n", + xen_suspend ? "resume" : "restore", err); return err; } @@ -717,8 +748,44 @@ EXPORT_SYMBOL_GPL(xenbus_dev_resume); int xenbus_dev_cancel(struct device *dev) { - /* Do nothing */ - DPRINTK("cancel"); + int err = 0; + struct xenbus_driver *drv; + struct xenbus_device *xdev + = container_of(dev, struct xenbus_device, dev); + bool xen_suspend = xen_suspend_mode_is_xen_suspend(); + + if (xen_suspend) { + /* Do nothing */ + DPRINTK("cancel"); + return 0; + } + + DPRINTK("%s", xdev->nodename); + + if (dev->driver == NULL) + return 0; + drv = to_xenbus_driver(dev->driver); + + err = talk_to_otherend(xdev); + if (err) { + dev_warn(dev, "thaw (talk_to_otherend) failed: %d.\n", err); + return err; + } + + if (drv->thaw) { + err = drv->thaw(xdev); + if (err) { + dev_warn(dev, "thaw failed: %i\n", err); + return err; + } + } + + err = watch_otherend(xdev); + if (err) { + dev_warn(dev, "thaw (watch_otherend) failed: %d.\n", err); + return err; + } + return 0; } EXPORT_SYMBOL_GPL(xenbus_dev_cancel); diff --git a/include/xen/xenbus.h b/include/xen/xenbus.h index b94074c82772..99c8c7d167e5 100644 --- a/include/xen/xenbus.h +++ b/include/xen/xenbus.h @@ -119,6 +119,9 @@ struct xenbus_driver { int (*remove)(struct xenbus_device *dev); int (*suspend)(struct xenbus_device *dev); int (*resume)(struct xenbus_device *dev); + int (*freeze)(struct xenbus_device *dev); + int (*thaw)(struct xenbus_device *dev); + int (*restore)(struct xenbus_device *dev); int (*uevent)(struct xenbus_device *, struct kobj_uevent_env *); struct device_driver driver; int (*read_otherend_details)(struct xenbus_device *dev);