aboutsummaryrefslogtreecommitdiffstats
path: root/net/rds
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-01-24 17:03:44 -0500
committerDavid S. Miller <davem@davemloft.net>2012-01-24 17:03:44 -0500
commitefc3dbc37412c027e363736b4f4c74ee5e8ecffc (patch)
tree958b635fa7f52456c19247e892a3d92d21a448a7 /net/rds
parent36a1211970193ce215de50ed1e4e1272bc814df1 (diff)
rds: Make rds_sock_lock BH rather than IRQ safe.
rds_sock_info() triggers locking warnings because we try to perform a local_bh_enable() (via sock_i_ino()) while hardware interrupts are disabled (via taking rds_sock_lock). There is no reason for rds_sock_lock to be a hardware IRQ disabling lock, none of these access paths run in hardware interrupt context. Therefore making it a BH disabling lock is safe and sufficient to fix this bug. Reported-by: Kumar Sanghvi <kumaras@chelsio.com> Reported-by: Josh Boyer <jwboyer@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/rds')
-rw-r--r--net/rds/af_rds.c20
1 files changed, 8 insertions, 12 deletions
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c
index bb6ad81b671d..424ff622ab5f 100644
--- a/net/rds/af_rds.c
+++ b/net/rds/af_rds.c
@@ -68,7 +68,6 @@ static int rds_release(struct socket *sock)
68{ 68{
69 struct sock *sk = sock->sk; 69 struct sock *sk = sock->sk;
70 struct rds_sock *rs; 70 struct rds_sock *rs;
71 unsigned long flags;
72 71
73 if (!sk) 72 if (!sk)
74 goto out; 73 goto out;
@@ -94,10 +93,10 @@ static int rds_release(struct socket *sock)
94 rds_rdma_drop_keys(rs); 93 rds_rdma_drop_keys(rs);
95 rds_notify_queue_get(rs, NULL); 94 rds_notify_queue_get(rs, NULL);
96 95
97 spin_lock_irqsave(&rds_sock_lock, flags); 96 spin_lock_bh(&rds_sock_lock);
98 list_del_init(&rs->rs_item); 97 list_del_init(&rs->rs_item);
99 rds_sock_count--; 98 rds_sock_count--;
100 spin_unlock_irqrestore(&rds_sock_lock, flags); 99 spin_unlock_bh(&rds_sock_lock);
101 100
102 rds_trans_put(rs->rs_transport); 101 rds_trans_put(rs->rs_transport);
103 102
@@ -409,7 +408,6 @@ static const struct proto_ops rds_proto_ops = {
409 408
410static int __rds_create(struct socket *sock, struct sock *sk, int protocol) 409static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
411{ 410{
412 unsigned long flags;
413 struct rds_sock *rs; 411 struct rds_sock *rs;
414 412
415 sock_init_data(sock, sk); 413 sock_init_data(sock, sk);
@@ -426,10 +424,10 @@ static int __rds_create(struct socket *sock, struct sock *sk, int protocol)
426 spin_lock_init(&rs->rs_rdma_lock); 424 spin_lock_init(&rs->rs_rdma_lock);
427 rs->rs_rdma_keys = RB_ROOT; 425 rs->rs_rdma_keys = RB_ROOT;
428 426
429 spin_lock_irqsave(&rds_sock_lock, flags); 427 spin_lock_bh(&rds_sock_lock);
430 list_add_tail(&rs->rs_item, &rds_sock_list); 428 list_add_tail(&rs->rs_item, &rds_sock_list);
431 rds_sock_count++; 429 rds_sock_count++;
432 spin_unlock_irqrestore(&rds_sock_lock, flags); 430 spin_unlock_bh(&rds_sock_lock);
433 431
434 return 0; 432 return 0;
435} 433}
@@ -471,12 +469,11 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
471{ 469{
472 struct rds_sock *rs; 470 struct rds_sock *rs;
473 struct rds_incoming *inc; 471 struct rds_incoming *inc;
474 unsigned long flags;
475 unsigned int total = 0; 472 unsigned int total = 0;
476 473
477 len /= sizeof(struct rds_info_message); 474 len /= sizeof(struct rds_info_message);
478 475
479 spin_lock_irqsave(&rds_sock_lock, flags); 476 spin_lock_bh(&rds_sock_lock);
480 477
481 list_for_each_entry(rs, &rds_sock_list, rs_item) { 478 list_for_each_entry(rs, &rds_sock_list, rs_item) {
482 read_lock(&rs->rs_recv_lock); 479 read_lock(&rs->rs_recv_lock);
@@ -492,7 +489,7 @@ static void rds_sock_inc_info(struct socket *sock, unsigned int len,
492 read_unlock(&rs->rs_recv_lock); 489 read_unlock(&rs->rs_recv_lock);
493 } 490 }
494 491
495 spin_unlock_irqrestore(&rds_sock_lock, flags); 492 spin_unlock_bh(&rds_sock_lock);
496 493
497 lens->nr = total; 494 lens->nr = total;
498 lens->each = sizeof(struct rds_info_message); 495 lens->each = sizeof(struct rds_info_message);
@@ -504,11 +501,10 @@ static void rds_sock_info(struct socket *sock, unsigned int len,
504{ 501{
505 struct rds_info_socket sinfo; 502 struct rds_info_socket sinfo;
506 struct rds_sock *rs; 503 struct rds_sock *rs;
507 unsigned long flags;
508 504
509 len /= sizeof(struct rds_info_socket); 505 len /= sizeof(struct rds_info_socket);
510 506
511 spin_lock_irqsave(&rds_sock_lock, flags); 507 spin_lock_bh(&rds_sock_lock);
512 508
513 if (len < rds_sock_count) 509 if (len < rds_sock_count)
514 goto out; 510 goto out;
@@ -529,7 +525,7 @@ out:
529 lens->nr = rds_sock_count; 525 lens->nr = rds_sock_count;
530 lens->each = sizeof(struct rds_info_socket); 526 lens->each = sizeof(struct rds_info_socket);
531 527
532 spin_unlock_irqrestore(&rds_sock_lock, flags); 528 spin_unlock_bh(&rds_sock_lock);
533} 529}
534 530
535static void rds_exit(void) 531static void rds_exit(void)