summaryrefslogtreecommitdiff
path: root/sys/netinet/tcp_timer.c
diff options
context:
space:
mode:
authorRandall Stewart <rrs@FreeBSD.org>2016-08-16 13:08:03 +0000
committerRandall Stewart <rrs@FreeBSD.org>2016-08-16 13:08:03 +0000
commit0fa047b98c07b0e555ac3b0c2898de82abb44a0a (patch)
treed2337beca238a1caad2d4f54ee7d1a9a424f8409 /sys/netinet/tcp_timer.c
parentb07fef500b4d2829cb310d101455b3b7a4def353 (diff)
Notes
Diffstat (limited to 'sys/netinet/tcp_timer.c')
-rw-r--r--sys/netinet/tcp_timer.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index 183271cfd1ac..1be20ce8643f 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -301,6 +301,25 @@ tcp_timer_delack(void *xtp)
CURVNET_RESTORE();
}
+/*
+ * When a timer wants to remove a TCB it must
+ * hold the INP_INFO_RLOCK(). The timer function
+ * should only have grabbed the INP_WLOCK() when
+ * it entered. To safely switch to holding both the
+ * INP_INFO_RLOCK() and the INP_WLOCK() we must first
+ * grab a reference on the inp, this will hold the inp
+ * so that it can't be removed. We then unlock and grab
+ * the info-read lock. Once we have the INP_INFO_RLOCK() we
+ * proceed again to get the INP_WLOCK() but after that
+ * we must check if someone else deleted the pcb i.e.
+ * the inp_flags check. If so we return 1 otherwise
+ * we return 0.
+ *
+ * No matter which the tcp_inpinfo_lock_add() function
+ * returns the caller must afterwards call tcp_inpinfo_lock_del()
+ * to drop the locks and reference properly.
+ */
+
int
tcp_inpinfo_lock_add(struct inpcb *inp)
{