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

svn-commits@oss.oracle.com svn-commits at oss.oracle.com
Thu May 25 19:31:39 CDT 2006


Author: zab
Date: 2006-05-25 19:31:37 -0500 (Thu, 25 May 2006)
New Revision: 78

Modified:
   trunk/linux/net/rds/flow.c
   trunk/linux/net/rds/rds.h
   trunk/linux/net/rds/recv.c
Log:
Don't deref null flow in rx path.

The recv path was trying to get the transport function pointers via the
flow to queue an ack at times when the flow could be null.  We introduce
a helper to queue the acks that uses the inc pointer which will always
be safe.


Modified: trunk/linux/net/rds/flow.c
===================================================================
--- trunk/linux/net/rds/flow.c	2006-05-25 23:38:46 UTC (rev 77)
+++ trunk/linux/net/rds/flow.c	2006-05-26 00:31:37 UTC (rev 78)
@@ -171,8 +171,7 @@
 	pr_debug("put flow %p ref %d\n", flow, atomic_read(&flow->f_refcount));
 	if (atomic_dec_and_test(&flow->f_refcount)) {
 		if (flow->f_inc) {
-			flow->f_conn->c_trans->ack_queue_inc(flow->f_inc,
-							     GFP_ATOMIC);
+			rds_inc_ack(flow->f_inc, GFP_ATOMIC);
 			rds_inc_put(flow->f_inc);
 		}
 		if (flow->f_rs)

Modified: trunk/linux/net/rds/rds.h
===================================================================
--- trunk/linux/net/rds/rds.h	2006-05-25 23:38:46 UTC (rev 77)
+++ trunk/linux/net/rds/rds.h	2006-05-26 00:31:37 UTC (rev 78)
@@ -237,6 +237,7 @@
 void rds_inc_init(struct rds_incoming *inc, struct rds_connection *conn);
 void rds_inc_addref(struct rds_incoming *inc);
 void rds_inc_put(struct rds_incoming *inc);
+void rds_inc_ack(struct rds_incoming *inc, gfp_t gfp);
 int rds_recv_incoming(struct rds_connection *conn, struct rds_incoming *inc,
 		      gfp_t gfp);
 void rds_recv_enqueue(struct rds_flow *caller_flow, __be32 saddr, __be32 daddr,

Modified: trunk/linux/net/rds/recv.c
===================================================================
--- trunk/linux/net/rds/recv.c	2006-05-25 23:38:46 UTC (rev 77)
+++ trunk/linux/net/rds/recv.c	2006-05-26 00:31:37 UTC (rev 78)
@@ -47,6 +47,15 @@
 }
 
 /*
+ * This little helper is sure to get the trans ref via a safe path since we
+ * know we have the inc when we want to ack it.
+ */
+void rds_inc_ack(struct rds_incoming *inc, gfp_t gfp)
+{
+	inc->i_conn->c_trans->ack_queue_inc(inc, gfp);
+}
+
+/*
  * This is called when a transport has a full message accumulated in
  * 'inc'.  This can happen on behalf of the transport in rds_recv_incoming()
  * as it reassembles.  Transports, like loopback, call this directly when
@@ -87,7 +96,7 @@
 	if (flow != caller_flow)
 		rds_flow_put(flow);
 	if (inc)
-		inc->i_conn->c_trans->ack_queue_inc(inc, gfp);
+		rds_inc_ack(inc, gfp);
 }
 
 /*
@@ -206,7 +215,7 @@
 
 out:
 	if (ack)
-		flow->f_conn->c_trans->ack_queue_inc(inc, gfp);
+		rds_inc_ack(inc, gfp);
 	if (flow)
 		rds_flow_put(flow);
 	return ret;
@@ -253,7 +262,7 @@
 	write_unlock_irqrestore(&sk->sk_callback_lock, flags);
 
 	if (ret && drop)
-		inc->i_conn->c_trans->ack_queue_inc(inc, GFP_KERNEL);
+		rds_inc_ack(inc, GFP_KERNEL);
 
 	pr_debug("inc %p rs %p still %d dropped %d\n", inc, rs, ret, drop);
 	return ret;
@@ -347,7 +356,7 @@
 
 	list_for_each_entry_safe(inc, tmp, &rs->rs_recv_queue, i_item) {
 		list_del_init(&inc->i_item);
-		inc->i_conn->c_trans->ack_queue_inc(inc, GFP_KERNEL);
+		rds_inc_ack(inc, GFP_KERNEL);
 		rds_inc_put(inc);
 	}
 }




More information about the Rds-commits mailing list