[haiku-bugs] Re: [Haiku] #15234: userland rw_lock races into a deadlock

  • From: "Haiku" <trac@xxxxxxxxxxxx>
  • To: undisclosed-recipients: ;
  • Date: Wed, 07 Aug 2019 14:31:50 -0000

#15234: userland rw_lock races into a deadlock
----------------------+----------------------------
   Reporter:  X512    |      Owner:  waddlesplash
       Type:  bug     |     Status:  assigned
   Priority:  normal  |  Milestone:  Unscheduled
  Component:  System  |    Version:  R1/Development
 Resolution:          |   Keywords:
 Blocked By:          |   Blocking:
Has a Patch:  0       |   Platform:  All
----------------------+----------------------------

Comment (by waddlesplash):

 So, the cause of the KDL in #15211 was indeed a race between the userland
 rw_lock's
 
[https://xref.plausible.coop/source/xref/haiku/src/system/libroot/os/locks/rw_lock.cpp#22
 wait()] calling _user_thread_block, and a separate thread calling
 _user_thread_unblock, and unblocking it on something else (in all recorded
 case in that ticket, the thread mutex) and then general mayhem ensuing.


 In [https://git.haiku-
 os.org/haiku/commit/?id=2c588b031fd618f8ec37376906fbfc68f4eeea0b
 hrev53345~1], I fixed the KDLs by only having _user_unblock_thread
 actually unblock threads when they were blocked by an equivalent
 _user_block_thread, and otherwise just set the
 {{{user_thread->wait_status}}}. Before touching that, it of course
 acquires the thread's lock; and similarly in
 
[https://xref.plausible.coop/source/xref/haiku/src/system/kernel/thread.cpp#3700
 _user_block_thread], it acquires the thread's mutex before checking
 wait_status, and it returns immediately if wait_status has already been
 set; and otherwise it blocks.

 As we only unlock the thread inside _user_block_thread after calling
 {{{thread_prepare_to_block}}}, this should (as I wrote in that commit)
 prevent the exact race seen here. But apparently it doesn't, and so there
 is somehow a way we are entering thread_block() (or, more particularly,
 thread_prepare_to_block()) with the wait_status already changed, and so we
 of course never get thread_unblocked.

 I've gone over the code multiple times and as far as I can see, all bases
 should be covered by locking the thread.

-- 
Ticket URL: <https://dev.haiku-os.org/ticket/15234#comment:3>
Haiku <https://dev.haiku-os.org>
The Haiku operating system.

Other related posts: