inpcb: consolidate possible deletion in pcblist functions in to epoch

deferred context.
This commit is contained in:
mmacy 2018-05-20 02:27:58 +00:00
parent 99ec59840b
commit fe7765802e
4 changed files with 31 additions and 47 deletions

View File

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

View File

@ -851,6 +851,7 @@ rip_detach(struct socket *so)
ip_rsvp_force_done(so); ip_rsvp_force_done(so);
if (so == V_ip_rsvpd) if (so == V_ip_rsvpd)
ip_rsvp_done(); ip_rsvp_done();
/* XXX defer to epoch_call */
in_pcbdetach(inp); in_pcbdetach(inp);
in_pcbfree(inp); in_pcbfree(inp);
INP_INFO_WUNLOCK(&V_ripcbinfo); INP_INFO_WUNLOCK(&V_ripcbinfo);
@ -1020,6 +1021,7 @@ static int
rip_pcblist(SYSCTL_HANDLER_ARGS) rip_pcblist(SYSCTL_HANDLER_ARGS)
{ {
int error, i, n; int error, i, n;
struct in_pcblist *il;
struct inpcb *inp, **inp_list; struct inpcb *inp, **inp_list;
inp_gen_t gencnt; inp_gen_t gencnt;
struct xinpgen xig; struct xinpgen xig;
@ -1054,9 +1056,8 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
if (error) if (error)
return (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);
if (inp_list == NULL) inp_list = il->il_inp_list;
return (ENOMEM);
INP_INFO_RLOCK(&V_ripcbinfo); INP_INFO_RLOCK(&V_ripcbinfo);
for (inp = LIST_FIRST(V_ripcbinfo.ipi_listhead), i = 0; inp && i < n; for (inp = LIST_FIRST(V_ripcbinfo.ipi_listhead), i = 0; inp && i < n;
@ -1085,14 +1086,9 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
} else } else
INP_RUNLOCK(inp); INP_RUNLOCK(inp);
} }
INP_INFO_WLOCK(&V_ripcbinfo); il->il_count = n;
for (i = 0; i < n; i++) { il->il_pcbinfo = &V_ripcbinfo;
inp = inp_list[i]; epoch_call(net_epoch_preempt, &il->il_epoch_ctx, in_pcblist_rele_rlocked);
INP_RLOCK(inp);
if (!in_pcbrele_rlocked(inp))
INP_RUNLOCK(inp);
}
INP_INFO_WUNLOCK(&V_ripcbinfo);
if (!error) { if (!error) {
/* /*
@ -1108,7 +1104,6 @@ rip_pcblist(SYSCTL_HANDLER_ARGS)
INP_INFO_RUNLOCK(&V_ripcbinfo); INP_INFO_RUNLOCK(&V_ripcbinfo);
error = SYSCTL_OUT(req, &xig, sizeof xig); error = SYSCTL_OUT(req, &xig, sizeof xig);
} }
free(inp_list, M_TEMP);
return (error); return (error);
} }

View File

@ -943,6 +943,7 @@ deregister_tcp_functions(struct tcp_function_block *blk, bool quiesce,
rw_wunlock(&tcp_function_lock); rw_wunlock(&tcp_function_lock);
VNET_LIST_RLOCK(); VNET_LIST_RLOCK();
/* XXX handle */
VNET_FOREACH(vnet_iter) { VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter); CURVNET_SET(vnet_iter);
INP_INFO_WLOCK(&V_tcbinfo); INP_INFO_WLOCK(&V_tcbinfo);
@ -1732,6 +1733,7 @@ tcp_ccalgounload(struct cc_algo *unload_algo)
tmpalgo = CC_ALGO(tp); tmpalgo = CC_ALGO(tp);
/* NewReno does not require any init. */ /* NewReno does not require any init. */
CC_ALGO(tp) = &newreno_cc_algo; CC_ALGO(tp) = &newreno_cc_algo;
/* XXX defer to epoch_call */
if (tmpalgo->cb_destroy != NULL) if (tmpalgo->cb_destroy != NULL)
tmpalgo->cb_destroy(tp->ccv); tmpalgo->cb_destroy(tp->ccv);
} }
@ -2102,6 +2104,7 @@ static int
tcp_pcblist(SYSCTL_HANDLER_ARGS) tcp_pcblist(SYSCTL_HANDLER_ARGS)
{ {
int error, i, m, n, pcb_count; int error, i, m, n, pcb_count;
struct in_pcblist *il;
struct inpcb *inp, **inp_list; struct inpcb *inp, **inp_list;
inp_gen_t gencnt; inp_gen_t gencnt;
struct xinpgen xig; struct xinpgen xig;
@ -2148,7 +2151,8 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
if (error) if (error)
return (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); INP_INFO_WLOCK(&V_tcbinfo);
for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0; for (inp = LIST_FIRST(V_tcbinfo.ipi_listhead), i = 0;
@ -2191,14 +2195,10 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
} else } else
INP_RUNLOCK(inp); INP_RUNLOCK(inp);
} }
INP_INFO_RLOCK(&V_tcbinfo);
for (i = 0; i < n; i++) { il->il_count = n;
inp = inp_list[i]; il->il_pcbinfo = &V_tcbinfo;
INP_RLOCK(inp); epoch_call(net_epoch_preempt, &il->il_epoch_ctx, in_pcblist_rele_rlocked);
if (!in_pcbrele_rlocked(inp))
INP_RUNLOCK(inp);
}
INP_INFO_RUNLOCK(&V_tcbinfo);
if (!error) { if (!error) {
/* /*
@ -2215,7 +2215,6 @@ tcp_pcblist(SYSCTL_HANDLER_ARGS)
INP_LIST_RUNLOCK(&V_tcbinfo); INP_LIST_RUNLOCK(&V_tcbinfo);
error = SYSCTL_OUT(req, &xig, sizeof xig); error = SYSCTL_OUT(req, &xig, sizeof xig);
} }
free(inp_list, M_TEMP);
return (error); return (error);
} }

View File

@ -836,6 +836,7 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
{ {
int error, i, n; int error, i, n;
struct inpcb *inp, **inp_list; struct inpcb *inp, **inp_list;
struct in_pcblist *il;
inp_gen_t gencnt; inp_gen_t gencnt;
struct xinpgen xig; struct xinpgen xig;
@ -873,10 +874,8 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
error = SYSCTL_OUT(req, &xig, sizeof xig); error = SYSCTL_OUT(req, &xig, sizeof xig);
if (error) if (error)
return (error); return (error);
il = malloc(sizeof(struct in_pcblist) + n * sizeof(struct inpcb *), M_TEMP, M_WAITOK|M_ZERO);
inp_list = malloc(n * sizeof *inp_list, M_TEMP, M_WAITOK); inp_list = il->il_inp_list;
if (inp_list == NULL)
return (ENOMEM);
INP_INFO_RLOCK(&V_udbinfo); INP_INFO_RLOCK(&V_udbinfo);
for (inp = LIST_FIRST(V_udbinfo.ipi_listhead), i = 0; inp && i < n; for (inp = LIST_FIRST(V_udbinfo.ipi_listhead), i = 0; inp && i < n;
@ -905,14 +904,9 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
} else } else
INP_RUNLOCK(inp); INP_RUNLOCK(inp);
} }
INP_INFO_WLOCK(&V_udbinfo); il->il_count = n;
for (i = 0; i < n; i++) { il->il_pcbinfo = &V_udbinfo;
inp = inp_list[i]; epoch_call(net_epoch_preempt, &il->il_epoch_ctx, in_pcblist_rele_rlocked);
INP_RLOCK(inp);
if (!in_pcbrele_rlocked(inp))
INP_RUNLOCK(inp);
}
INP_INFO_WUNLOCK(&V_udbinfo);
if (!error) { if (!error) {
/* /*
@ -928,7 +922,6 @@ udp_pcblist(SYSCTL_HANDLER_ARGS)
INP_INFO_RUNLOCK(&V_udbinfo); INP_INFO_RUNLOCK(&V_udbinfo);
error = SYSCTL_OUT(req, &xig, sizeof xig); error = SYSCTL_OUT(req, &xig, sizeof xig);
} }
free(inp_list, M_TEMP);
return (error); return (error);
} }
@ -1717,6 +1710,7 @@ udp_detach(struct socket *so)
INP_WLOCK(inp); INP_WLOCK(inp);
up = intoudpcb(inp); up = intoudpcb(inp);
KASSERT(up != NULL, ("%s: up == NULL", __func__)); KASSERT(up != NULL, ("%s: up == NULL", __func__));
/* XXX defer to epoch_call */
inp->inp_ppcb = NULL; inp->inp_ppcb = NULL;
in_pcbdetach(inp); in_pcbdetach(inp);
in_pcbfree(inp); in_pcbfree(inp);