From 16db446e752b3626bb4b46663904544c529b7ffd Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 13 Apr 2017 00:46:17 +0800 Subject: [PATCH] inpcb: Don't rely on ncpus2 for local port allocation. --- sys/netinet/in_pcb.c | 40 +++++++++++++++++++++------------------- sys/netinet/in_pcb.h | 2 +- sys/netinet/tcp_subr.c | 2 +- sys/netinet/udp_usrreq.c | 2 +- sys/netinet6/in6_pcb.c | 4 ++-- sys/netinet6/in6_src.c | 10 +++++----- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 263ce967f1..24a194b3cc 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -400,8 +400,8 @@ in_pcbsetlport(struct inpcb *inp, int wild, struct ucred *cred) inp->inp_flags |= INP_ANONPORT; - step = pcbinfo->portinfo_mask + 1; - portinfo_first = mycpuid & pcbinfo->portinfo_mask; + step = pcbinfo->portinfo_cnt; + portinfo_first = mycpuid % pcbinfo->portinfo_cnt; portinfo_idx = portinfo_first; loop: portinfo = &pcbinfo->portinfo[portinfo_idx]; @@ -447,7 +447,7 @@ loop: } lport = in_pcblastport_down(lastport, first, last, step); - KKASSERT((lport & pcbinfo->portinfo_mask) == + KKASSERT((lport % pcbinfo->portinfo_cnt) == portinfo->offset); lport = htons(lport); @@ -470,7 +470,7 @@ loop: break; } lport = in_pcblastport_up(lastport, first, last, step); - KKASSERT((lport & pcbinfo->portinfo_mask) == + KKASSERT((lport % pcbinfo->portinfo_cnt) == portinfo->offset); lport = htons(lport); @@ -485,7 +485,7 @@ loop: if (error) { /* Try next portinfo */ portinfo_idx++; - portinfo_idx &= pcbinfo->portinfo_mask; + portinfo_idx %= pcbinfo->portinfo_cnt; if (portinfo_idx != portinfo_first) goto loop; inp->inp_laddr.s_addr = INADDR_ANY; @@ -581,8 +581,8 @@ in_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td) */ pcbinfo = inp->inp_pcbinfo; portinfo = - &pcbinfo->portinfo[lport_ho & pcbinfo->portinfo_mask]; - KKASSERT((lport_ho & pcbinfo->portinfo_mask) == + &pcbinfo->portinfo[lport_ho % pcbinfo->portinfo_cnt]; + KKASSERT((lport_ho % pcbinfo->portinfo_cnt) == portinfo->offset); /* @@ -760,11 +760,11 @@ in_pcbbind_remote(struct inpcb *inp, const struct sockaddr *remote, inp->inp_flags |= INP_ANONPORT; - step = pcbinfo->portinfo_mask + 1; - portinfo_first = mycpuid & pcbinfo->portinfo_mask; + step = pcbinfo->portinfo_cnt; + portinfo_first = mycpuid % pcbinfo->portinfo_cnt; portinfo_idx = portinfo_first; loop: - hash_cpu = portinfo_idx & ncpus2_mask; + hash_cpu = portinfo_idx % netisr_ncpus; portinfo = &pcbinfo->portinfo[portinfo_idx]; selfconn = 0; @@ -816,7 +816,7 @@ loop: lport = in_pcblastport_down(lastport, first, last, step); - KKASSERT((lport & pcbinfo->portinfo_mask) == + KKASSERT((lport % pcbinfo->portinfo_cnt) == portinfo->offset); lport = htons(lport); if (IS_SELFCONNECT(inp, lport, sin)) { @@ -831,7 +831,8 @@ loop: --hash_count; hash = hash_base ^ toeplitz_piecemeal_port(lport); - if ((hash & ncpus2_mask) != hash_cpu && hash_count) + if (netisr_hashcpu(hash) != hash_cpu && + hash_count) continue; } @@ -855,7 +856,7 @@ loop: } lport = in_pcblastport_up(lastport, first, last, step); - KKASSERT((lport & pcbinfo->portinfo_mask) == + KKASSERT((lport % pcbinfo->portinfo_cnt) == portinfo->offset); lport = htons(lport); if (IS_SELFCONNECT(inp, lport, sin)) { @@ -870,7 +871,8 @@ loop: --hash_count; hash = hash_base ^ toeplitz_piecemeal_port(lport); - if ((hash & ncpus2_mask) != hash_cpu && hash_count) + if (netisr_hashcpu(hash) != hash_cpu && + hash_count) continue; } @@ -887,7 +889,7 @@ loop: if (error) { /* Try next portinfo */ portinfo_idx++; - portinfo_idx &= pcbinfo->portinfo_mask; + portinfo_idx %= pcbinfo->portinfo_cnt; if (portinfo_idx != portinfo_first) goto loop; inp->inp_laddr.s_addr = INADDR_ANY; @@ -1789,8 +1791,8 @@ in_pcbinsporthash_lport(struct inpcb *inp) /* Locate the proper portinfo based on lport */ lport_ho = ntohs(inp->inp_lport); - portinfo = &pcbinfo->portinfo[lport_ho & pcbinfo->portinfo_mask]; - KKASSERT((lport_ho & pcbinfo->portinfo_mask) == portinfo->offset); + portinfo = &pcbinfo->portinfo[lport_ho % pcbinfo->portinfo_cnt]; + KKASSERT((lport_ho % pcbinfo->portinfo_cnt) == portinfo->offset); porthash = in_pcbporthash_head(portinfo, inp->inp_lport); GET_PORTHASH_TOKEN(porthash); @@ -2337,12 +2339,12 @@ in_pcbportrange(u_short *hi0, u_short *lo0, u_short ofs, u_short step) hi = *hi0; lo = *lo0; - hi = rounddown2(hi, step); + hi = rounddown(hi, step); hi += ofs; if (hi > (int)*hi0) hi -= step; - lo = roundup2(lo, step); + lo = roundup(lo, step); lo -= (step - ofs); if (lo < (int)*lo0) lo += step; diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index a0b0e299f1..9d09edd02b 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -302,7 +302,7 @@ struct inpcbinfo { /* XXX documentation, prefixes */ struct lwkt_token *infotoken; /* if this inpcbinfo is shared */ struct inpcbhead *hashbase; u_long hashmask; - int portinfo_mask; + int portinfo_cnt; struct inpcbportinfo *portinfo; struct inpcbport *portsave; /* port allocation cache */ struct inpcontainerhead *wildcardhashbase; diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index 154557b339..003f7f2ace 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -395,7 +395,7 @@ tcp_init(void) &ticb->hashmask); in_pcbportinfo_init(&portinfo[cpu], hashsize, cpu); ticb->portinfo = portinfo; - ticb->portinfo_mask = ncpus2_mask; + ticb->portinfo_cnt = netisr_ncpus; ticb->wildcardhashbase = hashinit(hashsize, M_PCB, &ticb->wildcardhashmask); ticb->localgrphashbase = hashinit(hashsize, M_PCB, diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index b50c7c7c0b..5fb5bebf2a 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -223,7 +223,7 @@ udp_init(void) in_pcbportinfo_init(&portinfo[cpu], UDBHASHSIZE, cpu); uicb->portinfo = portinfo; - uicb->portinfo_mask = ncpus2_mask; + uicb->portinfo_cnt = netisr_ncpus; uicb->wildcardhashbase = hashinit(UDBHASHSIZE, M_PCB, &uicb->wildcardhashmask); diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 92a07d47b8..76131dfd7c 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -222,8 +222,8 @@ in6_pcbbind(struct inpcb *inp, struct sockaddr *nam, struct thread *td) */ pcbinfo = inp->inp_pcbinfo; portinfo = - &pcbinfo->portinfo[lport_ho & pcbinfo->portinfo_mask]; - KKASSERT((lport_ho & pcbinfo->portinfo_mask) == + &pcbinfo->portinfo[lport_ho % pcbinfo->portinfo_cnt]; + KKASSERT((lport_ho % pcbinfo->portinfo_cnt) == portinfo->offset); /* diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index fbf9bb68c5..97e20729fa 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -424,8 +424,8 @@ in6_pcbsetlport(struct in6_addr *laddr, struct inpcb *inp, struct thread *td) inp->inp_flags |= INP_ANONPORT; - step = pcbinfo->portinfo_mask + 1; - portinfo_first = mycpuid & pcbinfo->portinfo_mask; + step = pcbinfo->portinfo_cnt; + portinfo_first = mycpuid % pcbinfo->portinfo_cnt; portinfo_idx = portinfo_first; loop: portinfo = &pcbinfo->portinfo[portinfo_idx]; @@ -467,7 +467,7 @@ loop: } lport = in_pcblastport_down(lastport, first, last, step); - KKASSERT((lport & pcbinfo->portinfo_mask) == + KKASSERT((lport % pcbinfo->portinfo_cnt) == portinfo->offset); lport = htons(lport); @@ -490,7 +490,7 @@ loop: break; } lport = in_pcblastport_up(lastport, first, last, step); - KKASSERT((lport & pcbinfo->portinfo_mask) == + KKASSERT((lport % pcbinfo->portinfo_cnt) == portinfo->offset); lport = htons(lport); @@ -505,7 +505,7 @@ loop: if (error) { /* Try next portinfo */ portinfo_idx++; - portinfo_idx &= pcbinfo->portinfo_mask; + portinfo_idx %= pcbinfo->portinfo_cnt; if (portinfo_idx != portinfo_first) goto loop; -- 2.11.4.GIT