saimayithri commented on issue #13358:
URL: 
https://github.com/apache/trafficserver/issues/13358#issuecomment-4976518797

   Thanks again for continuing to test this in production. I spent some more 
time tracing the current source to understand the locking model before making 
any further changes to the patch.
   
   Here's what I've been able to establish from the current source:
   
   * `netvc->thread` and `nh->thread` appear to be assigned together during 
NetHandler/NetVConnection initialization, and I couldn't find any later 
reassignment that would cause them to diverge.
   * `Http1ClientSession`, `Http2ClientSession`, and `Http2ConnectionState` are 
all initialized with a `nullptr` continuation mutex, and during 
`new_connection()` they are assigned `new_vc->mutex`. In other words, these 
continuations execute under `vc->mutex`, not `nh->mutex`.
   * `EThread::process_event()` acquires only the continuation mutex before 
invoking `handleEvent()`. It does not automatically acquire `nh->mutex`.
   * `NetHandler::waitForActivity()` acquires `nh->mutex` while processing the 
network poll and ready list, and from tracing `EThread::execute_regular()`, 
queued events (`process_event()`) and `waitForActivity()` execute in separate 
phases of the event loop.
   
   From that, my current understanding is that queue operations like 
`add_to_active_queue()` are not expected to inherit `nh->mutex` from the 
continuation. Instead, they appear to rely on `MUTEX_TRY_LOCK(nh->mutex)` 
acquiring it on the owner thread.
   
   However, your latest production crash exposed a contradiction that I haven't 
been able to explain from the source alone.
   
   The owner-thread check appears to have already passed:
   
   ```cpp
   if (this->thread != this_ethread()) {
       ...
   }
   ```
   
   yet immediately afterwards:
   
   ```cpp
   MUTEX_TRY_LOCK(lock, nh->mutex, this_ethread());
   ```
   
   failed.
   
   If my understanding of the execution model is correct, I would have expected 
that try-lock to succeed when executing on the owner thread. Since your 
production result contradicts that expectation, I don't think I can honestly 
claim that scheduling `HTTP2_SESSION_EVENT_REENABLE` onto `netvc->thread` is 
sufficient without understanding what is actually holding `nh->mutex` at that 
point.
   
   Would you be willing to run one build with a little diagnostic 
instrumentation immediately before the assertion? I think that would tell us 
exactly which invariant is being violated.
   
   For example:
   
   ```cpp
   Warning("add_to_active_queue try-lock failed:"
           " vc=%p"
           " current=%p"
           " vc->thread=%p"
           " nh->thread=%p"
           " holder=%p"
           " vc->mutex=%p"
           " nh->mutex=%p",
           this,
           this_ethread(),
           this->thread,
           nh->thread,
           nh->mutex->thread_holding,
           this->mutex,
           nh->mutex);
   ```
   
   If possible, it would also be useful to log the current event (or otherwise 
confirm whether this is still occurring on the `HTTP2_SESSION_EVENT_REENABLE` 
path).
   
   I think this should let us distinguish between a few possibilities:
   
   * the execution isn't actually occurring on the expected owner thread,
   * another execution context still owns `nh->mutex`,
   * or there's another path reaching `add_to_active_queue()` that I haven't 
identified yet.
   
   Once we know who actually owns `nh->mutex` at the point of failure, it 
should be much easier to determine whether the scheduling change is 
insufficient by itself or whether there's another concurrency path that still 
needs to be addressed.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to