summaryrefslogtreecommitdiffstats
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2008-07-07 12:27:55 +0000
committerrwatson <rwatson@FreeBSD.org>2008-07-07 12:27:55 +0000
commit5e3d2e741eff224ce4216bc83b1f996fdea11089 (patch)
treeaf7bcfafa29718a258e98852bf6aaa00d6b6a6ac /sys/netinet/udp_usrreq.c
parentdaac7ea9396b9248e8fbfd8491769c31ec3ccf93 (diff)
downloadFreeBSD-src-5e3d2e741eff224ce4216bc83b1f996fdea11089.zip
FreeBSD-src-5e3d2e741eff224ce4216bc83b1f996fdea11089.tar.gz
Allow udp_notify() to accept read, as well as write, locks on the passed
inpcb. When directly invoking udp_notify() from udp_ctlinput(), acquire only a read lock; we may still see write locks in udp_notify() as the in_pcbnotifyall() routine is shared with TCP and always uses a write lock on the inpcb being notified. MFC after: 1 month
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r--sys/netinet/udp_usrreq.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 2098da9..312dcfc 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -567,7 +567,13 @@ struct inpcb *
udp_notify(struct inpcb *inp, int errno)
{
- INP_WLOCK_ASSERT(inp);
+ /*
+ * 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->inp_socket->so_error = errno;
sorwakeup(inp->inp_socket);
@@ -609,11 +615,11 @@ udp_ctlinput(int cmd, struct sockaddr *sa, void *vip)
inp = in_pcblookup_hash(&udbinfo, faddr, uh->uh_dport,
ip->ip_src, uh->uh_sport, 0, NULL);
if (inp != NULL) {
- INP_WLOCK(inp);
+ INP_RLOCK(inp);
if (inp->inp_socket != NULL) {
udp_notify(inp, inetctlerrmap[cmd]);
}
- INP_WUNLOCK(inp);
+ INP_RUNLOCK(inp);
}
INP_INFO_RUNLOCK(&udbinfo);
} else
OpenPOWER on IntegriCloud