PERFORCE change 128646 for review
Kip Macy
kmacy at FreeBSD.org
Sun Nov 4 14:44:08 PST 2007
http://perforce.freebsd.org/chv.cgi?CH=128646
Change 128646 by kmacy at 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)
{
More information about the p4-projects
mailing list