diff options
Diffstat (limited to 'net/rds')
-rw-r--r-- | net/rds/rdma.c | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index 3b442d4d64cf..463b458ff27e 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -130,14 +130,22 @@ void rds_rdma_drop_keys(struct rds_sock *rs) | |||
130 | { | 130 | { |
131 | struct rds_mr *mr; | 131 | struct rds_mr *mr; |
132 | struct rb_node *node; | 132 | struct rb_node *node; |
133 | unsigned long flags; | ||
133 | 134 | ||
134 | /* Release any MRs associated with this socket */ | 135 | /* Release any MRs associated with this socket */ |
136 | spin_lock_irqsave(&rs->rs_rdma_lock, flags); | ||
135 | while ((node = rb_first(&rs->rs_rdma_keys))) { | 137 | while ((node = rb_first(&rs->rs_rdma_keys))) { |
136 | mr = container_of(node, struct rds_mr, r_rb_node); | 138 | mr = container_of(node, struct rds_mr, r_rb_node); |
137 | if (mr->r_trans == rs->rs_transport) | 139 | if (mr->r_trans == rs->rs_transport) |
138 | mr->r_invalidate = 0; | 140 | mr->r_invalidate = 0; |
141 | rb_erase(&mr->r_rb_node, &rs->rs_rdma_keys); | ||
142 | RB_CLEAR_NODE(&mr->r_rb_node); | ||
143 | spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); | ||
144 | rds_destroy_mr(mr); | ||
139 | rds_mr_put(mr); | 145 | rds_mr_put(mr); |
146 | spin_lock_irqsave(&rs->rs_rdma_lock, flags); | ||
140 | } | 147 | } |
148 | spin_unlock_irqrestore(&rs->rs_rdma_lock, flags); | ||
141 | 149 | ||
142 | if (rs->rs_transport && rs->rs_transport->flush_mrs) | 150 | if (rs->rs_transport && rs->rs_transport->flush_mrs) |
143 | rs->rs_transport->flush_mrs(); | 151 | rs->rs_transport->flush_mrs(); |