All of lore.kernel.org
 help / color / mirror / Atom feed
From: Oleksandr Andrushchenko <andr2000@gmail.com>
To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org,
	dri-devel@lists.freedesktop.org, airlied@linux.ie,
	daniel.vetter@intel.com, seanpaul@chromium.org,
	gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com,
	konrad.wilk@oracle.com
Cc: andr2000@gmail.com,
	Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Subject: [PATCH v2 2/8] drm/xen-front: Implement Xen bus state handling
Date: Tue, 13 Mar 2018 15:31:01 +0200	[thread overview]
Message-ID: <1520947867-32514-3-git-send-email-andr2000@gmail.com> (raw)
In-Reply-To: <1520947867-32514-1-git-send-email-andr2000@gmail.com>

From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

Initial handling for Xen bus states: implement
Xen bus state machine for the frontend driver according to
the state diagram and recovery flow from display para-virtualized
protocol: xen/interface/io/displif.h.

Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
---
 drivers/gpu/drm/xen/xen_drm_front.c | 124 +++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/xen/xen_drm_front.h |  18 ++++++
 2 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/xen/xen_drm_front.h

diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
index 03bc50b128fd..520b5b34520b 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -16,19 +16,141 @@
 
 #include <xen/interface/io/displif.h>
 
+#include "xen_drm_front.h"
+
+static void xen_drv_remove_internal(struct xen_drm_front_info *front_info)
+{
+}
+
+static int displback_initwait(struct xen_drm_front_info *front_info)
+{
+	return 0;
+}
+
+static int displback_connect(struct xen_drm_front_info *front_info)
+{
+	return 0;
+}
+
+static void displback_disconnect(struct xen_drm_front_info *front_info)
+{
+	xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising);
+}
+
 static void displback_changed(struct xenbus_device *xb_dev,
 		enum xenbus_state backend_state)
 {
+	struct xen_drm_front_info *front_info = dev_get_drvdata(&xb_dev->dev);
+	int ret;
+
+	DRM_DEBUG("Backend state is %s, front is %s\n",
+			xenbus_strstate(backend_state),
+			xenbus_strstate(xb_dev->state));
+
+	switch (backend_state) {
+	case XenbusStateReconfiguring:
+		/* fall through */
+	case XenbusStateReconfigured:
+		/* fall through */
+	case XenbusStateInitialised:
+		break;
+
+	case XenbusStateInitialising:
+		/* recovering after backend unexpected closure */
+		displback_disconnect(front_info);
+		break;
+
+	case XenbusStateInitWait:
+		/* recovering after backend unexpected closure */
+		displback_disconnect(front_info);
+		if (xb_dev->state != XenbusStateInitialising)
+			break;
+
+		ret = displback_initwait(front_info);
+		if (ret < 0)
+			xenbus_dev_fatal(xb_dev, ret,
+					"initializing frontend");
+		else
+			xenbus_switch_state(xb_dev, XenbusStateInitialised);
+		break;
+
+	case XenbusStateConnected:
+		if (xb_dev->state != XenbusStateInitialised)
+			break;
+
+		ret = displback_connect(front_info);
+		if (ret < 0)
+			xenbus_dev_fatal(xb_dev, ret,
+					"initializing DRM driver");
+		else
+			xenbus_switch_state(xb_dev, XenbusStateConnected);
+		break;
+
+	case XenbusStateClosing:
+		/*
+		 * in this state backend starts freeing resources,
+		 * so let it go into closed state, so we can also
+		 * remove ours
+		 */
+		break;
+
+	case XenbusStateUnknown:
+		/* fall through */
+	case XenbusStateClosed:
+		if (xb_dev->state == XenbusStateClosed)
+			break;
+
+		displback_disconnect(front_info);
+		break;
+	}
 }
 
 static int xen_drv_probe(struct xenbus_device *xb_dev,
 		const struct xenbus_device_id *id)
 {
-	return 0;
+	struct xen_drm_front_info *front_info;
+
+	front_info = devm_kzalloc(&xb_dev->dev,
+			sizeof(*front_info), GFP_KERNEL);
+	if (!front_info)
+		return -ENOMEM;
+
+	front_info->xb_dev = xb_dev;
+	dev_set_drvdata(&xb_dev->dev, front_info);
+	return xenbus_switch_state(xb_dev, XenbusStateInitialising);
 }
 
 static int xen_drv_remove(struct xenbus_device *dev)
 {
+	struct xen_drm_front_info *front_info = dev_get_drvdata(&dev->dev);
+	int to = 100;
+
+	xenbus_switch_state(dev, XenbusStateClosing);
+
+	/*
+	 * On driver removal it is disconnected from XenBus,
+	 * so no backend state change events come via .otherend_changed
+	 * callback. This prevents us from exiting gracefully, e.g.
+	 * signaling the backend to free event channels, waiting for its
+	 * state to change to XenbusStateClosed and cleaning at our end.
+	 * Normally when front driver removed backend will finally go into
+	 * XenbusStateInitWait state.
+	 *
+	 * Workaround: read backend's state manually and wait with time-out.
+	 */
+	while ((xenbus_read_unsigned(front_info->xb_dev->otherend,
+			"state", XenbusStateUnknown) != XenbusStateInitWait) &&
+			to--)
+		msleep(10);
+
+	if (!to)
+		DRM_ERROR("Backend state is %s while removing driver\n",
+			xenbus_strstate(xenbus_read_unsigned(
+					front_info->xb_dev->otherend,
+					"state", XenbusStateUnknown)));
+
+	xen_drv_remove_internal(front_info);
+	xenbus_frontend_closed(dev);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/xen/xen_drm_front.h b/drivers/gpu/drm/xen/xen_drm_front.h
new file mode 100644
index 000000000000..8b8d4d1e0816
--- /dev/null
+++ b/drivers/gpu/drm/xen/xen_drm_front.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+/*
+ *  Xen para-virtual DRM device
+ *
+ * Copyright (C) 2016-2018 EPAM Systems Inc.
+ *
+ * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
+ */
+
+#ifndef __XEN_DRM_FRONT_H_
+#define __XEN_DRM_FRONT_H_
+
+struct xen_drm_front_info {
+	struct xenbus_device *xb_dev;
+};
+
+#endif /* __XEN_DRM_FRONT_H_ */
-- 
2.7.4

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

WARNING: multiple messages have this Message-ID (diff)
From: Oleksandr Andrushchenko <andr2000@gmail.com>
To: xen-devel@lists.xenproject.org, linux-kernel@vger.kernel.org,
	dri-devel@lists.freedesktop.org, airlied@linux.ie,
	daniel.vetter@intel.com, seanpaul@chromium.org,
	gustavo@padovan.org, jgross@suse.com, boris.ostrovsky@oracle.com,
	konrad.wilk@oracle.com
Cc: andr2000@gmail.com,
	Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
Subject: [PATCH v2 2/8] drm/xen-front: Implement Xen bus state handling
Date: Tue, 13 Mar 2018 15:31:01 +0200	[thread overview]
Message-ID: <1520947867-32514-3-git-send-email-andr2000@gmail.com> (raw)
In-Reply-To: <1520947867-32514-1-git-send-email-andr2000@gmail.com>

From: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>

Initial handling for Xen bus states: implement
Xen bus state machine for the frontend driver according to
the state diagram and recovery flow from display para-virtualized
protocol: xen/interface/io/displif.h.

Signed-off-by: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
---
 drivers/gpu/drm/xen/xen_drm_front.c | 124 +++++++++++++++++++++++++++++++++++-
 drivers/gpu/drm/xen/xen_drm_front.h |  18 ++++++
 2 files changed, 141 insertions(+), 1 deletion(-)
 create mode 100644 drivers/gpu/drm/xen/xen_drm_front.h

diff --git a/drivers/gpu/drm/xen/xen_drm_front.c b/drivers/gpu/drm/xen/xen_drm_front.c
index 03bc50b128fd..520b5b34520b 100644
--- a/drivers/gpu/drm/xen/xen_drm_front.c
+++ b/drivers/gpu/drm/xen/xen_drm_front.c
@@ -16,19 +16,141 @@
 
 #include <xen/interface/io/displif.h>
 
+#include "xen_drm_front.h"
+
+static void xen_drv_remove_internal(struct xen_drm_front_info *front_info)
+{
+}
+
+static int displback_initwait(struct xen_drm_front_info *front_info)
+{
+	return 0;
+}
+
+static int displback_connect(struct xen_drm_front_info *front_info)
+{
+	return 0;
+}
+
+static void displback_disconnect(struct xen_drm_front_info *front_info)
+{
+	xenbus_switch_state(front_info->xb_dev, XenbusStateInitialising);
+}
+
 static void displback_changed(struct xenbus_device *xb_dev,
 		enum xenbus_state backend_state)
 {
+	struct xen_drm_front_info *front_info = dev_get_drvdata(&xb_dev->dev);
+	int ret;
+
+	DRM_DEBUG("Backend state is %s, front is %s\n",
+			xenbus_strstate(backend_state),
+			xenbus_strstate(xb_dev->state));
+
+	switch (backend_state) {
+	case XenbusStateReconfiguring:
+		/* fall through */
+	case XenbusStateReconfigured:
+		/* fall through */
+	case XenbusStateInitialised:
+		break;
+
+	case XenbusStateInitialising:
+		/* recovering after backend unexpected closure */
+		displback_disconnect(front_info);
+		break;
+
+	case XenbusStateInitWait:
+		/* recovering after backend unexpected closure */
+		displback_disconnect(front_info);
+		if (xb_dev->state != XenbusStateInitialising)
+			break;
+
+		ret = displback_initwait(front_info);
+		if (ret < 0)
+			xenbus_dev_fatal(xb_dev, ret,
+					"initializing frontend");
+		else
+			xenbus_switch_state(xb_dev, XenbusStateInitialised);
+		break;
+
+	case XenbusStateConnected:
+		if (xb_dev->state != XenbusStateInitialised)
+			break;
+
+		ret = displback_connect(front_info);
+		if (ret < 0)
+			xenbus_dev_fatal(xb_dev, ret,
+					"initializing DRM driver");
+		else
+			xenbus_switch_state(xb_dev, XenbusStateConnected);
+		break;
+
+	case XenbusStateClosing:
+		/*
+		 * in this state backend starts freeing resources,
+		 * so let it go into closed state, so we can also
+		 * remove ours
+		 */
+		break;
+
+	case XenbusStateUnknown:
+		/* fall through */
+	case XenbusStateClosed:
+		if (xb_dev->state == XenbusStateClosed)
+			break;
+
+		displback_disconnect(front_info);
+		break;
+	}
 }
 
 static int xen_drv_probe(struct xenbus_device *xb_dev,
 		const struct xenbus_device_id *id)
 {
-	return 0;
+	struct xen_drm_front_info *front_info;
+
+	front_info = devm_kzalloc(&xb_dev->dev,
+			sizeof(*front_info), GFP_KERNEL);
+	if (!front_info)
+		return -ENOMEM;
+
+	front_info->xb_dev = xb_dev;
+	dev_set_drvdata(&xb_dev->dev, front_info);
+	return xenbus_switch_state(xb_dev, XenbusStateInitialising);
 }
 
 static int xen_drv_remove(struct xenbus_device *dev)
 {
+	struct xen_drm_front_info *front_info = dev_get_drvdata(&dev->dev);
+	int to = 100;
+
+	xenbus_switch_state(dev, XenbusStateClosing);
+
+	/*
+	 * On driver removal it is disconnected from XenBus,
+	 * so no backend state change events come via .otherend_changed
+	 * callback. This prevents us from exiting gracefully, e.g.
+	 * signaling the backend to free event channels, waiting for its
+	 * state to change to XenbusStateClosed and cleaning at our end.
+	 * Normally when front driver removed backend will finally go into
+	 * XenbusStateInitWait state.
+	 *
+	 * Workaround: read backend's state manually and wait with time-out.
+	 */
+	while ((xenbus_read_unsigned(front_info->xb_dev->otherend,
+			"state", XenbusStateUnknown) != XenbusStateInitWait) &&
+			to--)
+		msleep(10);
+
+	if (!to)
+		DRM_ERROR("Backend state is %s while removing driver\n",
+			xenbus_strstate(xenbus_read_unsigned(
+					front_info->xb_dev->otherend,
+					"state", XenbusStateUnknown)));
+
+	xen_drv_remove_internal(front_info);
+	xenbus_frontend_closed(dev);
 	return 0;
 }
 
diff --git a/drivers/gpu/drm/xen/xen_drm_front.h b/drivers/gpu/drm/xen/xen_drm_front.h
new file mode 100644
index 000000000000..8b8d4d1e0816
--- /dev/null
+++ b/drivers/gpu/drm/xen/xen_drm_front.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 OR MIT */
+
+/*
+ *  Xen para-virtual DRM device
+ *
+ * Copyright (C) 2016-2018 EPAM Systems Inc.
+ *
+ * Author: Oleksandr Andrushchenko <oleksandr_andrushchenko@epam.com>
+ */
+
+#ifndef __XEN_DRM_FRONT_H_
+#define __XEN_DRM_FRONT_H_
+
+struct xen_drm_front_info {
+	struct xenbus_device *xb_dev;
+};
+
+#endif /* __XEN_DRM_FRONT_H_ */
-- 
2.7.4

  parent reply	other threads:[~2018-03-13 13:31 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-13 13:30 [PATCH v2 0/8] drm/xen-front: Add support for Xen PV display frontend Oleksandr Andrushchenko
2018-03-13 13:30 ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 1/8] drm/xen-front: Introduce Xen para-virtualized frontend driver Oleksandr Andrushchenko
2018-03-13 13:31   ` Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 2/8] drm/xen-front: Implement Xen bus state handling Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko [this message]
2018-03-13 13:31   ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 3/8] drm/xen-front: Read driver configuration from Xen store Oleksandr Andrushchenko
2018-03-13 13:31   ` Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 4/8] drm/xen-front: Implement Xen event channel handling Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko
2018-03-13 13:31   ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 5/8] drm/xen-front: Implement handling of shared display buffers Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko
2018-03-13 13:31   ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 6/8] drm/xen-front: Introduce DRM/KMS virtual display driver Oleksandr Andrushchenko
2018-03-13 13:31   ` Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 7/8] drm/xen-front: Implement GEM operations and backend communication Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko
2018-03-13 13:31 ` [PATCH v2 8/8] drm/xen-front: Provide kernel documentation Oleksandr Andrushchenko
2018-03-13 13:31 ` Oleksandr Andrushchenko

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1520947867-32514-3-git-send-email-andr2000@gmail.com \
    --to=andr2000@gmail.com \
    --cc=airlied@linux.ie \
    --cc=boris.ostrovsky@oracle.com \
    --cc=daniel.vetter@intel.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gustavo@padovan.org \
    --cc=jgross@suse.com \
    --cc=konrad.wilk@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleksandr_andrushchenko@epam.com \
    --cc=seanpaul@chromium.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.