Date: Sun, 4 Nov 2007 22:44:07 GMT From: Kip Macy <kmacy@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 128646 for review Message-ID: <200711042244.lA4Mi7RY084065@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=128646 Change 128646 by kmacy@kmacy:storage:toestack on 2007/11/04 22:43:20 add initial hooks for listen offload add support code for reset Affected files ... .. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#13 edit .. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_defs.h#4 edit .. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_listen.c#2 edit .. //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_tom.c#5 edit Differences ... ==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_cpl_io.c#13 (text+ko) ==== @@ -132,6 +132,8 @@ extern int tcp_autorcvbuf_max; extern int tcp_autosndbuf_max; +static void t3_send_reset(struct socket *so); + static inline unsigned int mkprio(unsigned int cntrl, const struct socket *so) { @@ -427,14 +429,16 @@ so = tp->t_inpcb->inp_socket; close_conn(so); - return (0); } static int cxgb_toe_abort(struct tcpcb *tp) { - printf("%s UNIMPLEMENTED!!!!\n", __FUNCTION__); + struct socket *so; + + so = tp->t_inpcb->inp_socket; + t3_send_reset(so); return (0); } @@ -451,20 +455,6 @@ } static int -cxgb_toe_listen_start(struct tcpcb *tp) -{ - printf("%s UNIMPLEMENTED!!!!\n", __FUNCTION__); - return (0); -} - -static int -cxgb_toe_listen_stop(struct tcpcb *tp) -{ - printf("%s UNIMPLEMENTED!!!!\n", __FUNCTION__); - return (0); -} - -static int cxgb_toe_rcvd(struct tcpcb *tp) { t3_cleanup_rbuf(tp); @@ -476,8 +466,6 @@ .tu_disconnect = cxgb_toe_disconnect, .tu_abort = cxgb_toe_abort, .tu_send = cxgb_toe_send, - .tu_listen_start = cxgb_toe_listen_start, - .tu_listen_stop = cxgb_toe_listen_stop, .tu_rcvd = cxgb_toe_rcvd, }; @@ -954,6 +942,57 @@ } /* + * Send an ABORT_REQ message. Cannot fail. This routine makes sure we do + * not send multiple ABORT_REQs for the same connection and also that we do + * not try to send a message after the connection has closed. Returns 1 if + * an ABORT_REQ wasn't generated after all, 0 otherwise. + */ +static void +t3_send_reset(struct socket *so) +{ + printf("t3_send_reset unimplemented\n"); + +#ifdef notyet + struct cpl_abort_req *req; + struct tcp_sock *tp = tcp_sk(sk); + unsigned int tid = TID(tp); + int mode = CPL_ABORT_SEND_RST; + + if (unlikely(sock_flag(sk, ABORT_SHUTDOWN) || !TOE_DEV(sk))) { + if (skb) + __kfree_skb(skb); + return 1; + } + + sock_set_flag(sk, ABORT_RPL_PENDING); + sock_set_flag(sk, ABORT_SHUTDOWN); + + /* Purge the send queue so we don't send anything after an abort. */ + t3_purge_write_queue(sk); + + if (sock_flag(sk, CLOSE_CON_REQUESTED) && is_t3a(TOE_DEV(sk))) + mode |= CPL_ABORT_POST_CLOSE_REQ; + + if (!skb) + skb = alloc_skb_nofail(sizeof(*req)); + skb->priority = mkprio(CPL_PRIORITY_DATA, sk); + set_arp_failure_handler(skb, abort_arp_failure); + + req = (struct cpl_abort_req *)skb_put(skb, sizeof(*req)); + req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_OFLD_HOST_ABORT_CON_REQ)); + req->wr.wr_lo = htonl(V_WR_TID(tid)); + OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_ABORT_REQ, tid)); + req->rsvd0 = htonl(tp->snd_nxt); + req->rsvd1 = !sock_flag(sk, TX_DATA_SENT); + req->cmd = mode; + if (sk->sk_state == TCP_SYN_SENT) + __skb_queue_tail(&tp->out_of_order_queue, skb); // defer + else + l2t_send(T3C_DEV(sk), skb, L2T_ENTRY(sk)); +#endif +} + +/* * Process new data received for a connection. */ static void ==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_defs.h#4 (text+ko) ==== @@ -6,14 +6,16 @@ #define toeptoso(toep) ((toep)->tp_tp->t_inpcb->inp_socket) #define sototoep(so) (sototcpcb((so))->t_toe) +void t3tom_register_cpl_handler(unsigned int opcode, cxgb_cpl_handler_func h); +void t3_listen_start(struct toedev *dev, struct socket *so, struct t3cdev *cdev); +void t3_listen_stop(struct toedev *dev, struct socket *so, struct t3cdev *cdev); +int t3_push_frames(struct socket *so, int req_completion); void t3_enable_ddp(struct socket *so, int on); int t3_connect(struct toedev *tdev, struct socket *so, struct ifnet *egress_ifp); void t3_init_listen_cpl_handlers(void); int t3_init_cpl_io(void); -void t3tom_register_cpl_handler(unsigned int opcode, cxgb_cpl_handler_func h); void t3_init_offload_ops(void); void t3_init_wr_tab(unsigned int wr_len); -int t3_push_frames(struct socket *so, int req_completion); uint32_t t3_send_rx_credits(struct tcpcb *tp, uint32_t credits, uint32_t dack, int nofail); void t3_cleanup_rbuf(struct tcpcb *tp); ==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_listen.c#2 (text+ko) ==== @@ -1,6 +1,3 @@ - - - /************************************************************************** Copyright (c) 2007, Chelsio Inc. @@ -42,6 +39,7 @@ #include <sys/mutex.h> #include <sys/socket.h> #include <sys/socketvar.h> +#include <sys/syslog.h> #include <net/if.h> #include <net/route.h> @@ -98,3 +96,112 @@ t3tom_register_cpl_handler(CPL_PASS_OPEN_RPL, do_pass_open_rpl); t3tom_register_cpl_handler(CPL_CLOSE_LISTSRV_RPL, do_close_server_rpl); } + + +/* + * Start a listening server by sending a passive open request to HW. + */ +void +t3_listen_start(struct toedev *dev, struct socket *so, struct t3cdev *cdev) +{ + printf("start listen\n"); +#if 0 + int stid; + struct sk_buff *skb; + struct cpl_pass_open_req *req; + struct tom_data *d = TOM_DATA(dev); + struct listen_ctx *ctx; + + if (!TOM_TUNABLE(dev, activated)) + return; + + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (!ctx) + return; + + ctx->tom_data = d; + ctx->lsk = sk; + + stid = cxgb3_alloc_stid(d->cdev, d->client, ctx); + if (stid < 0) + goto free_ctx; + + sock_hold(sk); + + skb = alloc_skb(sizeof(*req), GFP_KERNEL); + if (!skb) + goto free_stid; + + if (!listen_hash_add(d, sk, stid)) + goto free_all; + + req = (struct cpl_pass_open_req *)__skb_put(skb, sizeof(*req)); + req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); + OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_PASS_OPEN_REQ, stid)); +#ifdef LINUX_2_4 + req->local_port = sk->sport; + req->local_ip = sk->rcv_saddr; +#else + req->local_port = inet_sk(sk)->sport; + req->local_ip = inet_sk(sk)->rcv_saddr; +#endif /* LINUX_2_4 */ + req->peer_port = 0; + req->peer_ip = 0; + req->peer_netmask = 0; + req->opt0h = htonl(F_DELACK | F_TCAM_BYPASS); + req->opt0l = htonl(V_RCV_BUFSIZ(16)); + req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); + + skb->priority = CPL_PRIORITY_LISTEN; + cxgb3_ofld_send(cdev, skb); + return; + +free_all: + __kfree_skb(skb); +free_stid: + cxgb3_free_stid(cdev, stid); + sock_put(sk); +free_ctx: + kfree(ctx); +#endif +} + +/* + * Stop a listening server by sending a close_listsvr request to HW. + * The server TID is freed when we get the reply. + */ +void +t3_listen_stop(struct toedev *dev, struct socket *so, struct t3cdev *cdev) +{ + printf("stop listen\n"); +#if 0 + struct sk_buff *skb; + struct cpl_close_listserv_req *req; + + int stid = listen_hash_del(TOM_DATA(dev), sk); + if (stid < 0) + return; + + /* + * Do this early so embryonic connections are marked as being aborted + * while the stid is still open. This ensures pass_establish messages + * that arrive while we are closing the server will be able to locate + * the listening socket. + */ + t3_reset_synq(sk); + + /* Send the close ASAP to stop further passive opens */ + skb = alloc_skb_nofail(sizeof(*req)); + req = (struct cpl_close_listserv_req *)__skb_put(skb, sizeof(*req)); + req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); + OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, stid)); + req->cpu_idx = 0; + skb->priority = CPL_PRIORITY_LISTEN; + cxgb3_ofld_send(cdev, skb); + + t3_disconnect_acceptq(sk); +#endif +} + + + ==== //depot/projects/toestack/sys/dev/cxgb/ulp/tom/cxgb_tom.c#5 (text+ko) ==== @@ -37,6 +37,7 @@ #include <sys/linux_compat.h> #include <sys/limits.h> #include <sys/lock.h> +#include <sys/eventhandler.h> #include <sys/mbuf.h> #include <sys/module.h> #include <sys/mutex.h> @@ -56,8 +57,10 @@ #include <dev/cxgb/cxgb_osdep.h> #include <dev/cxgb/sys/mbufq.h> +#include <netinet/in_pcb.h> #include <netinet/tcp.h> #include <netinet/tcp_var.h> +#include <netinet/tcp_ofld.h> #include <netinet/tcp_fsm.h> #include <net/route.h> @@ -89,11 +92,7 @@ */ static cxgb_cpl_handler_func tom_cpl_handlers[NUM_CPL_CMDS]; -#ifdef notyet -static struct notifier_block listen_notifier = { - .notifier_call = listen_notify_handler -}; -#endif +static eventhandler_tag listen_tag; static struct offload_id t3_toe_id_tab[] = { { TOE_ID_CHELSIO_T3, 0 }, @@ -346,16 +345,51 @@ return (0); } +static void +cxgb_toe_listen(void *unused, int event, struct tcpcb *tp) +{ + struct socket *so = tp->t_inpcb->inp_socket; + struct tom_data *p; + + switch (event) { + case OFLD_LISTEN_OPEN: + case OFLD_LISTEN_CLOSE: + mtx_lock(&cxgb_list_lock); + TAILQ_FOREACH(p, &cxgb_list, entry) { + if (event == OFLD_LISTEN_OPEN) + t3_listen_start(&p->tdev, so, p->cdev); + else + t3_listen_stop(&p->tdev, so, p->cdev); + } + mtx_unlock(&cxgb_list_lock); + break; + default: + log(LOG_ERR, "unrecognized listen event %d\n", event); + break; + } +} + +static void +cxgb_register_listeners(void) +{ + struct inpcb *inp; + struct tcpcb *tp; + + INP_INFO_RLOCK(&tcbinfo); + LIST_FOREACH(inp, tcbinfo.ipi_listhead, inp_list) { + tp = intotcpcb(inp); + + if (tp->t_state == TCPS_LISTEN) + cxgb_toe_listen(NULL, OFLD_LISTEN_OPEN, tp); + } + INP_INFO_RUNLOCK(&tcbinfo); +} + static int t3_tom_init(void) { #if 0 -#ifdef CONFIG_CHELSIO_T3_OFFLOAD_MODULE - err = prepare_tom_for_offload(); - if (err) - return err; -#endif struct socket *sock; err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); if (err < 0) { @@ -380,20 +414,18 @@ "Unable to register Chelsio T3 TCP offload module.\n"); return -1; } -#ifdef notyet - register_listen_offload_notifier(&listen_notifier); -#endif + + mtx_init(&cxgb_list_lock, "cxgb tom list", NULL, MTX_DEF); + listen_tag = EVENTHANDLER_REGISTER(ofld_listen, cxgb_toe_listen, NULL, EVENTHANDLER_PRI_ANY); TAILQ_INIT(&cxgb_list); - mtx_init(&cxgb_list_lock, "cxgb tom list", NULL, MTX_DEF); /* Register to offloading devices */ t3c_tom_client.add = t3c_tom_add; cxgb_register_client(&t3c_tom_client); - - return 0; + cxgb_register_listeners(); + return (0); } - static int t3_tom_load(module_t mod, int cmd, void *arg) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200711042244.lA4Mi7RY084065>