All of lore.kernel.org
 help / color / mirror / Atom feed
From: Yifeng Li <tomli@tomli.me>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jiri Slaby <jslaby@suse.com>,
	Nicolas Pitre <nicolas.pitre@linaro.org>,
	Adam Borowski <kilobyte@angband.pl>,
	Mikulas Patocka <mpatocka@redhat.com>,
	Alexander Potapenko <glider@google.com>,
	Yifeng Li <tomli@tomli.me>, Mike Frysinger <vapier@chromium.org>,
	Daniel Vetter <daniel.vetter@ffwll.ch>
Subject: [RFC 0/1] Fix TIOCL_BLANKSCREEN VT console blanking if blankinterval == 0
Date: Tue, 26 Feb 2019 00:43:45 +0800	[thread overview]
Message-ID: <20190225164346.1359-1-tomli@tomli.me> (raw)

Previously, in the userspace, it was possible to use the "setterm" command
from util-linux to blank the VT console by default, using the following
command.

# setterm -blank force

According to the man page,

> The force option keeps the screen blank even if a key is pressed.

It was implemented by calling TIOCL_BLANKSCREEN.

	case BLANKSCREEN:
		ioctlarg = TIOCL_BLANKSCREEN;
		if (ioctl(STDIN_FILENO, TIOCLINUX, &ioctlarg))
			warn(_("cannot force blank"));
		break;

However, after Linux 4.12, this command ceased to work anymore, which is
unexpected. By inspecting the kernel source, it shows that the issue was
triggered by the side-effect from commit a4199f5e ("tty: Disable default
console blanking interval").

The console blanking is implemented by function do_blank_screen(). It can
be called by the inactive timer "console_timer" with the time specified by
"blankinterval", or by the IOCTL call TIOCL_BLANKSCREEN. The variable
"blank_state" is used to indicate the current status of console blanking,
it can have three possible values, blank_off, blank_normal_wait, or
blank_vesa_wait.

When do_blank_screen() is called by "console_timer" or TIOCL_BLANKSCREEN:

1. If blank_state == vesa_off_interval, it means the console was already
soft-blanked previously, and now it's the time to use VESA to put the CRT
into a deeper sleep mode. When we're done, blank_state is set to blank_off,
means the screen is now off, return.

2. If blank_state == blank_normal_wait, it means the console was previously on,
waiting to be blanked by the inactive timer. It will set blank_state to
"blank_off", means the screen is now off, and it then blanks the console. The
exception is that, it also checks if VESA powersaving is on, if so, blank_state
will be set to "blank_vesa_wait" instead, and the timer "console_timer" is
reinitialized to call do_blank_screen() again after "vesa_off_interval", for
VESA blanking, see Step 1.

3. If blank_state != blank_normal_wait at this point, it means the screen is
neither on, or VESA blanked - it must be blanked already, so return.

The problem is, "blank_state" will be initialized to "blank_normal_wait" in
con_init(), if AND ONLY IF ("blankinterval" > 0). If "blankinterval" is 0,
"blank_state" will be "blank_off" (== 0), and a call to do_blank_screen() will
always abort, per Step 3. Even if a forced blanking is required from the user
by calling TIOCL_BLANKSCREEN, the console won't be blanked.

In other words, the screen cannot be blanked if autoblanking is disabled,
unless we set a "blankinterval" beforehand, and the confusingly, the ioctl
will not even return an error code.

This behavior is unexpected from a user's point-of-view, since it's not
mentioned in any documentation. The setterm man page suggests it will always
work, and the kernel comments in uapi/linux/tiocl.h says

> #define TIOCL_BLANKSCREEN 14 /* keep screen blank even if a key is pressed */

The absence of an error is also misleading.

Personally, I consider it is either: (a) a bug of the implementation,
"blankinterval" shouldn't be a kill switch for manual console blanking, (b) or a
bug of inadequate documentation.

In the following patch, I suggest making a minor change to the console blanking
logic. We introduce a 4th "blank_state" - "blank_normal_notimer", it indicates
the console can be blanked, but not automatically by a timer. Then, we made a
change to "con_init()" - if (blankinterval == 0), "blank_state" will be set to
"blank_normal_notimer" (we have similar changes to "do_unblank_screen()" and
"poke_blanked_console()"). Finally, we change Step 3 in do_blank_screen() - now
it will return if "blank_state" is neither "blank_normal_wait" nor
"blank_normal_notimer", thus allowing the console to be blanked even if there's
no timed autoblanking.

Dear maintainers, please review if my proposed chance is appropriate.

Thanks,
Tom Li

Yifeng Li (1):
  tty: vt.c: Fix TIOCL_BLANKSCREEN VT console blanking if blankinterval
    == 0

 drivers/tty/vt/vt.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

-- 
2.20.1


             reply	other threads:[~2019-02-25 16:44 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-02-25 16:43 Yifeng Li [this message]
2019-02-25 16:43 ` [RFC 1/1] tty: vt.c: Fix TIOCL_BLANKSCREEN VT console blanking if blankinterval == 0 Yifeng Li
2019-02-25 18:29   ` Nicolas Pitre
2019-02-26 11:20     ` Tom Li

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=20190225164346.1359-1-tomli@tomli.me \
    --to=tomli@tomli.me \
    --cc=daniel.vetter@ffwll.ch \
    --cc=glider@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jslaby@suse.com \
    --cc=kilobyte@angband.pl \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mpatocka@redhat.com \
    --cc=nicolas.pitre@linaro.org \
    --cc=vapier@chromium.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.