inpcb: Split portinfo token into tokens for porthash head
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Mon, 7 Dec 2015 06:33:51 +0000 (14:33 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Wed, 9 Dec 2015 02:21:14 +0000 (10:21 +0800)
And use pooled token for porthash head.  This avoids another 10K/s
~20K/s contention during local port selection.

sys/netinet/in_pcb.c
sys/netinet/in_pcb.h
sys/netinet/ip_divert.c
sys/netinet/raw_ip.c
sys/netinet/tcp_subr.c
sys/netinet/udp_usrreq.c
sys/netinet6/in6_pcb.c
sys/netinet6/in6_pcb.h
sys/netinet6/in6_src.c

index 43b3531..dea655a 100644 (file)
 #define INP_LOCALGROUP_SIZMIN  8
 #define INP_LOCALGROUP_SIZMAX  256
 
+static struct inpcb *in_pcblookup_local(struct inpcbporthead *porthash,
+               struct in_addr laddr, u_int lport_arg, int wild_okay,
+               struct ucred *cred);
+
 struct in_addr zeroin_addr;
 
 /*
@@ -363,21 +367,24 @@ static boolean_t
 in_pcbporthash_update(struct inpcbportinfo *portinfo,
     struct inpcb *inp, u_short lport, struct ucred *cred, int wild)
 {
+       struct inpcbporthead *porthash;
+
        /*
         * This has to be atomic.  If the porthash is shared across multiple
         * protocol threads, e.g. tcp and udp, then the token must be held.
         */
-       GET_PORT_TOKEN(portinfo);
+       porthash = in_pcbporthash_head(portinfo, lport);
+       GET_PORTHASH_TOKEN(porthash);
 
-       if (in_pcblookup_local(portinfo, inp->inp_laddr, lport,
+       if (in_pcblookup_local(porthash, inp->inp_laddr, lport,
            wild, cred) != NULL) {
-               REL_PORT_TOKEN(portinfo);
+               REL_PORTHASH_TOKEN(porthash);
                return FALSE;
        }
        inp->inp_lport = lport;
-       in_pcbinsporthash(portinfo, inp);
+       in_pcbinsporthash(porthash, inp);
 
-       REL_PORT_TOKEN(portinfo);
+       REL_PORTHASH_TOKEN(porthash);
        return TRUE;
 }
 
@@ -508,6 +515,7 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
                struct sockaddr_in *sin = (struct sockaddr_in *)nam;
                struct inpcbinfo *pcbinfo;
                struct inpcbportinfo *portinfo;
+               struct inpcbporthead *porthash;
                struct inpcb *t;
                u_short lport, lport_ho;
                int reuseport = (so->so_options & SO_REUSEPORT);
@@ -579,14 +587,15 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
 
                /*
                 * This has to be atomic.  If the porthash is shared across
-                * multiple protocol threads (aka tcp) then the token must
-                * be held.
+                * multiple protocol threads, e.g. tcp and udp then the token
+                * must be held.
                 */
-               GET_PORT_TOKEN(portinfo);
+               porthash = in_pcbporthash_head(portinfo, lport);
+               GET_PORTHASH_TOKEN(porthash);
 
                if (so->so_cred->cr_uid != 0 &&
                    !IN_MULTICAST(ntohl(sin->sin_addr.s_addr))) {
-                       t = in_pcblookup_local(portinfo, sin->sin_addr, lport,
+                       t = in_pcblookup_local(porthash, sin->sin_addr, lport,
                            INPLOOKUP_WILDCARD, cred);
                        if (t &&
                            (so->so_cred->cr_uid !=
@@ -601,7 +610,7 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
                        error = EADDRNOTAVAIL;
                        goto done;
                }
-               t = in_pcblookup_local(portinfo, sin->sin_addr, lport,
+               t = in_pcblookup_local(porthash, sin->sin_addr, lport,
                    wild, cred);
                if (t && !(reuseport & t->inp_socket->so_options)) {
                        inp->inp_laddr.s_addr = INADDR_ANY;
@@ -609,10 +618,10 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
                        goto done;
                }
                inp->inp_lport = lport;
-               in_pcbinsporthash(portinfo, inp);
+               in_pcbinsporthash(porthash, inp);
                error = 0;
 done:
-               REL_PORT_TOKEN(portinfo);
+               REL_PORTHASH_TOKEN(porthash);
                return (error);
        } else {
                jsin.sin_family = AF_INET;
@@ -628,11 +637,10 @@ done:
 }
 
 static struct inpcb *
-in_pcblookup_localremote(struct inpcbportinfo *portinfo, struct in_addr laddr,
+in_pcblookup_localremote(struct inpcbporthead *porthash, struct in_addr laddr,
     u_short lport, struct in_addr faddr, u_short fport, struct ucred *cred)
 {
        struct inpcb *inp;
-       struct inpcbporthead *porthash;
        struct inpcbport *phd;
        struct inpcb *match = NULL;
 
@@ -640,7 +648,7 @@ in_pcblookup_localremote(struct inpcbportinfo *portinfo, struct in_addr laddr,
         * If the porthashbase is shared across several cpus, it must
         * have been locked.
         */
-       ASSERT_PORT_TOKEN_HELD(portinfo);
+       ASSERT_PORTHASH_TOKEN_HELD(porthash);
 
        /*
         * Best fit PCB lookup.
@@ -648,8 +656,6 @@ in_pcblookup_localremote(struct inpcbportinfo *portinfo, struct in_addr laddr,
         * First see if this local port is in use by looking on the
         * port hash list.
         */
-       porthash = &portinfo->porthashbase[
-                       INP_PCBPORTHASH(lport, portinfo->porthashmask)];
        LIST_FOREACH(phd, porthash, phd_hash) {
                if (phd->phd_port == lport)
                        break;
@@ -687,21 +693,24 @@ in_pcbporthash_update4(struct inpcbportinfo *portinfo,
     struct inpcb *inp, u_short lport, const struct sockaddr_in *sin,
     struct ucred *cred)
 {
+       struct inpcbporthead *porthash;
+
        /*
         * This has to be atomic.  If the porthash is shared across multiple
         * protocol threads, e.g. tcp and udp, then the token must be held.
         */
-       GET_PORT_TOKEN(portinfo);
+       porthash = in_pcbporthash_head(portinfo, lport);
+       GET_PORTHASH_TOKEN(porthash);
 
-       if (in_pcblookup_localremote(portinfo, inp->inp_laddr,
+       if (in_pcblookup_localremote(porthash, inp->inp_laddr,
            lport, sin->sin_addr, sin->sin_port, cred) != NULL) {
-               REL_PORT_TOKEN(portinfo);
+               REL_PORTHASH_TOKEN(porthash);
                return FALSE;
        }
        inp->inp_lport = lport;
-       in_pcbinsporthash(portinfo, inp);
+       in_pcbinsporthash(porthash, inp);
 
-       REL_PORT_TOKEN(portinfo);
+       REL_PORTHASH_TOKEN(porthash);
        return TRUE;
 }
 
@@ -1372,14 +1381,13 @@ in_rtchange(struct inpcb *inp, int err)
 /*
  * Lookup a PCB based on the local address and port.
  */
-struct inpcb *
-in_pcblookup_local(struct inpcbportinfo *portinfo, struct in_addr laddr,
+static struct inpcb *
+in_pcblookup_local(struct inpcbporthead *porthash, struct in_addr laddr,
                   u_int lport_arg, int wild_okay, struct ucred *cred)
 {
        struct inpcb *inp;
        int matchwild = 3, wildcard;
        u_short lport = lport_arg;
-       struct inpcbporthead *porthash;
        struct inpcbport *phd;
        struct inpcb *match = NULL;
 
@@ -1387,7 +1395,7 @@ in_pcblookup_local(struct inpcbportinfo *portinfo, struct in_addr laddr,
         * If the porthashbase is shared across several cpus, it must
         * have been locked.
         */
-       ASSERT_PORT_TOKEN_HELD(portinfo);
+       ASSERT_PORTHASH_TOKEN_HELD(porthash);
 
        /*
         * Best fit PCB lookup.
@@ -1395,8 +1403,6 @@ in_pcblookup_local(struct inpcbportinfo *portinfo, struct in_addr laddr,
         * First see if this local port is in use by looking on the
         * port hash list.
         */
-       porthash = &portinfo->porthashbase[
-                       INP_PCBPORTHASH(lport, portinfo->porthashmask)];
        LIST_FOREACH(phd, porthash, phd_hash) {
                if (phd->phd_port == lport)
                        break;
@@ -1725,23 +1731,20 @@ in_pcbremconnhash(struct inpcb *inp)
  * Insert PCB into port hash table.
  */
 void
-in_pcbinsporthash(struct inpcbportinfo *portinfo, struct inpcb *inp)
+in_pcbinsporthash(struct inpcbporthead *pcbporthash, struct inpcb *inp)
 {
        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
-       struct inpcbporthead *pcbporthash;
        struct inpcbport *phd;
 
        /*
         * If the porthashbase is shared across several cpus, it must
         * have been locked.
         */
-       ASSERT_PORT_TOKEN_HELD(portinfo);
+       ASSERT_PORTHASH_TOKEN_HELD(pcbporthash);
 
        /*
         * Insert into the port hash table.
         */
-       pcbporthash = &portinfo->porthashbase[
-           INP_PCBPORTHASH(inp->inp_lport, portinfo->porthashmask)];
 
        /* Go through port list and look for a head for this lport. */
        LIST_FOREACH(phd, pcbporthash, phd_hash) {
@@ -1759,7 +1762,7 @@ in_pcbinsporthash(struct inpcbportinfo *portinfo, struct inpcb *inp)
                LIST_INSERT_HEAD(pcbporthash, phd, phd_hash);
        }
 
-       inp->inp_portinfo = portinfo;
+       inp->inp_porthash = pcbporthash;
        inp->inp_phd = phd;
        LIST_INSERT_HEAD(&phd->phd_pcblist, inp, inp_portlist);
 
@@ -1780,6 +1783,7 @@ in_pcbinsporthash_lport(struct inpcb *inp)
 {
        struct inpcbinfo *pcbinfo = inp->inp_pcbinfo;
        struct inpcbportinfo *portinfo;
+       struct inpcbporthead *porthash;
        u_short lport_ho;
 
        /* Locate the proper portinfo based on lport */
@@ -1787,28 +1791,24 @@ in_pcbinsporthash_lport(struct inpcb *inp)
        portinfo = &pcbinfo->portinfo[lport_ho & pcbinfo->portinfo_mask];
        KKASSERT((lport_ho & pcbinfo->portinfo_mask) == portinfo->offset);
 
-       GET_PORT_TOKEN(portinfo);
-       in_pcbinsporthash(portinfo, inp);
-       REL_PORT_TOKEN(portinfo);
+       porthash = in_pcbporthash_head(portinfo, inp->inp_lport);
+       GET_PORTHASH_TOKEN(porthash);
+       in_pcbinsporthash(porthash, inp);
+       REL_PORTHASH_TOKEN(porthash);
 }
 
 void
 in_pcbremporthash(struct inpcb *inp)
 {
-       struct inpcbportinfo *portinfo;
+       struct inpcbporthead *porthash;
        struct inpcbport *phd;
 
        if (inp->inp_phd == NULL)
                return;
        KASSERT(inp->inp_lport != 0, ("inpcb has no lport"));
 
-       /*
-        * NOTE:
-        * inp->inp_portinfo is _not_ necessary same as
-        * inp->inp_pcbinfo->portinfo.
-        */
-       portinfo = inp->inp_portinfo;
-       GET_PORT_TOKEN(portinfo);
+       porthash = inp->inp_porthash;
+       GET_PORTHASH_TOKEN(porthash);
 
        phd = inp->inp_phd;
        LIST_REMOVE(inp, inp_portlist);
@@ -1817,9 +1817,10 @@ in_pcbremporthash(struct inpcb *inp)
                kfree(phd, M_PCB);
        }
 
-       REL_PORT_TOKEN(portinfo);
+       REL_PORTHASH_TOKEN(porthash);
 
        inp->inp_phd = NULL;
+       /* NOTE: Don't whack inp_lport, which may be used later */
 }
 
 static struct inp_localgroup *
@@ -2308,7 +2309,7 @@ in_savefaddr(struct socket *so, const struct sockaddr *faddr)
 
 void
 in_pcbportinfo_init(struct inpcbportinfo *portinfo, int hashsize,
-    boolean_t shared, u_short offset)
+    u_short offset)
 {
        memset(portinfo, 0, sizeof(*portinfo));
 
@@ -2319,12 +2320,6 @@ in_pcbportinfo_init(struct inpcbportinfo *portinfo, int hashsize,
 
        portinfo->porthashbase = hashinit(hashsize, M_PCB,
            &portinfo->porthashmask);
-
-       if (shared) {
-               portinfo->porttoken = kmalloc(sizeof(struct lwkt_token),
-                   M_PCB, M_WAITOK);
-               lwkt_token_init(portinfo->porttoken, "porttoken");
-       }
 }
 
 void
index 59f1fd9..b7b023c 100644 (file)
@@ -238,7 +238,7 @@ struct inpcb {
                u_int8_t        inp6_hlim;
        } inp_depend6;
        LIST_ENTRY(inpcb) inp_portlist;
-       struct  inpcbportinfo *inp_portinfo;
+       struct  inpcbporthead *inp_porthash;
        struct  inpcbport *inp_phd;     /* head of this list */
        inp_gen_t       inp_gencnt;     /* generation count of this instance */
 #define        in6p_faddr      inp_inc.inc6_faddr
@@ -292,7 +292,6 @@ struct inpcbport {
 struct lwkt_token;
 
 struct inpcbportinfo {
-       struct  lwkt_token *porttoken;  /* if this inpcbportinfo is shared */
        struct  inpcbporthead *porthashbase;
        u_long  porthashmask;
        u_short offset;
@@ -421,27 +420,29 @@ struct baddynamicports {
 
 #ifdef _KERNEL
 
-#define GET_PORT_TOKEN(portinfo) \
+static __inline struct inpcbporthead *
+in_pcbporthash_head(struct inpcbportinfo *portinfo, u_short lport)
+{
+       return &portinfo->porthashbase[
+           INP_PCBPORTHASH(lport, portinfo->porthashmask)];
+}
+
+#define GET_PORTHASH_TOKEN(porthashhead) \
 do { \
-       if ((portinfo)->porttoken) \
-               lwkt_gettoken((portinfo)->porttoken); \
+       lwkt_getpooltoken((porthashhead)); \
 } while (0)
 
-#define REL_PORT_TOKEN(portinfo) \
+#define REL_PORTHASH_TOKEN(porthashhead) \
 do { \
-       if ((portinfo)->porttoken) \
-               lwkt_reltoken((portinfo)->porttoken); \
+       lwkt_relpooltoken((porthashhead)); \
 } while (0)
 
 #ifdef INVARIANTS
-#define ASSERT_PORT_TOKEN_HELD(portinfo) \
-do { \
-       if ((portinfo)->porttoken) \
-               ASSERT_LWKT_TOKEN_HELD((portinfo)->porttoken); \
-} while (0)
-#else  /* !INVARIANTS */
-#define ASSERT_PORT_TOKEN_HELD(portinfo)
-#endif /* INVARIANTS */
+#define ASSERT_PORTHASH_TOKEN_HELD(pcbhashhead) \
+       ASSERT_LWKT_TOKEN_HELD(lwkt_token_pool_lookup((pcbhashhead)))
+#else
+#define ASSERT_PORTHASH_TOKEN_HELD(pcbhashhead)
+#endif
 
 #define GET_PCBINFO_TOKEN(pcbinfo) \
 do { \
@@ -496,7 +497,7 @@ void        in_pcbpurgeif0 (struct inpcbinfo *, struct ifnet *);
 void   in_losing (struct inpcb *);
 void   in_rtchange (struct inpcb *, int);
 void   in_pcbinfo_init (struct inpcbinfo *, int, boolean_t);
-void   in_pcbportinfo_init (struct inpcbportinfo *, int, boolean_t, u_short);
+void   in_pcbportinfo_init (struct inpcbportinfo *, int, u_short);
 int    in_pcballoc (struct socket *, struct inpcbinfo *);
 void   in_pcbunlink (struct inpcb *, struct inpcbinfo *);
 void   in_pcbunlink_flags (struct inpcb *, struct inpcbinfo *, int);
@@ -513,16 +514,13 @@ void      in_pcbdisconnect (struct inpcb *);
 void   in_pcbinswildcardhash(struct inpcb *inp);
 void   in_pcbinswildcardhash_oncpu(struct inpcb *, struct inpcbinfo *);
 void   in_pcbinsconnhash(struct inpcb *inp);
-void   in_pcbinsporthash (struct inpcbportinfo *, struct inpcb *);
+void   in_pcbinsporthash(struct inpcbporthead *, struct inpcb *);
 void   in_pcbinsporthash_lport (struct inpcb *);
 void   in_pcbremporthash (struct inpcb *);
 int    in_pcbladdr (struct inpcb *, struct sockaddr *,
            struct sockaddr_in **, struct thread *);
 int    in_pcbladdr_find (struct inpcb *, struct sockaddr *,
            struct sockaddr_in **, struct thread *, int);
-struct inpcb *
-       in_pcblookup_local (struct inpcbportinfo *, struct in_addr, u_int, int,
-                           struct ucred *);
 struct inpcb *
        in_pcblookup_hash (struct inpcbinfo *,
                               struct in_addr, u_int, struct in_addr, u_int,
index c0c528e..85fa421 100644 (file)
@@ -126,7 +126,7 @@ void
 div_init(void)
 {
        in_pcbinfo_init(&divcbinfo, 0, FALSE);
-       in_pcbportinfo_init(&divcbportinfo, 1, FALSE, 0);
+       in_pcbportinfo_init(&divcbportinfo, 1, 0);
        /*
         * XXX We don't use the hash list for divert IP, but it's easier
         * to allocate a one entry hash list than it is to check all
index 010aca0..d977235 100644 (file)
@@ -129,7 +129,7 @@ void
 rip_init(void)
 {
        in_pcbinfo_init(&ripcbinfo, 0, FALSE);
-       in_pcbportinfo_init(&ripcbportinfo, 1, FALSE, 0);
+       in_pcbportinfo_init(&ripcbportinfo, 1, 0);
        /*
         * XXX We don't use the hash list for raw IP, but it's easier
         * to allocate a one entry hash list than it is to check all
index 15eae38..b1f4fd0 100644 (file)
@@ -393,7 +393,7 @@ tcp_init(void)
                in_pcbinfo_init(ticb, cpu, FALSE);
                ticb->hashbase = hashinit(hashsize, M_PCB,
                                          &ticb->hashmask);
-               in_pcbportinfo_init(&portinfo[cpu], hashsize, TRUE, cpu);
+               in_pcbportinfo_init(&portinfo[cpu], hashsize, cpu);
                ticb->portinfo = portinfo;
                ticb->portinfo_mask = ncpus2_mask;
                ticb->wildcardhashbase = hashinit(hashsize, M_PCB,
index bbc96b7..807a12c 100644 (file)
@@ -221,7 +221,7 @@ udp_init(void)
                in_pcbinfo_init(uicb, cpu, TRUE);
                uicb->hashbase = hashinit(UDBHASHSIZE, M_PCB, &uicb->hashmask);
 
-               in_pcbportinfo_init(&portinfo[cpu], UDBHASHSIZE, TRUE, cpu);
+               in_pcbportinfo_init(&portinfo[cpu], UDBHASHSIZE, cpu);
                uicb->portinfo = portinfo;
                uicb->portinfo_mask = ncpus2_mask;
 
index 98d0648..92a07d4 100644 (file)
@@ -138,6 +138,7 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
                struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)nam;
                struct inpcbinfo *pcbinfo;
                struct inpcbportinfo *portinfo;
+               struct inpcbporthead *porthash;
                int wild = 0, reuseport = (so->so_options & SO_REUSEPORT);
                struct ucred *cred = NULL;
                struct inpcb *t;
@@ -230,11 +231,12 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
                 * multiple protocol threads (aka tcp) then the token must
                 * be held.
                 */
-               GET_PORT_TOKEN(portinfo);
+               porthash = in_pcbporthash_head(portinfo, lport);
+               GET_PORTHASH_TOKEN(porthash);
 
                if (so->so_cred->cr_uid != 0 &&
                    !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
-                       t = in6_pcblookup_local(portinfo,
+                       t = in6_pcblookup_local(porthash,
                            &sin6->sin6_addr, lport, INPLOOKUP_WILDCARD, cred);
                        if (t &&
                            (so->so_cred->cr_uid !=
@@ -250,7 +252,7 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
                        error = EADDRNOTAVAIL;
                        goto done;
                }
-               t = in6_pcblookup_local(portinfo, &sin6->sin6_addr, lport,
+               t = in6_pcblookup_local(porthash, &sin6->sin6_addr, lport,
                    wild, cred);
                if (t && (reuseport & t->inp_socket->so_options) == 0) {
                        inp->in6p_laddr = kin6addr_any;
@@ -259,10 +261,10 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td)
                }
 
                inp->inp_lport = lport;
-               in_pcbinsporthash(portinfo, inp);
+               in_pcbinsporthash(porthash, inp);
                error = 0;
 done:
-               REL_PORT_TOKEN(portinfo);
+               REL_PORTHASH_TOKEN(porthash);
                return (error);
        } else {
 auto_select:
@@ -634,14 +636,13 @@ do_notify:
  * Lookup a PCB based on the local address and port.
  */
 struct inpcb *
-in6_pcblookup_local(struct inpcbportinfo *portinfo,
+in6_pcblookup_local(struct inpcbporthead *porthash,
     const struct in6_addr *laddr, u_int lport_arg, int wild_okay,
     struct ucred *cred)
 {
        struct inpcb *inp;
        int matchwild = 3, wildcard;
        u_short lport = lport_arg;
-       struct inpcbporthead *porthash;
        struct inpcbport *phd;
        struct inpcb *match = NULL;
 
@@ -649,7 +650,7 @@ in6_pcblookup_local(struct inpcbportinfo *portinfo,
         * If the porthashbase is shared across several cpus, it must
         * have been locked.
         */
-       ASSERT_PORT_TOKEN_HELD(portinfo);
+       ASSERT_PORTHASH_TOKEN_HELD(porthash);
 
        /*
         * Best fit PCB lookup.
@@ -657,8 +658,6 @@ in6_pcblookup_local(struct inpcbportinfo *portinfo,
         * First see if this local port is in use by looking on the
         * port hash list.
         */
-       porthash = &portinfo->porthashbase[
-                               INP_PCBPORTHASH(lport, portinfo->porthashmask)];
        LIST_FOREACH(phd, porthash, phd_hash) {
                if (phd->phd_port == lport)
                        break;
index aea91fd..f0d2b26 100644 (file)
@@ -110,7 +110,7 @@ void        in6_pcbdisconnect (struct inpcb *);
 int    in6_pcbladdr (struct inpcb *, struct sockaddr *,
                          struct in6_addr **, struct thread *);
 struct inpcb *
-       in6_pcblookup_local (struct inpcbportinfo *, const struct in6_addr *,
+       in6_pcblookup_local (struct inpcbporthead *, const struct in6_addr *,
                             u_int, int, struct ucred *);
 struct inpcb *
        in6_pcblookup_hash (struct inpcbinfo *,
index 10d5459..fbf9bb6 100644 (file)
@@ -380,21 +380,24 @@ static boolean_t
 in6_pcbporthash_update(struct inpcbportinfo *portinfo,
     struct inpcb *inp, u_short lport, struct ucred *cred, int wild)
 {
+       struct inpcbporthead *porthash;
+
        /*
         * This has to be atomic.  If the porthash is shared across multiple
         * protocol threads, e.g. tcp and udp, then the token must be held.
         */
-       GET_PORT_TOKEN(portinfo);
+       porthash = in_pcbporthash_head(portinfo, lport);
+       GET_PORTHASH_TOKEN(porthash);
 
-       if (in6_pcblookup_local(portinfo, &inp->in6p_laddr, lport,
+       if (in6_pcblookup_local(porthash, &inp->in6p_laddr, lport,
            wild, cred) != NULL) {
-               REL_PORT_TOKEN(portinfo);
+               REL_PORTHASH_TOKEN(porthash);
                return FALSE;
        }
        inp->inp_lport = lport;
-       in_pcbinsporthash(portinfo, inp);
+       in_pcbinsporthash(porthash, inp);
 
-       REL_PORT_TOKEN(portinfo);
+       REL_PORTHASH_TOKEN(porthash);
        return TRUE;
 }