will restore it back ;)
S-o-b line went missing here :-)
will review and try to rework after the driver is in
I've read through it, 2 actual review comments (around hot-unplug and
around the error recovery for failed flips), a few bikesheds, but looks
all reasonable to me. And much easier to read as one big patch (it's just
3k).
One more thing I'd do as a follow-up (don't rewrite everything, this is
close to merge, better to get it in first): You have a lot of indirections
and function calls across sources files. That's kinda ok if you have a
huge driver with 100+k lines of code where you have to split things up.
But for a small driver like yours here it's a bit overkill.
I prefer to have it in smaller chunks and all related code at
Personally I'd merge at least the xen backend stuff into the corresponding
kms code, but that's up to you.
And as mentioned, if you decide to doOk, after the merge
that, a follow-up patch (once this has merged) is perfectly fine.
-DanielI had that the way you say in some of the previous implementations,
+int xen_drm_front_dbuf_create_from_sgt(struct xen_drm_front_info *front_info,The above two wrappers seem a bit much, just to set sgt = NULL or pages =
+ uint64_t dbuf_cookie, uint32_t width, uint32_t height,
+ uint32_t bpp, uint64_t size, struct sg_table *sgt)
+{
+ return be_dbuf_create_int(front_info, dbuf_cookie, width, height,
+ bpp, size, NULL, sgt);
+}
+
+int xen_drm_front_dbuf_create_from_pages(struct xen_drm_front_info *front_info,
+ uint64_t dbuf_cookie, uint32_t width, uint32_t height,
+ uint32_t bpp, uint64_t size, struct page **pages)
+{
+ return be_dbuf_create_int(front_info, dbuf_cookie, width, height,
+ bpp, size, pages, NULL);
+}
NULL in one of them. I'd drop them, but that's a bikeshed so feel free to
ignore.
Will rework it with drm_dev_unplug, thank you+static void displback_disconnect(struct xen_drm_front_info *front_info)Ok this logic here is fishy, since you're open-coding the drm unplug
+{
+ bool removed = true;
+
+ if (front_info->drm_pdev) {
+ if (xen_drm_front_drv_is_used(front_info->drm_pdev)) {
+ DRM_WARN("DRM driver still in use, deferring removal\n");
+ removed = false;
+ } else
+ xen_drv_remove_internal(front_info);
infrastructure, but slightly differently and slightyl racy. If you have a
driver where your underlying "hw" (well it's virtual here, but same idea)
can disappear any time while userspace is still using the drm driver, you
need to use the drm_dev_unplug() function and related code.
drm_dev_unplug() works like drm_dev_unregister, except for the hotplug
case.
Then you also have to guard all the driver entry points where you do
access the backchannel using drm_dev_is_unplugged() (I've seen a few of
those already). Then you can rip out all the logic here and the xen_drm_front_drv_is_used() helper.
I thought there's some patches from Noralf in-flight that improved theok, will remove #define
docs on this, I need to check
+#define XEN_DRM_NUM_VIDEO_MODES 1Bikeshed: just hardcode this to 1, the #define is imo more confusing.
+#define XEN_DRM_CRTC_VREFRESH_HZ 60
+
+static int connector_get_modes(struct drm_connector *connector)
+{
+ struct xen_drm_front_drm_pipeline *pipeline =
+ to_xen_drm_pipeline(connector);
+ struct drm_display_mode *mode;
+ struct videomode videomode;
+ int width, height;
+
+ mode = drm_mode_create(connector->dev);
+ if (!mode)
+ return 0;
+
+ memset(&videomode, 0, sizeof(videomode));
+ videomode.hactive = pipeline->width;
+ videomode.vactive = pipeline->height;
+ width = videomode.hactive + videomode.hfront_porch +
+ videomode.hback_porch + videomode.hsync_len;
+ height = videomode.vactive + videomode.vfront_porch +
+ videomode.vback_porch + videomode.vsync_len;
+ videomode.pixelclock = width * height * XEN_DRM_CRTC_VREFRESH_HZ;
+ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER;
+
+ drm_display_mode_from_videomode(&videomode, mode);
+ drm_mode_probed_add(connector, mode);
+ return XEN_DRM_NUM_VIDEO_MODES;
The reason for having bool for page flip here is that we
+The control flow here is a bit confusing. I'd put the call to send out the
+ }
+ /*
+ * Send page flip request to the backend *after* we have event cached
+ * above, so on page flip done event from the backend we can
+ * deliver it and there is no race condition between this code and
+ * event from the backend.
+ * If this is not a page flip, e.g. no flip done event from the backend
+ * is expected, then send now.
+ */
+ if (!display_send_page_flip(pipe, old_plane_state))
+ xen_drm_front_kms_send_pending_event(pipeline);
event right away in case of a failure to communicate with the backend into
display_send_page_flip() itself. Then drop the bool return value and make
it void, and also push the comment explaining what you do in case of
errors into that function.
Well, I tried to keep it all at one place, but as we decided
That way the error handling and recovery is all neatly tied together in
one place instead of spread around.
Thank you very much for review and comments,