[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#905033: xserver-xorg-input-elographics: locks up system on EOF from touchscreen



Package: xserver-xorg-input-elographics
Version: 1:1.4.1-1
Severity: normal
Tags: patch

When reading from the touchscreen device returns 0 (EOF), the driver
goes into an endless loop of poll and read. This locks up the Xorg
server, and when trying to kill it with -9, it hangs the whole
system (no idea how it manages to do that, but only an unfriendly
reboot seems to help):

  watchdog: BUG: soft lockup - CPU#7 stuck for 22s! [Xorg:3781]

Patch to handle EOF like error return:

--- src/xf86Elo.c
+++ src/xf86Elo.c
@@ -251,6 +251,10 @@
     ErrorF("System error while reading from Elographics touchscreen.");
     return !Success;
   }
+  if (num_bytes == 0) {
+    ErrorF("EOF while reading from Elographics touchscreen.");
+    return !Success;
+  }
   DBG(4, ErrorF("Read %d bytes\n", num_bytes));
 
   while (num_bytes) {

Well, I thought that would help, but it didn't. Seems I
misunderstood the comment above: "Okay, give up."

That's not what I understand by giving up, it still keeps retrying
and spamming the log with "EOF while reading from Elographics
touchscreen." -- at this point I also noticed the missing "\n" in
the error messages.

So without changing too much (the fd is passed by value, so I can't
easily change it; also I don't know when this function is called
from where etc.), for a quick and dirty solution I just reassign the
fd to something harmless. /dev/null doesn't work as it always
returns ready in poll and EOF in read too, so I create a pipe,
discard one end, so the other end will be not ready for reading.
This seems to work for me, but a permanent solution should probably
do something more elegant:

--- src/xf86Elo.c
+++ src/xf86Elo.c
@@ -58,6 +58,8 @@
 
 #include "xf86Module.h"
 
+#include <unistd.h>
+
 /**
  * models to be treated specially.
  */
@@ -248,7 +250,18 @@
    * Okay, give up.
    */
   if (num_bytes < 0) {
-    ErrorF("System error while reading from Elographics touchscreen.");
+    ErrorF("System error while reading from Elographics touchscreen.\n");
+    return !Success;
+  }
+  if (num_bytes == 0) {
+    /*
+     * Avoid reading from fd again, quick and dirty. Discard one end of a pipe,
+     * so the other end never gets EOF (unlike /dev/null) or reads anything.
+     */
+    int dummy[2];
+    pipe(dummy);
+    dup2(dummy[0], fd);
+    ErrorF("EOF while reading from Elographics touchscreen.\n");
     return !Success;
   }
   DBG(4, ErrorF("Read %d bytes\n", num_bytes));


Reply to: