RDS: Rewrite connection cleanup, fixing oops on rmmod

This fixes a bug where a connection was unexpectedly
not on *any* list while being destroyed. It also
cleans up some code duplication and regularizes some
function names.

* Grab appropriate lock in conn_free() and explain in comment
* Ensure via locking that a conn is never not on either
  a dev's list or the nodev list
* Add rds_xx_remove_conn() to match rds_xx_add_conn()
* Make rds_xx_add_conn() return void
* Rename remove_{,nodev_}conns() to
  destroy_{,nodev_}conns() and unify their implementation
  in a helper function
* Document lock ordering as nodev conn_lock before
  dev_conn_lock

Reported-by: Yosef Etigin <yosefe@voltaire.com>
Signed-off-by: Andy Grover <andy.grover@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Šī revīzija ir iekļauta:
Andy Grover
2009-04-01 08:20:19 +00:00
revīziju iesūtīja David S. Miller
vecāks f1cffcbfcc
revīzija 745cbccac3
8 mainīti faili ar 119 papildinājumiem un 95 dzēšanām

Parādīt failu

@@ -294,9 +294,17 @@ void rds_iw_cm_connect_complete(struct rds_connection *conn,
/* ib_rdma.c */
int rds_iw_update_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_id);
int rds_iw_add_conn(struct rds_iw_device *rds_iwdev, struct rds_connection *conn);
void rds_iw_remove_nodev_conns(void);
void rds_iw_remove_conns(struct rds_iw_device *rds_iwdev);
void rds_iw_add_conn(struct rds_iw_device *rds_iwdev, struct rds_connection *conn);
void rds_iw_remove_conn(struct rds_iw_device *rds_iwdev, struct rds_connection *conn);
void __rds_iw_destroy_conns(struct list_head *list, spinlock_t *list_lock);
static inline void rds_iw_destroy_nodev_conns(void)
{
__rds_iw_destroy_conns(&iw_nodev_conns, &iw_nodev_conns_lock);
}
static inline void rds_iw_destroy_conns(struct rds_iw_device *rds_iwdev)
{
__rds_iw_destroy_conns(&rds_iwdev->conn_list, &rds_iwdev->spinlock);
}
struct rds_iw_mr_pool *rds_iw_create_mr_pool(struct rds_iw_device *);
void rds_iw_get_mr_info(struct rds_iw_device *rds_iwdev, struct rds_info_rdma_connection *iinfo);
void rds_iw_destroy_mr_pool(struct rds_iw_mr_pool *);