Commit 0f7dc324 authored by Takashi Iwai's avatar Takashi Iwai Committed by Thomas Zimmermann
Browse files

drm/udl: Sync pending URBs at suspend / disconnect



We need to wait for finishing to process the all URBs after disabling
the pipe; otherwise pending URBs may stray at suspend/resume, leading
to a possible memory corruption in a worst case.

Tested-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: default avatarThomas Zimmermann <tzimmermann@suse.de>
Link: https://patchwork.freedesktop.org/patch/msgid/20220804075826.27036-3-tiwai@suse.de
parent acd45c56
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ static inline struct urb *udl_get_urb(struct drm_device *dev)
}

int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len);
int udl_sync_pending_urbs(struct drm_device *dev);
void udl_urb_completion(struct urb *urb);

int udl_init(struct udl_device *udl);
+17 −0
Original line number Diff line number Diff line
@@ -270,6 +270,23 @@ int udl_submit_urb(struct drm_device *dev, struct urb *urb, size_t len)
	return ret;
}

/* wait until all pending URBs have been processed */
int udl_sync_pending_urbs(struct drm_device *dev)
{
	struct udl_device *udl = to_udl(dev);
	int ret = 0;

	spin_lock_irq(&udl->urbs.lock);
	/* 2 seconds as a sane timeout */
	if (!wait_event_lock_irq_timeout(udl->urbs.sleep,
					 udl->urbs.available == udl->urbs.count,
					 udl->urbs.lock,
					 msecs_to_jiffies(2000)))
		ret = -ETIMEDOUT;
	spin_unlock_irq(&udl->urbs.lock);
	return ret;
}

int udl_init(struct udl_device *udl)
{
	struct drm_device *dev = &udl->drm;
+2 −0
Original line number Diff line number Diff line
@@ -408,6 +408,8 @@ udl_simple_display_pipe_disable(struct drm_simple_display_pipe *pipe)
	buf = udl_dummy_render(buf);

	udl_submit_urb(dev, urb, buf - (char *)urb->transfer_buffer);

	udl_sync_pending_urbs(dev);
}

static void