Author: mmacy
Date: Sun May 20 02:27:58 2018
New Revision: 333911
URL: https://svnweb.freebsd.org/changeset/base/333911

Log:
  inpcb: consolidate possible deletion in pcblist functions in to epoch
  deferred context.

Modified:
  head/sys/netinet/ip_divert.c
  head/sys/netinet/raw_ip.c
  head/sys/netinet/tcp_subr.c
  head/sys/netinet/udp_usrreq.c

Modified: head/sys/netinet/ip_divert.c
==============================================================================
--- head/sys/netinet/ip_divert.c        Sun May 20 02:17:30 2018        
(r333910)
+++ head/sys/netinet/ip_divert.c        Sun May 20 02:27:58 2018        
(r333911)
@@ -550,6 +550,7 @@ div_detach(struct socket *so)
        KASSERT(inp != NULL, ("div_detach: inp == NULL"));
        INP_INFO_WLOCK(&V_divcbinfo);
        INP_WLOCK(inp);
+       /* XXX defer destruction to epoch_call */
        in_pcbdetach(inp);
        in_pcbfree(inp);
        INP_INFO_WUNLOCK(&V_divcbinfo);
@@ -629,6 +630,7 @@ static int
 div_pcblist(SYSCTL_HANDLER_ARGS)
 {
        int error, i, n;
+       struct in_pcblist *il;
        struct inpcb *inp, **inp_list;
        inp_gen_t gencnt;
        struct xinpgen xig;
@@ -668,9 +670,8 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
        if (error)
                return error;
 
-       inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
-       if (inp_list == NULL)
-               return ENOMEM;
+       il = malloc(sizeof(struct in_pcblist) + n * sizeof(struct inpcb *), 
M_TEMP, M_WAITOK|M_ZERO);
+       inp_list = il->il_inp_list;
        
        INP_INFO_RLOCK(&V_divcbinfo);
        for (inp = LIST_FIRST(V_divcbinfo.ipi_listhead), i = 0; inp && i < n;
@@ -699,14 +700,9 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
                } else
                        INP_RUNLOCK(inp);
        }
-       INP_INFO_WLOCK(&V_divcbinfo);
-       for (i = 0; i < n; i++) {
-               inp = inp_list[i];
-               INP_RLOCK(inp);
-               if (!in_pcbrele_rlocked(inp))
-                       INP_RUNLOCK(inp);
-       }
-       INP_INFO_WUNLOCK(&V_divcbinfo);
+       il->il_count = n;
+       il->il_pcbinfo = &V_divcbinfo;
+       epoch_call(net_epoch_preempt, &il->il_epoch_ctx, 
in_pcblist_rele_rlocked);
 
        if (!error) {
                /*
@@ -723,7 +719,6 @@ div_pcblist(SYSCTL_HANDLER_ARGS)
                INP_INFO_RUNLOCK(&V_divcbinfo);
                error = SYSCTL_OUT(req, &xig, sizeof xig);
        }
-       free(inp_list, M_TEMP);
        return error;
 }
 
@@ -803,6 +798,7 @@ div_modevent(module_t mod, int type, void *unused)
                        break;
                }
                ip_divert_ptr = NULL;
+               /* XXX defer to epoch_call ? */
                err = pf_proto_unregister(PF_INET, IPPROTO_DIVERT, SOCK_RAW);
                INP_INFO_WUNLOCK(&V_divcbinfo);
 #ifndef VIMAGE

Modified: head/sys/netinet/raw_ip.c
==============================================================================
--- head/sys/netinet/raw_ip.c   Sun May 20 02:17:30 2018        (r333910)
+++ head/sys/netinet/raw_ip.c   Sun May 20 02:27:58 2018        (r333911)
@@ -851,6 +851,7 @@ rip_detach(struct socket *so)
                ip_rsvp_force_done(so);
        if (so == V_ip_rsvpd)
                ip_rsvp_done();
+       /* XXX defer to epoch_call */
        in_pcbdetach(inp);
        in_pcbfree(inp);
        INP_INFO_WUNLOCK(&V_ripcbinfo);
@@ -1020,6 +1021,7 @@ static int
 rip_pcblist(SYSCTL_HANDLER_ARGS)
 {
        int error, i, n;
+       struct in_pcblist *il;
        struct inpcb *inp, **inp_list;
        inp_gen_t gencnt;
        struct xinpgen xig;
@@ -1054,9 +1056,8 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
        if (error)
                return (error);
 
-       inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
-       if (inp_list == NULL)
-               return (ENOMEM);
+       il = malloc(sizeof(struct in_pcblist) + n * sizeof(struct inpcb *), 
M_TEMP, M_WAITOK|M_ZERO);
+       inp_list = il->il_inp_list;
 
        INP_INFO_RLOCK(&V_ripcbinfo);
        for (inp = LIST_FIRST(V_ripcbinfo.ipi_listhead), i = 0; inp && i < n;
@@ -1085,14 +1086,9 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
                } else
                        INP_RUNLOCK(inp);
        }
-       INP_INFO_WLOCK(&V_ripcbinfo);
-       for (i = 0; i < n; i++) {
-               inp = inp_list[i];
-               INP_RLOCK(inp);
-               if (!in_pcbrele_rlocked(inp))
-                       INP_RUNLOCK(inp);
-       }
-       INP_INFO_WUNLOCK(&V_ripcbinfo);
+       il->il_count = n;
+       il->il_pcbinfo = &V_ripcbinfo;
+       epoch_call(net_epoch_preempt, &il->il_epoch_ctx, 
in_pcblist_rele_rlocked);
 
        if (!error) {
                /*
@@ -1108,7 +1104,6 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
                INP_INFO_RUNLOCK(&V_ripcbinfo);
                error = SYSCTL_OUT(req, &xig, sizeof xig);
        }
-       free(inp_list, M_TEMP);
        return (error);
 }
 

Modified: head/sys/netinet/tcp_subr.c
==============================================================================
--- head/sys/netinet/tcp_subr.c Sun May 20 02:17:30 2018        (r333910)
+++ head/sys/netinet/tcp_subr.c Sun May 20 02:27:58 2018        (r333911)
@@ -943,6 +943,7 @@ deregister_tcp_functions(struct tcp_function_block *bl
                rw_wunlock(&tcp_function_lock);
 
                VNET_LIST_RLOCK();
+               /* XXX handle */
                VNET_FOREACH(vnet_iter) {
                        CURVNET_SET(vnet_iter);
                        INP_INFO_WLOCK(&V_tcbinfo);
@@ -1732,6 +1733,7 @@ tcp_ccalgounload(struct cc_algo *unload_algo)
                                        tmpalgo = CC_ALGO(tp);
                                        /* NewReno does not require any init. */
                                        CC_ALGO(tp) = &newreno_cc_algo;
+                                       /* XXX defer to epoch_call */
                                        if (tmpalgo->cb_destroy != NULL)
                                                tmpalgo->cb_destroy(tp->ccv);
                                }
@@ -2102,6 +2104,7 @@ static int
 tcp_pcblist(SYSCTL_HANDLER_ARGS)
 {
        int error, i, m, n, pcb_count;
+       struct in_pcblist *il;
        struct inpcb *inp, **inp_list;
        inp_gen_t gencnt;
        struct xinpgen xig;
@@ -2148,7 +2151,8 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
        if (error)
                return (error);
 
-       inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
+       il = malloc(sizeof(struct in_pcblist) + n * sizeof(struct inpcb *), 
M_TEMP, M_WAITOK|M_ZERO);
+       inp_list = il->il_inp_list;
 
        INP_INFO_WLOCK(&V_tcbinfo);
        for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0;
@@ -2191,15 +2195,11 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
                } else
                        INP_RUNLOCK(inp);
        }
-       INP_INFO_RLOCK(&V_tcbinfo);
-       for (i = 0; i < n; i++) {
-               inp = inp_list[i];
-               INP_RLOCK(inp);
-               if (!in_pcbrele_rlocked(inp))
-                       INP_RUNLOCK(inp);
-       }
-       INP_INFO_RUNLOCK(&V_tcbinfo);
 
+       il->il_count = n;
+       il->il_pcbinfo = &V_tcbinfo;
+       epoch_call(net_epoch_preempt, &il->il_epoch_ctx, 
in_pcblist_rele_rlocked);
+
        if (!error) {
                /*
                 * Give the user an updated idea of our state.
@@ -2215,7 +2215,6 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
                INP_LIST_RUNLOCK(&V_tcbinfo);
                error = SYSCTL_OUT(req, &xig, sizeof xig);
        }
-       free(inp_list, M_TEMP);
        return (error);
 }
 

Modified: head/sys/netinet/udp_usrreq.c
==============================================================================
--- head/sys/netinet/udp_usrreq.c       Sun May 20 02:17:30 2018        
(r333910)
+++ head/sys/netinet/udp_usrreq.c       Sun May 20 02:27:58 2018        
(r333911)
@@ -836,6 +836,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
 {
        int error, i, n;
        struct inpcb *inp, **inp_list;
+       struct in_pcblist *il;
        inp_gen_t gencnt;
        struct xinpgen xig;
 
@@ -873,11 +874,9 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
        error = SYSCTL_OUT(req, &xig, sizeof xig);
        if (error)
                return (error);
+       il = malloc(sizeof(struct in_pcblist) + n * sizeof(struct inpcb *), 
M_TEMP, M_WAITOK|M_ZERO);
+       inp_list = il->il_inp_list;
 
-       inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK);
-       if (inp_list == NULL)
-               return (ENOMEM);
-
        INP_INFO_RLOCK(&V_udbinfo);
        for (inp = LIST_FIRST(V_udbinfo.ipi_listhead), i = 0; inp && i < n;
             inp = LIST_NEXT(inp, inp_list)) {
@@ -905,14 +904,9 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
                } else
                        INP_RUNLOCK(inp);
        }
-       INP_INFO_WLOCK(&V_udbinfo);
-       for (i = 0; i < n; i++) {
-               inp = inp_list[i];
-               INP_RLOCK(inp);
-               if (!in_pcbrele_rlocked(inp))
-                       INP_RUNLOCK(inp);
-       }
-       INP_INFO_WUNLOCK(&V_udbinfo);
+       il->il_count = n;
+       il->il_pcbinfo = &V_udbinfo;
+       epoch_call(net_epoch_preempt, &il->il_epoch_ctx, 
in_pcblist_rele_rlocked);
 
        if (!error) {
                /*
@@ -928,7 +922,6 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
                INP_INFO_RUNLOCK(&V_udbinfo);
                error = SYSCTL_OUT(req, &xig, sizeof xig);
        }
-       free(inp_list, M_TEMP);
        return (error);
 }
 
@@ -1717,6 +1710,7 @@ udp_detach(struct socket *so)
        INP_WLOCK(inp);
        up = intoudpcb(inp);
        KASSERT(up != NULL, ("%s: up == NULL", __func__));
+       /* XXX defer to epoch_call */
        inp->inp_ppcb = NULL;
        in_pcbdetach(inp);
        in_pcbfree(inp);
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to