nvmf/fc: Cleanup FC qpair_fini code.
As NVMF qpair maps to a FC level connection, Ideally a qpair fini should cleanup fc level connection irrespective of what type of qpair it is i.e admin or IO. But today IO qpair cleanup is actually a dummy. Also FC nvmf_transport_qpair_fini is just triggering fc level connection cleanup but not properly synchronized. Use latest async nature of nvmf_transport_qpair_fini enhancements to fix this. Signed-off-by: Naresh Gottumukkala <raju.gottumukkala@broadcom.com> Change-Id: I883ed774769e2d4a2575b6d90bb3348981cd1e0d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5700 Community-CI: Broadcom CI Community-CI: Mellanox Build Bot Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
This commit is contained in:
parent
b50c6bc2d9
commit
e89d9af092
@ -321,30 +321,6 @@ nvmf_fc_create_hash_table(const char *name, size_t num_entries, size_t key_len)
|
||||
return rte_hash_create(&hash_params);
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_fc_handle_connection_failure(void *arg)
|
||||
{
|
||||
struct spdk_nvmf_fc_conn *fc_conn = arg;
|
||||
struct spdk_nvmf_fc_ls_add_conn_api_data *api_data = NULL;
|
||||
|
||||
if (!fc_conn->create_opd) {
|
||||
return;
|
||||
}
|
||||
api_data = &fc_conn->create_opd->u.add_conn;
|
||||
|
||||
nvmf_fc_ls_add_conn_failure(api_data->assoc, api_data->ls_rqst,
|
||||
api_data->args.fc_conn, api_data->aq_conn);
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_fc_handle_assoc_deletion(void *arg)
|
||||
{
|
||||
struct spdk_nvmf_fc_conn *fc_conn = arg;
|
||||
|
||||
nvmf_fc_delete_association(fc_conn->fc_assoc->tgtport,
|
||||
fc_conn->fc_assoc->assoc_id, false, true, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
nvmf_fc_free_conn_reqpool(struct spdk_nvmf_fc_conn *fc_conn)
|
||||
{
|
||||
@ -2062,28 +2038,69 @@ nvmf_fc_request_free(struct spdk_nvmf_request *req)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_fc_connection_delete_done_cb(void *arg)
|
||||
{
|
||||
struct spdk_nvmf_fc_qpair_remove_ctx *fc_ctx = arg;
|
||||
|
||||
if (fc_ctx->cb_fn) {
|
||||
spdk_thread_send_msg(fc_ctx->qpair_thread, fc_ctx->cb_fn, fc_ctx->cb_ctx);
|
||||
}
|
||||
free(fc_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
_nvmf_fc_close_qpair(void *arg)
|
||||
{
|
||||
struct spdk_nvmf_fc_qpair_remove_ctx *fc_ctx = arg;
|
||||
struct spdk_nvmf_qpair *qpair = fc_ctx->qpair;
|
||||
struct spdk_nvmf_fc_conn *fc_conn;
|
||||
int rc;
|
||||
|
||||
fc_conn = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_fc_conn, qpair);
|
||||
if (fc_conn->conn_id == NVMF_FC_INVALID_CONN_ID) {
|
||||
struct spdk_nvmf_fc_ls_add_conn_api_data *api_data = NULL;
|
||||
|
||||
if (fc_conn->create_opd) {
|
||||
api_data = &fc_conn->create_opd->u.add_conn;
|
||||
|
||||
nvmf_fc_ls_add_conn_failure(api_data->assoc, api_data->ls_rqst,
|
||||
api_data->args.fc_conn, api_data->aq_conn);
|
||||
}
|
||||
} else if (fc_conn->conn_state == SPDK_NVMF_FC_OBJECT_CREATED) {
|
||||
rc = nvmf_fc_delete_connection(fc_conn, false, true,
|
||||
nvmf_fc_connection_delete_done_cb, fc_ctx);
|
||||
if (!rc) {
|
||||
/* Wait for transport to complete its work. */
|
||||
return;
|
||||
}
|
||||
|
||||
SPDK_ERRLOG("%s: Delete FC connection failed.\n", __func__);
|
||||
}
|
||||
|
||||
nvmf_fc_connection_delete_done_cb(fc_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
nvmf_fc_close_qpair(struct spdk_nvmf_qpair *qpair,
|
||||
spdk_nvmf_transport_qpair_fini_cb cb_fn, void *cb_arg)
|
||||
{
|
||||
struct spdk_nvmf_fc_conn *fc_conn;
|
||||
struct spdk_nvmf_fc_qpair_remove_ctx *fc_ctx;
|
||||
|
||||
fc_conn = SPDK_CONTAINEROF(qpair, struct spdk_nvmf_fc_conn, qpair);
|
||||
|
||||
if (fc_conn->conn_id == NVMF_FC_INVALID_CONN_ID) {
|
||||
/* QP creation failure in FC tranport. Cleanup. */
|
||||
spdk_thread_send_msg(nvmf_fc_get_main_thread(),
|
||||
nvmf_fc_handle_connection_failure, fc_conn);
|
||||
} else if (fc_conn->fc_assoc->assoc_id == fc_conn->conn_id &&
|
||||
fc_conn->fc_assoc->assoc_state != SPDK_NVMF_FC_OBJECT_TO_BE_DELETED) {
|
||||
/* Admin connection */
|
||||
spdk_thread_send_msg(nvmf_fc_get_main_thread(),
|
||||
nvmf_fc_handle_assoc_deletion, fc_conn);
|
||||
fc_ctx = calloc(1, sizeof(struct spdk_nvmf_fc_qpair_remove_ctx));
|
||||
if (!fc_ctx) {
|
||||
SPDK_ERRLOG("Unable to allocate close_qpair ctx.");
|
||||
if (cb_fn) {
|
||||
cb_fn(cb_arg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
fc_ctx->qpair = qpair;
|
||||
fc_ctx->cb_fn = cb_fn;
|
||||
fc_ctx->cb_ctx = cb_arg;
|
||||
fc_ctx->qpair_thread = spdk_get_thread();
|
||||
|
||||
if (cb_fn) {
|
||||
cb_fn(cb_arg);
|
||||
}
|
||||
spdk_thread_send_msg(nvmf_fc_get_main_thread(), _nvmf_fc_close_qpair, fc_ctx);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -419,6 +419,9 @@ nvmf_fc_do_del_conn_cbs(struct nvmf_fc_ls_op_ctx *opd,
|
||||
SPDK_ERRLOG("Send LS response for delete connection failed\n");
|
||||
}
|
||||
}
|
||||
if (dp->del_conn_cb) {
|
||||
dp->del_conn_cb(dp->del_conn_cb_data);
|
||||
}
|
||||
free(opd);
|
||||
opd = nxt;
|
||||
}
|
||||
@ -444,7 +447,8 @@ nvmf_fc_ls_poller_delete_conn_cb(void *cb_data, enum spdk_nvmf_fc_poller_api_ret
|
||||
|
||||
static int
|
||||
nvmf_fc_ls_poller_delete_conn(struct spdk_nvmf_fc_conn *fc_conn, bool send_abts,
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst, bool backend_initiated)
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst, bool backend_initiated,
|
||||
spdk_nvmf_fc_del_conn_cb cb_fn, void *cb_data)
|
||||
{
|
||||
struct spdk_nvmf_fc_association *assoc = fc_conn->fc_assoc;
|
||||
struct spdk_nvmf_fc_ls_del_conn_api_data *api_data;
|
||||
@ -464,6 +468,8 @@ nvmf_fc_ls_poller_delete_conn(struct spdk_nvmf_fc_conn *fc_conn, bool send_abts,
|
||||
api_data = &opd->u.del_conn;
|
||||
api_data->assoc = assoc;
|
||||
api_data->ls_rqst = ls_rqst;
|
||||
api_data->del_conn_cb = cb_fn;
|
||||
api_data->del_conn_cb_data = cb_data;
|
||||
api_data->aq_conn = (assoc->aq_conn == fc_conn ? true : false);
|
||||
api_data->args.fc_conn = fc_conn;
|
||||
api_data->args.send_abts = send_abts;
|
||||
@ -527,7 +533,7 @@ nvmf_fc_ls_add_conn_cb(void *cb_data, enum spdk_nvmf_fc_poller_api_ret ret)
|
||||
if (nvmf_fc_xmt_ls_rsp(tgtport, ls_rqst) != 0) {
|
||||
SPDK_ERRLOG("Send LS response for %s failed - cleaning up\n",
|
||||
dp->aq_conn ? "association" : "connection");
|
||||
nvmf_fc_ls_poller_delete_conn(fc_conn, false, NULL, false);
|
||||
nvmf_fc_ls_poller_delete_conn(fc_conn, false, NULL, false, NULL, NULL);
|
||||
} else {
|
||||
SPDK_DEBUGLOG(nvmf_fc_ls,
|
||||
"LS response (conn_id 0x%lx) sent\n", fc_conn->conn_id);
|
||||
@ -767,7 +773,7 @@ _nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
|
||||
|
||||
/* delete all of the association's connections */
|
||||
TAILQ_FOREACH(fc_conn, &assoc->fc_conns, assoc_link) {
|
||||
rc = nvmf_fc_ls_poller_delete_conn(fc_conn, send_abts, NULL, backend_initiated);
|
||||
rc = nvmf_fc_ls_poller_delete_conn(fc_conn, send_abts, NULL, backend_initiated, NULL, NULL);
|
||||
if (rc) {
|
||||
SPDK_ERRLOG("Delete connection failed for assoc_id 0x%lx conn_id 0x%lx\n",
|
||||
assoc->assoc_id, fc_conn->conn_id);
|
||||
@ -1278,6 +1284,16 @@ nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
|
||||
del_assoc_cb, cb_data, false);
|
||||
}
|
||||
|
||||
int
|
||||
nvmf_fc_delete_connection(struct spdk_nvmf_fc_conn *fc_conn, bool send_abts,
|
||||
bool backend_initiated, spdk_nvmf_fc_del_conn_cb cb_fn,
|
||||
void *cb_data)
|
||||
{
|
||||
return nvmf_fc_ls_poller_delete_conn(fc_conn, send_abts, NULL,
|
||||
backend_initiated, cb_fn, cb_data);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
nvmf_fc_poller_api_cb_event(void *arg)
|
||||
{
|
||||
|
@ -176,6 +176,13 @@ struct spdk_nvmf_fc_srsr_bufs {
|
||||
uint16_t rpi;
|
||||
};
|
||||
|
||||
struct spdk_nvmf_fc_qpair_remove_ctx {
|
||||
struct spdk_nvmf_qpair *qpair;
|
||||
spdk_nvmf_transport_qpair_fini_cb cb_fn;
|
||||
void *cb_ctx;
|
||||
struct spdk_thread *qpair_thread;
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct representing a nport
|
||||
*/
|
||||
@ -552,6 +559,7 @@ SPDK_STATIC_ASSERT(sizeof(struct spdk_nvmf_fc_rq_buf_ls_request) ==
|
||||
|
||||
/* Poller API structures (arguments and callback data */
|
||||
typedef void (*spdk_nvmf_fc_del_assoc_cb)(void *arg, uint32_t err);
|
||||
typedef void (*spdk_nvmf_fc_del_conn_cb)(void *arg);
|
||||
|
||||
struct spdk_nvmf_fc_ls_add_conn_api_data {
|
||||
struct spdk_nvmf_fc_poller_api_add_connection_args args;
|
||||
@ -566,6 +574,8 @@ struct spdk_nvmf_fc_ls_del_conn_api_data {
|
||||
struct spdk_nvmf_fc_ls_rqst *ls_rqst;
|
||||
struct spdk_nvmf_fc_association *assoc;
|
||||
bool aq_conn; /* true if deleting AQ connection */
|
||||
spdk_nvmf_fc_del_conn_cb del_conn_cb;
|
||||
void *del_conn_cb_data;
|
||||
};
|
||||
|
||||
/* used by LS disconnect association cmd handling */
|
||||
@ -922,6 +932,10 @@ int nvmf_fc_delete_association(struct spdk_nvmf_fc_nport *tgtport,
|
||||
spdk_nvmf_fc_del_assoc_cb del_assoc_cb,
|
||||
void *cb_data);
|
||||
|
||||
int nvmf_fc_delete_connection(struct spdk_nvmf_fc_conn *fc_conn, bool send_abts,
|
||||
bool backend_initiated, spdk_nvmf_fc_del_conn_cb cb_fn,
|
||||
void *cb_data);
|
||||
|
||||
bool nvmf_ctrlr_is_on_nport(uint8_t port_hdl, uint16_t nport_hdl,
|
||||
struct spdk_nvmf_ctrlr *ctrlr);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user