diff mbox series

[RFC] fbcon: Reschedule cursor worker if try lock fails

Message ID 20230608094247.812488-1-chaitanya.kumar.borah@intel.com (mailing list archive)
State New, archived
Headers show
Series [RFC] fbcon: Reschedule cursor worker if try lock fails | expand

Commit Message

Chaitanya Kumar Borah June 8, 2023, 9:42 a.m. UTC
With the removal of timer implementation for cursor work[1],
the cursor delayed work does not get rescheduled if it fails
to acquire the console lock. This change pushes the cursor
work to the queue if we fail to acquire the lock.

This has been found to cause issue during the resume sequence
of the IGT test kms_fbcon_fbt@fbc-suspend[2]. The test expects
cursor blinking to start after the system resumes from suspend
state.

 fbcon_resumed()
	 redraw_screen()
		 set_cursor()
			 fb_flashcursor()

But the cursor work fails to acuire the lock and it never gets
rescheduled unless some other function comes in and invokes
fbcon_add_cursor_work() which adds the worker to the queue.
From empirical evidence this happens if we tweak the console
log level.

Re-scheduling the work heals the issue. I am not sure if this
is the best solution we can have, particularly with the "Fix me"
comment which indicates a bigger underlying problem. Hence, the
RFC.

[1] 3b0fb6ab25("fbcon: Use delayed work for cursor")
[2] https://intel-gfx-ci.01.org/tree/drm-tip/CI_DRM_13243/shard-glk2/igt@kms_fbcon_fbt@fbc-suspend.html

Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
---
 drivers/video/fbdev/core/fbcon.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c
index c6c9d040bdec..b98ea62836ae 100644
--- a/drivers/video/fbdev/core/fbcon.c
+++ b/drivers/video/fbdev/core/fbcon.c
@@ -357,8 +357,11 @@  static void fb_flashcursor(struct work_struct *work)
 	/* instead we just fail to flash the cursor if we can't get
 	 * the lock instead of blocking fbcon deinit */
 	ret = console_trylock();
-	if (ret == 0)
+	if (ret == 0) {
+		queue_delayed_work(system_power_efficient_wq, &ops->cursor_work,
+						   ops->cur_blink_jiffies);
 		return;
+	}
 
 	/* protected by console_lock */
 	info = ops->info;