Bug 103782

Summary: X server hangs at exit if it's in background
Product: xorg Reporter: Алексей Шилин <rootlexx>
Component: Server/GeneralAssignee: Xorg Project Team <xorg-team>
Status: RESOLVED FIXED QA Contact: Xorg Project Team <xorg-team>
Severity: normal    
Priority: medium CC: michalsrb
Version: git   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments:
Description Flags
Proposed patch fixing VT leave lockup
none
Proposed patch fixing VT leave lockup
none
os/inputthread: Force unlock when stopping thread. none

Description Алексей Шилин 2017-11-16 16:15:08 UTC
Created attachment 135523 [details] [review]
Proposed patch fixing VT leave lockup

Hi,

When X server is running in background, it freezes at exit i.e. after receiving SIGTERM.

Here is what gdb says:

# gdb --pid=536
GNU gdb (Debian 7.12-6) 7.12.0.20161007-git
...
Attaching to process 536
[New LWP 542]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f3851d5e6cd in pthread_join (threadid=139879650666240, 
    thread_return=thread_return@entry=0x0) at pthread_join.c:90
(gdb) info threads
  Id   Target Id         Frame 
* 1    Thread 0x7f385408ba40 (LWP 536) "Xorg" 0x00007f3851d5e6cd in pthread_join (
    threadid=139879650666240, thread_return=thread_return@entry=0x0) at pthread_join.c:90
  2    Thread 0x7f3844e3a700 (LWP 542) "InputThread" __lll_lock_wait ()
    at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
(gdb) bt
#0  0x00007f3851d5e6cd in pthread_join (threadid=139879650666240, 
    thread_return=thread_return@entry=0x0) at pthread_join.c:90
#1  0x000055d6880e63f0 in InputThreadFini () at ../../../../os/inputthread.c:500
#2  0x000055d687f816a6 in dix_main (argc=12, argv=0x7fff890930c8, envp=<optimized out>)
    at ../../../../dix/main.c:312
#3  0x00007f38519d82b1 in __libc_start_main (main=0x55d687f6b260 <main>, argc=12, 
    argv=0x7fff890930c8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, 
    stack_end=0x7fff890930b8) at ../csu/libc-start.c:291
#4  0x000055d687f6b29a in _start ()
(gdb) thread 2
[Switching to thread 2 (Thread 0x7f3844e3a700 (LWP 542))]
#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
(gdb) bt
#0  __lll_lock_wait () at ../sysdeps/unix/sysv/linux/x86_64/lowlevellock.S:135
#1  0x00007f3851d5fc06 in __GI___pthread_mutex_lock (
    mutex=mutex@entry=0x55d68837de60 <input_mutex>) at ../nptl/pthread_mutex_lock.c:115
#2  0x000055d6880e5c80 in input_lock () at ../../../../os/inputthread.c:113
#3  0x000055d6880e5df5 in InputThreadDoWork (arg=<optimized out>)
    at ../../../../os/inputthread.c:343
#4  0x00007f3851d5d494 in start_thread (arg=0x7f3844e3a700) at pthread_create.c:333
#5  0x00007f3851aa093f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:97
(gdb) 

So, the main thread is waiting for the input thread to quit while the latter is locked in pthread_mutex_lock().

After searching a bit, I found a suspicious function xf86VTLeave() in hw/xfree86/common/xf86Events.c, which locked the input mutex, but didn't unlock it at execution path when function xf86VTSwitchAway() returned true. Indeed, after adding input_unlock(), I can't reproduce the issue anymore.

Proposed patch is attached.
Comment 1 Michel Dänzer 2017-11-16 16:21:01 UTC
Please add your Signed-off-by to the commit log and send the patch to the xorg-devel mailing list for review.
Comment 2 Алексей Шилин 2017-11-16 23:43:47 UTC
Created attachment 135533 [details] [review]
Proposed patch fixing VT leave lockup
Comment 3 Michal Srb 2017-11-20 08:08:48 UTC
Created attachment 135599 [details] [review]
os/inputthread: Force unlock when stopping thread.

This is alternative fix that I sent few days ago to xorg-devel mailing list.

I think that the input mutex is kept locked for a reason (although I do not 
know the reason), because it is then again unlocked at the end of xf86VTEnter. 
If you unlock it in xf86VTLeave, you will get a double unlock in xf86VTEnter.
Comment 4 Adam Jackson 2018-01-24 21:45:50 UTC
commit 71348e99a8e6a95542e483b93839168ca8f51f81 (HEAD -> master, origin/master, origin/HEAD)
Author: Michal Srb <msrb@suse.com>
Date:   Mon Nov 27 09:59:01 2017 +0100

    os/inputthread: Force unlock when stopping thread.
    
    The inputthread is kept locked all the time while X server's VT is not active.
    If the X server is terminated while not active, it will be stuck forever in
    InputThreadFini waiting for the thread to join, but it wouldn't because it is
    locked.
    
    Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=103782
    Signed-off-by: Michal Srb <msrb@suse.com>
    Reviewed-by: Adam Jackson <ajax@redhat.com>

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.