diff options
author | Zach Brown <zach.brown@oracle.com> | 2010-06-04 14:25:27 -0700 |
---|---|---|
committer | Andy Grover <andy.grover@oracle.com> | 2010-09-08 18:15:26 -0700 |
commit | 501dcccdb7a2335cde07d4acb56e636182d62944 (patch) | |
tree | e2079f8d22c498e6c7f1fcfa326e123b4945df7b | |
parent | 671202f3491cccdb267f88ad59ba0635aeb2a22e (diff) |
rds: block ints when acquiring c_lock in rds_conn_message_info()
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>
-rw-r--r-- | net/rds/connection.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/net/rds/connection.c b/net/rds/connection.c index 5bd96d538fb..5bb0eec5ada 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -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(); |