[rds-commits] zab commits r84 - trunk/linux/net/rds

svn-commits@oss.oracle.com svn-commits at oss.oracle.com
Tue May 30 15:28:07 CDT 2006


Author: zab
Date: 2006-05-30 15:28:04 -0500 (Tue, 30 May 2006)
New Revision: 84

Modified:
   trunk/linux/net/rds/ack.c
   trunk/linux/net/rds/loop.c
   trunk/linux/net/rds/message.c
   trunk/linux/net/rds/rds.h
   trunk/linux/net/rds/send.c
   trunk/linux/net/rds/tcp.h
   trunk/linux/net/rds/tcp_send.c
   trunk/linux/net/rds/transport.c
Log:
Clean up ACK generation a little.

Stop using _delayed work in the ack generation path.  It adds a jiffy wait
even if 0 is given and that was slowing acks down considerably.

Add a FASTACK flag so that a sender can ask the receiver to send an
immediate ack.  The sender uses this as the send buffer starts to get
full.


Modified: trunk/linux/net/rds/ack.c
===================================================================
--- trunk/linux/net/rds/ack.c	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/ack.c	2006-05-30 20:28:04 UTC (rev 84)
@@ -109,7 +109,7 @@
 	del_timer(&conn->c_ack_timer);
 	rds_ack_fill_header(conn->c_ack_rm);
 	list_add_tail(&conn->c_ack_rm->m_conn_item, &conn->c_send_queue);
-	conn->c_trans->send_trigger(conn, 0);
+	conn->c_trans->send_trigger(conn);
 	conn->c_ack_rm = NULL;
 }
 
@@ -126,6 +126,7 @@
 	struct rds_incoming *inc, *tmp;
 	struct rds_message *rm, *my_rm = NULL;
 	unsigned long flags;
+	int fastpending = 0;
 retry:
 	spin_lock_irqsave(&conn->c_lock, flags);
 
@@ -136,14 +137,15 @@
 				my_rm = rds_message_alloc_ack(gfp);
 				if (my_rm == NULL) {
 					/* XXX tunable retry? */
-					conn->c_trans->send_trigger(conn, 2);
+					conn->c_trans->send_trigger(conn);
 					goto out;
 				}
 				goto retry;
 			}
 			/*
-			 * XXX I'm not sure what the best deadline strategy
-			 * would be.. let's keep it simple and profile it.
+			 * messages that don't need a fast ack sit around
+			 * for quite a while before we get around to acking
+			 * them.
 			 */
 			conn->c_ack_deadline = jiffies + HZ/100;
 			mod_timer(&conn->c_ack_timer, conn->c_ack_deadline);
@@ -156,16 +158,19 @@
 				     inc->i_hdr.h_dport,
 				     inc->i_hdr.h_sequence);
 
-		/* send now if the message is full */
-		if (rm->m_len == RDS_FRAG_SIZE / sizeof(struct rds_ack_entry))
+		if (rm->m_len == RDS_ACKS_PER_FRAG) {
 			rds_ack_send(conn);
+			fastpending = 0;
+		} else if (inc->i_hdr.h_flags & RDS_HEAD_FLAG_FASTACK)
+			fastpending = 1;
 
 		list_del_init(&inc->i_item);
 		rds_inc_put(inc);
 
 	}
 
-	if (conn->c_ack_rm && time_after_eq(jiffies, conn->c_ack_deadline))
+	if (conn->c_ack_rm && 
+	    (fastpending || time_after_eq(jiffies, conn->c_ack_deadline)))
 		rds_ack_send(conn);
 
 	spin_unlock_irqrestore(&conn->c_lock, flags);
@@ -181,7 +186,7 @@
 void rds_ack_timer(unsigned long data)
 {
 	struct rds_connection *conn = (struct rds_connection *)data;
-	conn->c_trans->send_trigger(conn, 0);
+	conn->c_trans->send_trigger(conn);
 }
 
 /*

Modified: trunk/linux/net/rds/loop.c
===================================================================
--- trunk/linux/net/rds/loop.c	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/loop.c	2006-05-30 20:28:04 UTC (rev 84)
@@ -94,7 +94,7 @@
  * XXX worry about missing sends due to the send sem, then worry about
  * not needing sending serialization at all.
  */
-static void rds_loop_send_trigger(struct rds_connection *conn, long delay)
+static void rds_loop_send_trigger(struct rds_connection *conn)
 {
 }
 static void rds_loop_conn_notice(struct rds_connection *conn)

Modified: trunk/linux/net/rds/message.c
===================================================================
--- trunk/linux/net/rds/message.c	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/message.c	2006-05-30 20:28:04 UTC (rev 84)
@@ -62,11 +62,11 @@
 }
 
 void rds_message_populate_headers(struct rds_message *rm, __be16 sport,
-			          __be16 dport, u64 seq)
+			          __be16 dport, u64 seq, int fastack)
 {
 	struct rds_header *addr, *hdr;
 	struct page *page;
-	u8 flags = 0;
+	u8 flags = fastack ? RDS_HEAD_FLAG_FASTACK : 0;
 	u16 len;
 	u32 left = rm->m_len;
 

Modified: trunk/linux/net/rds/rds.h
===================================================================
--- trunk/linux/net/rds/rds.h	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/rds.h	2006-05-30 20:28:04 UTC (rev 84)
@@ -78,6 +78,7 @@
 #define RDS_HEAD_FLAG_ACK	1
 #define RDS_HEAD_FLAG_FRAG	2
 #define RDS_HEAD_FLAG_EOM	4
+#define RDS_HEAD_FLAG_FASTACK	8
 
 struct rds_header {
 	u8	h_flags;
@@ -88,13 +89,15 @@
 	__be64	h_sequence;
 };
 
+#define RDS_HEADERS_PER_PAGE	(PAGE_SIZE / sizeof(struct rds_header))
+
 struct rds_ack_entry {
 	__be64	e_seq;
 	__be16	e_sport;
 	__be16	e_dport;
 } __attribute__((packed));
 
-#define RDS_HEADERS_PER_PAGE	(PAGE_SIZE / sizeof(struct rds_header))
+#define RDS_ACKS_PER_FRAG	(RDS_FRAG_SIZE / sizeof(struct rds_ack_entry))
 
 struct rds_incoming {
 	atomic_t		i_refcount;
@@ -124,7 +127,7 @@
 	void (*conn_notice)(struct rds_connection *conn);
 	void (*conn_shutdown)(struct rds_connection *conn);
 	int (*send)(struct rds_connection *conn);
-	void (*send_trigger)(struct rds_connection *conn, long delay);
+	void (*send_trigger)(struct rds_connection *conn);
 	int (*inc_copy_to_user)(struct rds_incoming *inc, struct iovec *iov,
 				size_t size);
 	void (*inc_process_acks)(struct rds_connection *conn,
@@ -229,7 +232,7 @@
 					       unsigned long nr_frags,
 					       size_t total_len);
 void rds_message_populate_headers(struct rds_message *rm, __be16 sport,
-			          __be16 dport, u64 seq);
+			          __be16 dport, u64 seq, int fastack);
 int rds_message_inc_copy_to_user(struct rds_incoming *inc,
 				 struct iovec *first_iov, size_t size);
 void rds_message_inc_free(struct rds_incoming *inc);

Modified: trunk/linux/net/rds/send.c
===================================================================
--- trunk/linux/net/rds/send.c	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/send.c	2006-05-30 20:28:04 UTC (rev 84)
@@ -241,6 +241,7 @@
 			     __be16 dport, int *queued)
 {
 	unsigned long flags;
+	int fastack;
 	u32 new;
 
 	if (*queued)
@@ -252,13 +253,21 @@
 	if (new > flow->f_message_bytes && new <= flow->f_rs->rs_sndbuf) {
 		flow->f_message_bytes = new;
 
+		/* 
+		 * Ask for an immediate ack as our send buf approaches 3/4
+		 * full, being careful not to overflow
+		 */
+		fastack = (flow->f_rs->rs_sndbuf - new) <=
+			  (flow->f_rs->rs_sndbuf / 4);
+
 		list_add_tail(&rm->m_flow_item, &flow->f_message_list);
 		list_add_tail(&rm->m_conn_item, &flow->f_conn->c_send_queue);
 		rds_message_addref(rm);
 		rds_message_addref(rm); /* XXX sigh. */
 
 		rds_message_populate_headers(rm, sport, dport, 
-					     flow->f_conn->c_next_tx_seq);
+					     flow->f_conn->c_next_tx_seq,
+					     fastack);
 		flow->f_conn->c_next_tx_seq += nr_frags;
 
 		pr_debug("queued msg %p len %d, flow %p bytes %d seq %llu\n",

Modified: trunk/linux/net/rds/tcp.h
===================================================================
--- trunk/linux/net/rds/tcp.h	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/tcp.h	2006-05-30 20:28:04 UTC (rev 84)
@@ -67,7 +67,7 @@
 
 /* tcp_send.c */
 int rds_tcp_send(struct rds_connection *conn);
-void rds_tcp_send_trigger(struct rds_connection *conn, long delay);
+void rds_tcp_send_trigger(struct rds_connection *conn);
 void rds_tcp_send_worker(void *arg);
 void rds_tcp_write_space(struct sock *sk);
 

Modified: trunk/linux/net/rds/tcp_send.c
===================================================================
--- trunk/linux/net/rds/tcp_send.c	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/tcp_send.c	2006-05-30 20:28:04 UTC (rev 84)
@@ -35,11 +35,11 @@
 	set_fs(oldfs);
 }
 
-void rds_tcp_send_trigger(struct rds_connection *conn, long delay)
+void rds_tcp_send_trigger(struct rds_connection *conn)
 {
 	struct rds_tcp_connection *tc = conn->c_transport_data;
 	if (tc->t_conn)
-		queue_delayed_work(rds_tcp_wq, &tc->t_send_work, delay);
+		queue_work(rds_tcp_wq, &tc->t_send_work);
 }
 
 /*

Modified: trunk/linux/net/rds/transport.c
===================================================================
--- trunk/linux/net/rds/transport.c	2006-05-30 20:11:00 UTC (rev 83)
+++ trunk/linux/net/rds/transport.c	2006-05-30 20:28:04 UTC (rev 84)
@@ -36,7 +36,7 @@
 	 * to make sure that the callers queued send doesn't get lost.
 	 */
 	if (down_trylock(&conn->c_send_sem)) {
-		conn->c_trans->send_trigger(conn, 0);
+		conn->c_trans->send_trigger(conn);
 		return;
 	}
 
@@ -45,7 +45,7 @@
 
 	/* we have little choice but to retry if we're low on memory */
 	if (conn->c_trans->send(conn) == -ENOMEM)
-		conn->c_trans->send_trigger(conn, 2);
+		conn->c_trans->send_trigger(conn);
 
 	up(&conn->c_send_sem);
 }




More information about the rds-commits mailing list