void smc_close_wake_tx_prepared(struct smc_sock *smc)
{ if (smc->wait_close_tx_prepared) /* wake up socket closing */
smc->sk.sk_state_change(&smc->sk);
}
release_sock(sk); if (cancel_work_sync(&smc->conn.close_work))
sock_put(sk);
cancel_delayed_work_sync(&smc->conn.tx_work);
lock_sock(sk);
}
/* terminate smc socket abnormally - active abort * link group is terminated, i.e. RDMA communication no longer possible
*/ void smc_close_active_abort(struct smc_sock *smc)
{ struct sock *sk = &smc->sk; bool release_clcsock = false;
if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
sk->sk_err = ECONNABORTED; if (smc->clcsock && smc->clcsock->sk)
tcp_abort(smc->clcsock->sk, ECONNABORTED);
} switch (sk->sk_state) { case SMC_ACTIVE: case SMC_APPCLOSEWAIT1: case SMC_APPCLOSEWAIT2:
sk->sk_state = SMC_PEERABORTWAIT;
smc_close_cancel_work(smc); if (sk->sk_state != SMC_PEERABORTWAIT) break;
sk->sk_state = SMC_CLOSED;
sock_put(sk); /* (postponed) passive closing */ break; case SMC_PEERCLOSEWAIT1: case SMC_PEERCLOSEWAIT2: case SMC_PEERFINCLOSEWAIT:
sk->sk_state = SMC_PEERABORTWAIT;
smc_close_cancel_work(smc); if (sk->sk_state != SMC_PEERABORTWAIT) break;
sk->sk_state = SMC_CLOSED;
smc_conn_free(&smc->conn);
release_clcsock = true;
sock_put(sk); /* passive closing */ break; case SMC_PROCESSABORT: case SMC_APPFINCLOSEWAIT:
sk->sk_state = SMC_PEERABORTWAIT;
smc_close_cancel_work(smc); if (sk->sk_state != SMC_PEERABORTWAIT) break;
sk->sk_state = SMC_CLOSED;
smc_conn_free(&smc->conn);
release_clcsock = true; break; case SMC_INIT: case SMC_PEERABORTWAIT: case SMC_CLOSED: break;
}
switch (sk->sk_state) { case SMC_INIT: case SMC_ACTIVE: case SMC_APPCLOSEWAIT1:
sk->sk_state = SMC_PROCESSABORT;
sock_put(sk); /* passive closing */ break; case SMC_APPFINCLOSEWAIT:
sk->sk_state = SMC_PROCESSABORT; break; case SMC_PEERCLOSEWAIT1: case SMC_PEERCLOSEWAIT2: if (txflags->peer_done_writing &&
!smc_close_sent_any_close(&smc->conn)) /* just shutdown, but not yet closed locally */
sk->sk_state = SMC_PROCESSABORT; else
sk->sk_state = SMC_CLOSED;
sock_put(sk); /* passive closing */ break; case SMC_APPCLOSEWAIT2: case SMC_PEERFINCLOSEWAIT:
sk->sk_state = SMC_CLOSED;
sock_put(sk); /* passive closing */ break; case SMC_PEERABORTWAIT:
sk->sk_state = SMC_CLOSED; break; case SMC_PROCESSABORT: /* nothing to do, add tracing in future patch */ break;
}
}
/* Either some kind of closing has been received: peer_conn_closed, * peer_conn_abort, or peer_done_writing * or the link group of the connection terminates abnormally.
*/ staticvoid smc_close_passive_work(struct work_struct *work)
{ struct smc_connection *conn = container_of(work, struct smc_connection,
close_work); struct smc_sock *smc = container_of(conn, struct smc_sock, conn); struct smc_cdc_conn_state_flags *rxflags; bool release_clcsock = false; struct sock *sk = &smc->sk; int old_state;
lock_sock(sk);
old_state = sk->sk_state;
rxflags = &conn->local_rx_ctrl.conn_state_flags; if (rxflags->peer_conn_abort) { /* peer has not received all data */
smc_close_passive_abort_received(smc);
release_sock(sk);
cancel_delayed_work_sync(&conn->tx_work);
lock_sock(sk); goto wakeup;
}
switch (sk->sk_state) { case SMC_INIT:
sk->sk_state = SMC_APPCLOSEWAIT1; break; case SMC_ACTIVE:
sk->sk_state = SMC_APPCLOSEWAIT1; /* postpone sock_put() for passive closing to cover * received SEND_SHUTDOWN as well
*/ break; case SMC_PEERCLOSEWAIT1: if (rxflags->peer_done_writing)
sk->sk_state = SMC_PEERCLOSEWAIT2;
fallthrough; /* to check for closing */ case SMC_PEERCLOSEWAIT2: if (!smc_cdc_rxed_any_close(conn)) break; if (sock_flag(sk, SOCK_DEAD) &&
smc_close_sent_any_close(conn)) { /* smc_release has already been called locally */
sk->sk_state = SMC_CLOSED;
} else { /* just shutdown, but not yet closed locally */
sk->sk_state = SMC_APPFINCLOSEWAIT;
}
sock_put(sk); /* passive closing */ break; case SMC_PEERFINCLOSEWAIT: if (smc_cdc_rxed_any_close(conn)) {
sk->sk_state = SMC_CLOSED;
sock_put(sk); /* passive closing */
} break; case SMC_APPCLOSEWAIT1: case SMC_APPCLOSEWAIT2: /* postpone sock_put() for passive closing to cover * received SEND_SHUTDOWN as well
*/ break; case SMC_APPFINCLOSEWAIT: case SMC_PEERABORTWAIT: case SMC_PROCESSABORT: case SMC_CLOSED: /* nothing to do, add tracing in future patch */ break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.