4.16-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Ka-Cheong Poon <ka-cheong.p...@oracle.com>


[ Upstream commit a43cced9a348901f9015f4730b70b69e7c41a9c9 ]

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.p...@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilim...@oracle.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>
---
 net/rds/send.c |   15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

--- 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
@@ -997,10 +997,15 @@ static int rds_send_mprds_hash(struct rd
        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;
        }


Reply via email to