diff --git a/lnet/klnds/socklnd/socklnd.c b/lnet/klnds/socklnd/socklnd.c index 6150792a3efae5c1826c26ca9adaf8f866127878..360f905895d8123a9217feb33bb18d16320b4a21 100644 --- a/lnet/klnds/socklnd/socklnd.c +++ b/lnet/klnds/socklnd/socklnd.c @@ -1505,6 +1505,41 @@ ksocknal_peer_failed (ksock_peer_t *peer) last_alive); } +void +ksocknal_finalize_zcreq(ksock_conn_t *conn) +{ + ksock_peer_t *peer = conn->ksnc_peer; + ksock_tx_t *tx; + ksock_tx_t *tmp; + CFS_LIST_HEAD (zlist); + + /* NB safe to finalize TXs because closing of socket will + * abort all buffered data */ + LASSERT (conn->ksnc_sock == NULL); + + spin_lock(&peer->ksnp_lock); + + list_for_each_entry_safe(tx, tmp, &peer->ksnp_zc_req_list, tx_zc_list) { + if (tx->tx_conn != conn) + continue; + + LASSERT (tx->tx_msg.ksm_zc_req_cookie != 0); + + tx->tx_msg.ksm_zc_req_cookie = 0; + list_del(&tx->tx_zc_list); + list_add(&tx->tx_zc_list, &zlist); + } + + spin_unlock(&peer->ksnp_lock); + + while (!list_empty(&zlist)) { + tx = list_entry(zlist.next, ksock_tx_t, tx_zc_list); + + list_del(&tx->tx_zc_list); + ksocknal_tx_decref(tx); + } +} + void ksocknal_terminate_conn (ksock_conn_t *conn) { @@ -1515,10 +1550,6 @@ ksocknal_terminate_conn (ksock_conn_t *conn) ksock_peer_t *peer = conn->ksnc_peer; ksock_sched_t *sched = conn->ksnc_scheduler; int failed = 0; - struct list_head *tmp; - struct list_head *nxt; - ksock_tx_t *tx; - LIST_HEAD (zlist); LASSERT(conn->ksnc_closing); @@ -1541,30 +1572,6 @@ ksocknal_terminate_conn (ksock_conn_t *conn) spin_unlock_bh (&sched->kss_lock); - spin_lock(&peer->ksnp_lock); - - list_for_each_safe(tmp, nxt, &peer->ksnp_zc_req_list) { - tx = list_entry(tmp, ksock_tx_t, tx_zc_list); - - if (tx->tx_conn != conn) - continue; - - LASSERT (tx->tx_msg.ksm_zc_req_cookie != 0); - - tx->tx_msg.ksm_zc_req_cookie = 0; - list_del(&tx->tx_zc_list); - list_add(&tx->tx_zc_list, &zlist); - } - - spin_unlock(&peer->ksnp_lock); - - list_for_each_safe(tmp, nxt, &zlist) { - tx = list_entry(tmp, ksock_tx_t, tx_zc_list); - - list_del(&tx->tx_zc_list); - ksocknal_tx_decref(tx); - } - /* serialise with callbacks */ write_lock_bh (&ksocknal_data.ksnd_global_lock); diff --git a/lnet/klnds/socklnd/socklnd.h b/lnet/klnds/socklnd/socklnd.h index bfda248fc766a4975557c38b70f0b714ca7eb685..b72df00b36922f25e31119e521be613c179e2d9c 100644 --- a/lnet/klnds/socklnd/socklnd.h +++ b/lnet/klnds/socklnd/socklnd.h @@ -401,6 +401,7 @@ ksocknal_conn_addref (ksock_conn_t *conn) } extern void ksocknal_queue_zombie_conn (ksock_conn_t *conn); +extern void ksocknal_finalize_zcreq(ksock_conn_t *conn); static inline void ksocknal_conn_decref (ksock_conn_t *conn) @@ -434,6 +435,7 @@ ksocknal_connsock_decref (ksock_conn_t *conn) LASSERT (conn->ksnc_closing); libcfs_sock_release(conn->ksnc_sock); conn->ksnc_sock = NULL; + ksocknal_finalize_zcreq(conn); } }