HomeFreeBSD

Merge r241129:
rS241435Unpublished

Unpublished Commit ยท Learn More

No further details are available.

Description

Merge r241129:

There is a complex race in in_pcblookup_hash() and in_pcblookup_group().
Both functions need to obtain lock on the found PCB, and they can't do
classic inter-lock with the PCB hash lock, due to lock order reversal.
To keep the PCB stable, these functions put a reference on it and after PCB
lock is acquired drop it. If the reference was the last one, this means
we've raced with in_pcbfree() and the PCB is no longer valid.

  This approach works okay only if we are acquiring writer-lock on the PCB.
In case of reader-lock, the following scenario can happen:

  - 2 threads locate pcb, and do in_pcbref() on it.
  - These 2 threads drop the inp hash lock.
  - Another thread comes to delete pcb via in_pcbfree(), it obtains hash
    lock,   does in_pcbremlists(), drops hash lock, and runs
    in_pcbrele_wlocked(), which  doesn't free the pcb due to two references
    on it. Then it unlocks the pcb.
  - 2 aforementioned threads acquire reader lock on the pcb and run
    in_pcbrele_rlocked(). One gets 1 from in_pcbrele_rlocked() and continues,
    second gets 0 and considers pcb freed, returns.
  - The thread that got 1 continutes working with detached pcb, which later
    leads to panic in the underlying protocol level.

  To plumb that problem an additional INPCB flag introduced - INP_FREED. We
check for that flag in the in_pcbrele_rlocked() and if it is set, we pretend
that that was the last reference.

Discussed with:	rwatson, jhb
Reported by:		Vladimir Medvedkin <medved rambler-co.ru>

Details

Provenance
glebiusAuthored on
Parents
rS241434: Count number of times each queue pair's interrupt handler is invoked.
Branches
Unknown
Tags
Unknown

Event Timeline