diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-08-21 09:39:55 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2018-09-21 10:29:40 +0200 |
commit | 2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783 (patch) | |
tree | bd7bad558534db4a1f400bc38a2c9aa7ea4f411e /freebsd/sys/netinet6/in6_pcb.c | |
parent | Update to FreeBSD head 2018-02-01 (diff) | |
download | rtems-libbsd-2df56dbd60bb5d925d2ce0ddbdefdbe6107ea783.tar.bz2 |
Update to FreeBSD head 2018-04-01
Git mirror commit 8dfb1ccc26d1cea7e2529303003ff61f9f1784c4.
Update #3472.
Diffstat (limited to 'freebsd/sys/netinet6/in6_pcb.c')
-rw-r--r-- | freebsd/sys/netinet6/in6_pcb.c | 74 |
1 files changed, 52 insertions, 22 deletions
diff --git a/freebsd/sys/netinet6/in6_pcb.c b/freebsd/sys/netinet6/in6_pcb.c index c9107260..a4bbd6a9 100644 --- a/freebsd/sys/netinet6/in6_pcb.c +++ b/freebsd/sys/netinet6/in6_pcb.c @@ -882,6 +882,7 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, struct inpcbhead *head; struct inpcb *inp, *tmpinp; u_short fport = fport_arg, lport = lport_arg; + bool locked; /* * First look for an exact match. @@ -1040,18 +1041,32 @@ in6_pcblookup_group(struct inpcbinfo *pcbinfo, struct inpcbgroup *pcbgroup, return (NULL); found: - in_pcbref(inp); - INP_GROUP_UNLOCK(pcbgroup); - if (lookupflags & INPLOOKUP_WLOCKPCB) { - INP_WLOCK(inp); - if (in_pcbrele_wlocked(inp)) - return (NULL); - } else if (lookupflags & INPLOOKUP_RLOCKPCB) { - INP_RLOCK(inp); - if (in_pcbrele_rlocked(inp)) - return (NULL); - } else + if (lookupflags & INPLOOKUP_WLOCKPCB) + locked = INP_TRY_WLOCK(inp); + else if (lookupflags & INPLOOKUP_RLOCKPCB) + locked = INP_TRY_RLOCK(inp); + else panic("%s: locking buf", __func__); + if (!locked) + in_pcbref(inp); + INP_GROUP_UNLOCK(pcbgroup); + if (!locked) { + if (lookupflags & INPLOOKUP_WLOCKPCB) { + INP_WLOCK(inp); + if (in_pcbrele_wlocked(inp)) + return (NULL); + } else { + INP_RLOCK(inp); + if (in_pcbrele_rlocked(inp)) + return (NULL); + } + } +#ifdef INVARIANTS + if (lookupflags & INPLOOKUP_WLOCKPCB) + INP_WLOCK_ASSERT(inp); + else + INP_RLOCK_ASSERT(inp); +#endif return (inp); } #endif /* PCBGROUP */ @@ -1177,23 +1192,38 @@ in6_pcblookup_hash(struct inpcbinfo *pcbinfo, struct in6_addr *faddr, struct ifnet *ifp) { struct inpcb *inp; + bool locked; INP_HASH_RLOCK(pcbinfo); inp = in6_pcblookup_hash_locked(pcbinfo, faddr, fport, laddr, lport, (lookupflags & ~(INPLOOKUP_RLOCKPCB | INPLOOKUP_WLOCKPCB)), ifp); if (inp != NULL) { - in_pcbref(inp); - INP_HASH_RUNLOCK(pcbinfo); - if (lookupflags & INPLOOKUP_WLOCKPCB) { - INP_WLOCK(inp); - if (in_pcbrele_wlocked(inp)) - return (NULL); - } else if (lookupflags & INPLOOKUP_RLOCKPCB) { - INP_RLOCK(inp); - if (in_pcbrele_rlocked(inp)) - return (NULL); - } else + if (lookupflags & INPLOOKUP_WLOCKPCB) + locked = INP_TRY_WLOCK(inp); + else if (lookupflags & INPLOOKUP_RLOCKPCB) + locked = INP_TRY_RLOCK(inp); + else panic("%s: locking bug", __func__); + if (!locked) + in_pcbref(inp); + INP_HASH_RUNLOCK(pcbinfo); + if (!locked) { + if (lookupflags & INPLOOKUP_WLOCKPCB) { + INP_WLOCK(inp); + if (in_pcbrele_wlocked(inp)) + return (NULL); + } else { + INP_RLOCK(inp); + if (in_pcbrele_rlocked(inp)) + return (NULL); + } + } +#ifdef INVARIANTS + if (lookupflags & INPLOOKUP_WLOCKPCB) + INP_WLOCK_ASSERT(inp); + else + INP_RLOCK_ASSERT(inp); +#endif } else INP_HASH_RUNLOCK(pcbinfo); return (inp); |