diff mbox series

[net] rds: MP-RDS may use an invalid c_path

Message ID 1523433445-7596-1-git-send-email-ka-cheong.poon@oracle.com
State Accepted, archived
Delegated to: David Miller
Headers show
Series [net] rds: MP-RDS may use an invalid c_path | expand

Commit Message

Ka-Cheong Poon April 11, 2018, 7:57 a.m. UTC
rds_sendmsg() calls rds_send_mprds_hash() to find a c_path to use to
send a message.  Suppose the RDS connection is not yet up.  In
rds_send_mprds_hash(), it does

	if (conn->c_npaths == 0)
		wait_event_interruptible(conn->c_hs_waitq,
					 (conn->c_npaths != 0));

If it is interrupted before the connection is set up,
rds_send_mprds_hash() will return a non-zero hash value.  Hence
rds_sendmsg() will use a non-zero c_path to send the message.  But if
the RDS connection ends up to be non-MP capable, the message will be
lost as only the zero c_path can be used.

Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
---
 net/rds/send.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

Comments

Santosh Shilimkar April 11, 2018, 2 p.m. UTC | #1
On 4/11/18 12:57 AM, Ka-Cheong Poon wrote:
> rds_sendmsg() calls rds_send_mprds_hash() to find a c_path to use to
> send a message.  Suppose the RDS connection is not yet up.  In
> rds_send_mprds_hash(), it does
> 
> 	if (conn->c_npaths == 0)
> 		wait_event_interruptible(conn->c_hs_waitq,
> 					 (conn->c_npaths != 0));
> 
> If it is interrupted before the connection is set up,
> rds_send_mprds_hash() will return a non-zero hash value.  Hence
> rds_sendmsg() will use a non-zero c_path to send the message.  But if
> the RDS connection ends up to be non-MP capable, the message will be
> lost as only the zero c_path can be used.
> 
> Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
> ---
Thanks for posting the fix upstream as well.

Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
David Miller April 11, 2018, 2:24 p.m. UTC | #2
From: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
Date: Wed, 11 Apr 2018 00:57:25 -0700

> rds_sendmsg() calls rds_send_mprds_hash() to find a c_path to use to
> send a message.  Suppose the RDS connection is not yet up.  In
> rds_send_mprds_hash(), it does
> 
> 	if (conn->c_npaths == 0)
> 		wait_event_interruptible(conn->c_hs_waitq,
> 					 (conn->c_npaths != 0));
> 
> If it is interrupted before the connection is set up,
> rds_send_mprds_hash() will return a non-zero hash value.  Hence
> rds_sendmsg() will use a non-zero c_path to send the message.  But if
> the RDS connection ends up to be non-MP capable, the message will be
> lost as only the zero c_path can be used.
> 
> Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>

Applied and queued up for -stable, thanks.
diff mbox series

Patch

diff --git a/net/rds/send.c b/net/rds/send.c
index acad042..94c7f74 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -1,5 +1,5 @@ 
 /*
- * Copyright (c) 2006 Oracle.  All rights reserved.
+ * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved.
  *
  * This software is available to you under a choice of one of two
  * licenses.  You may choose to be licensed under the terms of the GNU
@@ -1017,10 +1017,15 @@  static int rds_send_mprds_hash(struct rds_sock *rs, struct rds_connection *conn)
 	if (conn->c_npaths == 0 && hash != 0) {
 		rds_send_ping(conn, 0);
 
-		if (conn->c_npaths == 0) {
-			wait_event_interruptible(conn->c_hs_waitq,
-						 (conn->c_npaths != 0));
-		}
+		/* The underlying connection is not up yet.  Need to wait
+		 * until it is up to be sure that the non-zero c_path can be
+		 * used.  But if we are interrupted, we have to use the zero
+		 * c_path in case the connection ends up being non-MP capable.
+		 */
+		if (conn->c_npaths == 0)
+			if (wait_event_interruptible(conn->c_hs_waitq,
+						     conn->c_npaths != 0))
+				hash = 0;
 		if (conn->c_npaths == 1)
 			hash = 0;
 	}