HomeFreeBSD

Add if_try_ref() to simplify refcount handling inside epoch.

Description

Add if_try_ref() to simplify refcount handling inside epoch.

When we have an ifp pointer and the code is running inside epoch,
epoch guarantees the pointer will not be freed.
However, the following case can still happen:

  • in thread 1 we drop to refcount=0 for ifp and schedule its deletion.
  • in thread 2 we use this ifp and reference it
  • destroy callout kicks in
  • unhappy user reports a bug

This can happen with the current implementation of ifnet_byindex_ref(),
as we're not holding any locks preventing ifnet deletion by a parallel thread.

To address it, add if_try_ref(), allowing to return failure when
referencing ifp with refcount=0.
Additionally, enforce existing if_ref() is with KASSERT to provide a
cleaner error in such scenarios.

Finally, fix ifnet_byindex_ref() by using if_try_ref() and returning NULL
if the latter fails.

MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D28836

(cherry picked from commit 7563019bc69301a382abefbac3b0fea1d876410e)

Details

Provenance
melifaroAuthored on Feb 22 2021, 9:37 PM
Differential Revision
D28836: Add if_try_ref() to simplify refcount handling inside epoch
Parents
rG6053349c46a2: sctp: Fix racy UNBOUND flag check in sctp_inpcb_bind()
Branches
Unknown
Tags
Unknown