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));