Date: Sat, 26 May 2012 01:24:39 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r236034 - user/np/toe_iwarp/sys/netinet Message-ID: <201205260124.q4Q1Odc0044230@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Sat May 26 01:24:39 2012 New Revision: 236034 URL: http://svn.freebsd.org/changeset/base/236034 Log: Provide an opportunity to a TOE driver to install its hooks when expanding a syncache entry into a full socket. A couple of functions in toecore: * toe_connect_failed: to be called when an active open using a TOE device fails. * toe_4tuple_check: to check whether a 4-tuple is currently in use, and maybe release it if it's in TIME_WAIT and we have an incoming SYN for the 4-tuple. Modified: user/np/toe_iwarp/sys/netinet/tcp_syncache.c user/np/toe_iwarp/sys/netinet/toecore.c user/np/toe_iwarp/sys/netinet/toecore.h Modified: user/np/toe_iwarp/sys/netinet/tcp_syncache.c ============================================================================== --- user/np/toe_iwarp/sys/netinet/tcp_syncache.c Sat May 26 00:59:43 2012 (r236033) +++ user/np/toe_iwarp/sys/netinet/tcp_syncache.c Sat May 26 01:24:39 2012 (r236034) @@ -858,6 +858,18 @@ syncache_socket(struct syncache *sc, str if (sc->sc_rxmits > 1) tp->snd_cwnd = tp->t_maxseg; +#ifdef TCP_OFFLOAD + /* + * Allow a TOE driver to install its hooks. Note that we hold the + * pcbinfo lock too and that prevents tcp_usr_accept from accepting a + * new connection before the TOE driver has done its thing. + */ + if (ADDED_BY_TOE(sc)) { + struct toedev *tod = sc->sc_tod; + + tod->tod_offload_socket(tod, sc->sc_todctx, so); + } +#endif /* * Copy and activate timers. */ Modified: user/np/toe_iwarp/sys/netinet/toecore.c ============================================================================== --- user/np/toe_iwarp/sys/netinet/toecore.c Sat May 26 00:59:43 2012 (r236033) +++ user/np/toe_iwarp/sys/netinet/toecore.c Sat May 26 01:24:39 2012 (r236034) @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #define TCPSTATES #include <netinet/tcp.h> #include <netinet/tcp_fsm.h> +#include <netinet/tcp_timer.h> #include <netinet/tcp_var.h> #include <netinet/tcp_syncache.h> #include <netinet/tcp_offload.h> @@ -154,6 +155,14 @@ toedev_syncache_respond(struct toedev *t } static void +toedev_offload_socket(struct toedev *tod __unused, void *ctx __unused, + struct socket *so __unused) +{ + + return; +} + +static void toedev_ctloutput(struct toedev *tod __unused, struct tcpcb *tp __unused, int sopt_dir __unused, int sopt_name __unused) { @@ -247,6 +256,7 @@ init_toedev(struct toedev *tod) tod->tod_syncache_added = toedev_syncache_added; tod->tod_syncache_removed = toedev_syncache_removed; tod->tod_syncache_respond = toedev_syncache_respond; + tod->tod_offload_socket = toedev_offload_socket; tod->tod_ctloutput = toedev_ctloutput; } @@ -324,6 +334,41 @@ toe_syncache_expand(struct in_conninfo * return (syncache_expand(inc, to, th, lsop, NULL)); } +/* + * General purpose check to see if a 4-tuple is in use by the kernel. If a TCP + * header (presumably for an incoming SYN) is also provided, an existing 4-tuple + * in TIME_WAIT may be assassinated freeing it up for re-use. + * + * Note that the TCP header must have been run through tcp_fields_to_host() or + * equivalent. + */ +int +toe_4tuple_check(struct in_conninfo *inc, struct tcphdr *th, struct ifnet *ifp) +{ + struct inpcb *inp; + + if (inc->inc_flags & INC_ISIPV6) + return (ENOSYS); /* XXX: implement */ + + inp = in_pcblookup(&V_tcbinfo, inc->inc_faddr, inc->inc_fport, + inc->inc_laddr, inc->inc_lport, INPLOOKUP_WLOCKPCB, ifp); + if (inp != NULL) { + INP_WLOCK_ASSERT(inp); + + if ((inp->inp_flags & INP_TIMEWAIT) && th != NULL) { + + INP_INFO_WLOCK_ASSERT(&V_tcbinfo); /* for twcheck */ + if (!tcp_twcheck(inp, NULL, th, NULL, 0)) + return (EADDRINUSE); + } else { + INP_WUNLOCK(inp); + return (EADDRINUSE); + } + } + + return (0); +} + static void toe_lle_event(void *arg __unused, struct llentry *lle, int evt) { @@ -417,6 +462,41 @@ toe_l2_resolve(struct toedev *tod, struc return (rc); } +void +toe_connect_failed(struct toedev *tod, struct tcpcb *tp, int err) +{ + struct inpcb *inp = tp->t_inpcb; + + INP_WLOCK_ASSERT(inp); + KASSERT(tp->t_flags & TF_TOE, + ("%s: tp %p not offloaded.", __func__, tp)); + + if (!(inp->inp_flags & INP_DROPPED)) { + if (err == EAGAIN) { + + /* + * Temporary failure during offload, take this PCB back. + * Detach from the TOE driver and do the rest of what + * TCP's pru_connect would have done if the connection + * wasn't offloaded. + */ + + tod->tod_pcb_detach(tod, tp); + KASSERT(!(tp->t_flags & TF_TOE), + ("%s: tp %p still offloaded.", __func__, tp)); + tcp_timer_activate(tp, TT_KEEP, TP_KEEPINIT(tp)); + (void) tcp_output(tp); + } else { + + INP_INFO_WLOCK_ASSERT(&V_tcbinfo); + tp = tcp_drop(tp, err); + if (tp == NULL) + INP_WLOCK(inp); /* re-acquire */ + } + } + INP_WLOCK_ASSERT(inp); +} + static int toecore_load(void) { Modified: user/np/toe_iwarp/sys/netinet/toecore.h ============================================================================== --- user/np/toe_iwarp/sys/netinet/toecore.h Sat May 26 00:59:43 2012 (r236033) +++ user/np/toe_iwarp/sys/netinet/toecore.h Sat May 26 01:24:39 2012 (r236034) @@ -80,6 +80,7 @@ struct toedev { void (*tod_syncache_added)(struct toedev *, void *); void (*tod_syncache_removed)(struct toedev *, void *); int (*tod_syncache_respond)(struct toedev *, void *, struct mbuf *); + void (*tod_offload_socket)(struct toedev *, void *, struct socket *); /* TCP socket option */ void (*tod_ctloutput)(struct toedev *, struct tcpcb *, int, int); @@ -105,8 +106,12 @@ int unregister_toedev(struct toedev *); int toe_l2_resolve(struct toedev *, struct ifnet *, struct sockaddr *, uint8_t *, uint16_t *); +void toe_connect_failed(struct toedev *, struct tcpcb *, int); + void toe_syncache_add(struct in_conninfo *, struct tcpopt *, struct tcphdr *, struct inpcb *, void *, void *); int toe_syncache_expand(struct in_conninfo *, struct tcpopt *, struct tcphdr *, struct socket **); + +int toe_4tuple_check(struct in_conninfo *, struct tcphdr *, struct ifnet *); #endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201205260124.q4Q1Odc0044230>