From 03fb1cae8bbe1b9a309649e56fbb286e2022fe1c Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sat, 20 Dec 2008 11:13:45 +0800 Subject: [PATCH] Explicitly reallocate the inpcb cached route freed due to different rtentry CPU ownership, e.g. in tcp_connect(), so we could make sure that a RTF_PRCLONING rtentry will be cloned. --- sys/netinet/tcp_usrreq.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 1acefbc184..92e6376f6e 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -903,6 +903,7 @@ tcp_connect_oncpu(struct tcpcb *tp, struct sockaddr_in *sin, { struct inpcb *inp = tp->t_inpcb, *oinp; struct socket *so = inp->inp_socket; + struct route *ro = &inp->inp_route; struct tcpcb *otp; struct rmxp_tao *taop; struct rmxp_tao tao_noncached; @@ -928,6 +929,23 @@ tcp_connect_oncpu(struct tcpcb *tp, struct sockaddr_in *sin, inp->inp_cpcbinfo = &tcbinfo[mycpu->gd_cpuid]; in_pcbinsconnhash(inp); + /* + * We are now on the inpcb's owner CPU, if the cached route was + * freed because the rtentry's owner CPU is not the current CPU + * (e.g. in tcp_connect()), then we try to reallocate it here with + * the hope that a rtentry may be cloned from a RTF_PRCLONING + * rtentry. + */ + if (!(inp->inp_socket->so_options & SO_DONTROUTE) && /*XXX*/ + ro->ro_rt == NULL) { + bzero(&ro->ro_dst, sizeof(struct sockaddr_in)); + ro->ro_dst.sa_family = AF_INET; + ro->ro_dst.sa_len = sizeof(struct sockaddr_in); + ((struct sockaddr_in *)&ro->ro_dst)->sin_addr = + sin->sin_addr; + rtalloc(ro); + } + tcp_create_timermsg(tp); /* Compute window scaling to request. */ @@ -1033,7 +1051,7 @@ tcp_connect(struct tcpcb *tp, struct sockaddr *nam, struct thread *td) /* * in_pcbladdr() may have allocated a route entry for us * on the current CPU, but we need a route entry on the - * target CPU, so free it here. + * inpcb's owner CPU, so free it here. */ if (ro->ro_rt != NULL) RTFREE(ro->ro_rt); -- 2.41.0