rds: block ints when acquiring c_lock in rds_conn_message_info()
authorZach Brown <zach.brown@oracle.com>
Fri, 4 Jun 2010 21:25:27 +0000 (14:25 -0700)
committerAndy Grover <andy.grover@oracle.com>
Thu, 9 Sep 2010 01:15:26 +0000 (18:15 -0700)
conn->c_lock is acquired in interrupt context.  rds_conn_message_info() is
called from user context and was acquiring c_lock without blocking interrupts,
leading to possible deadlocks.

Signed-off-by: Zach Brown <zach.brown@oracle.com>
net/rds/connection.c

index 5bd96d538fb9e1ddaa4321b50ceb67d4a03a4c50..5bb0eec5ada3ee8e3c6bab3bf73298e6a0067584 100644 (file)
@@ -375,6 +375,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len,
        struct rds_connection *conn;
        struct rds_message *rm;
        unsigned int total = 0;
+       unsigned long flags;
        size_t i;
 
        len /= sizeof(struct rds_info_message);
@@ -389,7 +390,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len,
                        else
                                list = &conn->c_retrans;
 
-                       spin_lock(&conn->c_lock);
+                       spin_lock_irqsave(&conn->c_lock, flags);
 
                        /* XXX too lazy to maintain counts.. */
                        list_for_each_entry(rm, list, m_conn_item) {
@@ -400,7 +401,7 @@ static void rds_conn_message_info(struct socket *sock, unsigned int len,
                                                          conn->c_faddr, 0);
                        }
 
-                       spin_unlock(&conn->c_lock);
+                       spin_unlock_irqrestore(&conn->c_lock, flags);
                }
        }
        rcu_read_unlock();