Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Oct 2018 22:03:58 +0000 (UTC)
From:      Ryan Stone <rstone@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r339185 - head/sys/netinet
Message-ID:  <201810042203.w94M3wq1001668@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rstone
Date: Thu Oct  4 22:03:58 2018
New Revision: 339185
URL: https://svnweb.freebsd.org/changeset/base/339185

Log:
  Hold a write lock across udp_notify()
  
  With the new route cache feature udp_notify() will modify the inp when it
  needs to invalidate the route cache.  Ensure that we hold a write lock on
  the inp before calling the function to ensure that multiple threads don't
  race while trying to invalidate the cache (which previously lead to a page
  fault).
  
  Differential Revision: https://reviews.freebsd.org/D17246
  Reviewed by: sbruno, bz, karels
  Sponsored by: Dell EMC Isilon
  Approved by:	re (gjb)

Modified:
  head/sys/netinet/udp_usrreq.c

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c	Thu Oct  4 21:55:58 2018	(r339184)
+++ head/sys/netinet/udp_usrreq.c	Thu Oct  4 22:03:58 2018	(r339185)
@@ -756,13 +756,7 @@ struct inpcb *
 udp_notify(struct inpcb *inp, int errno)
 {
 
-	/*
-	 * While udp_ctlinput() always calls udp_notify() with a read lock
-	 * when invoking it directly, in_pcbnotifyall() currently uses write
-	 * locks due to sharing code with TCP.  For now, accept either a read
-	 * or a write lock, but a read lock is sufficient.
-	 */
-	INP_LOCK_ASSERT(inp);
+	INP_WLOCK_ASSERT(inp);
 	if ((errno == EHOSTUNREACH || errno == ENETUNREACH ||
 	     errno == EHOSTDOWN) && inp->inp_route.ro_rt) {
 		RTFREE(inp->inp_route.ro_rt);
@@ -808,13 +802,13 @@ udp_common_ctlinput(int cmd, struct sockaddr *sa, void
 	if (ip != NULL) {
 		uh = (struct udphdr *)((caddr_t)ip + (ip->ip_hl << 2));
 		inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
-		    ip->ip_src, uh->uh_sport, INPLOOKUP_RLOCKPCB, NULL);
+		    ip->ip_src, uh->uh_sport, INPLOOKUP_WLOCKPCB, NULL);
 		if (inp != NULL) {
-			INP_RLOCK_ASSERT(inp);
+			INP_WLOCK_ASSERT(inp);
 			if (inp->inp_socket != NULL) {
 				udp_notify(inp, inetctlerrmap[cmd]);
 			}
-			INP_RUNLOCK(inp);
+			INP_WUNLOCK(inp);
 		} else {
 			inp = in_pcblookup(pcbinfo, faddr, uh->uh_dport,
 					   ip->ip_src, uh->uh_sport,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201810042203.w94M3wq1001668>