kdb: Simplify code to fetch characters from console
authorDaniel Thompson <daniel.thompson@linaro.org>
Fri, 25 Oct 2019 07:33:25 +0000 (08:33 +0100)
committerDaniel Thompson <daniel.thompson@linaro.org>
Mon, 28 Oct 2019 12:02:21 +0000 (12:02 +0000)
Currently kdb_read_get_key() contains complex control flow that, on
close inspection, turns out to be unnecessary. In particular:

1. It is impossible to enter the branch conditioned on (escape_delay == 1)
   except when the loop enters with (escape_delay == 2) allowing us to
   combine the branches.

2. Most of the code conditioned on (escape_delay == 2) simply modifies
   local data and then breaks out of the loop causing the function to
   return escape_data[0].

3. Based on #2 there is not actually any need to ever explicitly set
   escape_delay to 2 because we it is much simpler to directly return
   escape_data[0] instead.

4. escape_data[0] is, for all but one exit path, known to be '\e'.

Simplify the code based on these observations.

There is a subtle (and harmless) change of behaviour resulting from this
simplification: instead of letting the escape timeout after ~1998
milliseconds we now timeout after ~2000 milliseconds

Signed-off-by: Daniel Thompson <daniel.thompson@linaro.org>
Reviewed-by: Douglas Anderson <dianders@chromium.org>
Link: https://lore.kernel.org/r/20191025073328.643-3-daniel.thompson@linaro.org
kernel/debug/kdb/kdb_io.c

index cfc054f..a92ceca 100644 (file)
@@ -124,25 +124,18 @@ static int kdb_read_get_key(char *buffer, size_t bufsize)
                        touch_nmi_watchdog();
                        f = &kdb_poll_funcs[0];
                }
-               if (escape_delay == 2) {
-                       *ped = '\0';
-                       ped = escape_data;
-                       --escape_delay;
-               }
-               if (escape_delay == 1) {
-                       key = *ped++;
-                       if (!*ped)
-                               --escape_delay;
-                       break;
-               }
+
                key = (*f)();
+
                if (key == -1) {
                        if (escape_delay) {
                                udelay(ESCAPE_UDELAY);
-                               --escape_delay;
+                               if (--escape_delay == 0)
+                                       return '\e';
                        }
                        continue;
                }
+
                if (bufsize <= 2) {
                        if (key == '\r')
                                key = '\n';
@@ -150,27 +143,24 @@ static int kdb_read_get_key(char *buffer, size_t bufsize)
                        *buffer = '\0';
                        return -1;
                }
+
                if (escape_delay == 0 && key == '\e') {
                        escape_delay = ESCAPE_DELAY;
                        ped = escape_data;
                        f_escape = f;
                }
                if (escape_delay) {
-                       *ped++ = key;
-                       if (f_escape != f) {
-                               escape_delay = 2;
-                               continue;
-                       }
+                       if (f_escape != f)
+                               return '\e';
 
+                       *ped++ = key;
                        key = kdb_handle_escape(escape_data, ped - escape_data);
-                       if (key > 0) {
-                               escape_data[0] = key;
-                               escape_data[1] = '\0';
-                       }
-                       if (key)
-                               escape_delay = 2;
-                       continue;
+                       if (key < 0)
+                               return '\e';
+                       if (key == 0)
+                               continue;
                }
+
                break;  /* A key to process */
        }
        return key;