Skip site navigation (1)Skip section navigation (2)
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>