diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 4c0dc391411a..671a9c7c7faf 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -235,16 +235,26 @@ in_pcblbgroup_alloc(struct inpcblbgrouphead *hdr, u_char vflag, grp->il_lport = port; grp->il_dependladdr = *addr; grp->il_inpsiz = size; - LIST_INSERT_HEAD(hdr, grp, il_list); + CK_LIST_INSERT_HEAD(hdr, grp, il_list); return (grp); } +static void +in_pcblbgroup_free_deferred(epoch_context_t ctx) +{ + struct inpcblbgroup *grp; + + grp = __containerof(ctx, struct inpcblbgroup, il_epoch_ctx); + free(grp, M_PCB); +} + static void in_pcblbgroup_free(struct inpcblbgroup *grp) { - LIST_REMOVE(grp, il_list); - free(grp, M_PCB); + CK_LIST_REMOVE(grp, il_list); + epoch_call(net_epoch_preempt, &grp->il_epoch_ctx, + in_pcblbgroup_free_deferred); } static struct inpcblbgroup * @@ -347,7 +357,7 @@ in_pcbinslbgrouphash(struct inpcb *inp) hdr = &pcbinfo->ipi_lbgrouphashbase[ INP_PCBLBGROUP_PORTHASH(inp->inp_lport, pcbinfo->ipi_lbgrouphashmask)]; - LIST_FOREACH(grp, hdr, il_list) { + CK_LIST_FOREACH(grp, hdr, il_list) { if (grp->il_vflag == inp->inp_vflag && grp->il_lport == inp->inp_lport && memcmp(&grp->il_dependladdr, @@ -409,7 +419,7 @@ in_pcbremlbgrouphash(struct inpcb *inp) INP_PCBLBGROUP_PORTHASH(inp->inp_lport, pcbinfo->ipi_lbgrouphashmask)]; - LIST_FOREACH(grp, hdr, il_list) { + CK_LIST_FOREACH(grp, hdr, il_list) { for (i = 0; i < grp->il_inpcnt; ++i) { if (grp->il_inp[i] != inp) continue; @@ -1972,7 +1982,7 @@ in_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo, * - Load balanced group does not contain IPv4 mapped INET6 wild sockets */ local_wild = NULL; - LIST_FOREACH(grp, hdr, il_list) { + CK_LIST_FOREACH(grp, hdr, il_list) { #ifdef INET6 if (!(grp->il_vflag & INP_IPV4)) continue; diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index d3677118bbec..86c9705cb905 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -70,6 +70,7 @@ */ CK_LIST_HEAD(inpcbhead, inpcb); CK_LIST_HEAD(inpcbporthead, inpcbport); +CK_LIST_HEAD(inpcblbgrouphead, inpcblbgroup); typedef uint64_t inp_gen_t; /* @@ -566,7 +567,8 @@ struct inpcbgroup { * is dynamically resized as processes bind/unbind to that specific group. */ struct inpcblbgroup { - LIST_ENTRY(inpcblbgroup) il_list; + CK_LIST_ENTRY(inpcblbgroup) il_list; + struct epoch_context il_epoch_ctx; uint16_t il_lport; /* (c) */ u_char il_vflag; /* (c) */ u_char il_pad; @@ -578,7 +580,6 @@ struct inpcblbgroup { uint32_t il_inpcnt; /* cur count in il_inp[] (h) */ struct inpcb *il_inp[]; /* (h) */ }; -LIST_HEAD(inpcblbgrouphead, inpcblbgroup); #define INP_LOCK_INIT(inp, d, t) \ rw_init_flags(&(inp)->inp_lock, (t), RW_RECURSE | RW_DUPOK) diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index 7fdd324567aa..a9c73798b18c 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -889,7 +889,7 @@ in6_pcblookup_lbgroup(const struct inpcbinfo *pcbinfo, * - Load balanced group does not contain jailed sockets. * - Load balanced does not contain IPv4 mapped INET6 wild sockets. */ - LIST_FOREACH(grp, hdr, il_list) { + CK_LIST_FOREACH(grp, hdr, il_list) { #ifdef INET if (!(grp->il_vflag & INP_IPV6)) continue;