nvmf/fc: Add support for hwport free admin api.

Currently we dont have an api to delete fc port. Add SPDK_FC_HW_PORT_FREE
api. This is useful in cases of hardware reset and other error cases.

Signed-off-by: Naresh Gottumukkala <raju.gottumukkala@broadcom.com>
Change-Id: Ib1b986ee7ab2f54043bd300b52121b651c292e5b
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/5810
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:
Naresh Gottumukkala 2021-01-07 10:41:46 +00:00 committed by Tomasz Zawadzki
parent dc0d896293
commit e3c78a6453
3 changed files with 91 additions and 0 deletions

View File

@ -936,6 +936,17 @@ nvmf_fc_port_add(struct spdk_nvmf_fc_port *fc_port)
nvmf_fc_lld_port_add(fc_port); nvmf_fc_lld_port_add(fc_port);
} }
static void
nvmf_fc_port_remove(struct spdk_nvmf_fc_port *fc_port)
{
TAILQ_REMOVE(&g_spdk_nvmf_fc_port_list, fc_port, link);
/*
* Let LLD remove the port from its list.
*/
nvmf_fc_lld_port_remove(fc_port);
}
struct spdk_nvmf_fc_port * struct spdk_nvmf_fc_port *
nvmf_fc_port_lookup(uint8_t port_hdl) nvmf_fc_port_lookup(uint8_t port_hdl)
{ {
@ -2813,6 +2824,75 @@ abort_port_init:
args->port_handle, err); args->port_handle, err);
} }
static void
nvmf_fc_adm_hwqp_clean_sync_cb(struct spdk_nvmf_fc_hwqp *hwqp)
{
struct spdk_nvmf_fc_abts_ctx *ctx;
struct spdk_nvmf_fc_poller_api_queue_sync_args *args = NULL, *tmp = NULL;
TAILQ_FOREACH_SAFE(args, &hwqp->sync_cbs, link, tmp) {
TAILQ_REMOVE(&hwqp->sync_cbs, args, link);
ctx = args->cb_info.cb_data;
if (ctx) {
if (++ctx->hwqps_responded == ctx->num_hwqps) {
free(ctx->sync_poller_args);
free(ctx->abts_poller_args);
spdk_free(ctx);
}
}
}
}
static void
nvmf_fc_adm_evnt_hw_port_free(void *arg)
{
ASSERT_SPDK_FC_MAIN_THREAD();
int err = 0, i;
struct spdk_nvmf_fc_port *fc_port = NULL;
struct spdk_nvmf_fc_hwqp *hwqp = NULL;
struct spdk_nvmf_fc_adm_api_data *api_data = (struct spdk_nvmf_fc_adm_api_data *)arg;
struct spdk_nvmf_fc_hw_port_free_args *args = (struct spdk_nvmf_fc_hw_port_free_args *)
api_data->api_args;
fc_port = nvmf_fc_port_lookup(args->port_handle);
if (!fc_port) {
SPDK_ERRLOG("Unable to find the SPDK FC port %d\n", args->port_handle);
err = -EINVAL;
goto out;
}
if (!TAILQ_EMPTY(&fc_port->nport_list)) {
SPDK_ERRLOG("Hw port %d: nports not cleared up yet.\n", args->port_handle);
err = -EIO;
goto out;
}
/* Clean up and free fc_port */
hwqp = &fc_port->ls_queue;
nvmf_fc_adm_hwqp_clean_sync_cb(hwqp);
rte_hash_free(hwqp->connection_list_hash);
rte_hash_free(hwqp->rport_list_hash);
for (i = 0; i < (int)fc_port->num_io_queues; i++) {
hwqp = &fc_port->io_queues[i];
nvmf_fc_adm_hwqp_clean_sync_cb(&fc_port->io_queues[i]);
rte_hash_free(hwqp->connection_list_hash);
rte_hash_free(hwqp->rport_list_hash);
}
nvmf_fc_port_remove(fc_port);
free(fc_port);
out:
SPDK_DEBUGLOG(nvmf_fc_adm_api, "HW port %d free done, rc = %d.\n",
args->port_handle, err);
if (api_data->cb_func != NULL) {
(void)api_data->cb_func(args->port_handle, SPDK_FC_HW_PORT_FREE, args->cb_ctx, err);
}
free(arg);
}
/* /*
* Online a HW port. * Online a HW port.
*/ */
@ -3808,6 +3888,10 @@ nvmf_fc_main_enqueue_event(enum spdk_fc_event event_type, void *args,
event_fn = nvmf_fc_adm_evnt_hw_port_init; event_fn = nvmf_fc_adm_evnt_hw_port_init;
break; break;
case SPDK_FC_HW_PORT_FREE:
event_fn = nvmf_fc_adm_evnt_hw_port_free;
break;
case SPDK_FC_HW_PORT_ONLINE: case SPDK_FC_HW_PORT_ONLINE:
event_fn = nvmf_fc_adm_evnt_hw_port_online; event_fn = nvmf_fc_adm_evnt_hw_port_online;
break; break;

View File

@ -633,6 +633,7 @@ struct spdk_nvmf_fc_poller_api_queue_sync_args {
*/ */
enum spdk_fc_event { enum spdk_fc_event {
SPDK_FC_HW_PORT_INIT, SPDK_FC_HW_PORT_INIT,
SPDK_FC_HW_PORT_FREE,
SPDK_FC_HW_PORT_ONLINE, SPDK_FC_HW_PORT_ONLINE,
SPDK_FC_HW_PORT_OFFLINE, SPDK_FC_HW_PORT_OFFLINE,
SPDK_FC_HW_PORT_RESET, SPDK_FC_HW_PORT_RESET,
@ -770,6 +771,11 @@ struct spdk_nvmf_fc_hw_port_reset_args {
struct spdk_nvmf_fc_unrecoverable_error_event_args { struct spdk_nvmf_fc_unrecoverable_error_event_args {
}; };
struct spdk_nvmf_fc_hw_port_free_args {
uint8_t port_handle;
void *cb_ctx;
};
/** /**
* Callback function to the FCT driver. * Callback function to the FCT driver.
*/ */

View File

@ -143,6 +143,7 @@ DEFINE_STUB(rte_hash_lookup_data, int, (const struct rte_hash *h, const void *ke
DEFINE_STUB(rte_hash_add_key_data, int, (const struct rte_hash *h, const void *key, void *data), 0); DEFINE_STUB(rte_hash_add_key_data, int, (const struct rte_hash *h, const void *key, void *data), 0);
DEFINE_STUB_V(rte_hash_free, (struct rte_hash *h)); DEFINE_STUB_V(rte_hash_free, (struct rte_hash *h));
DEFINE_STUB(nvmf_fc_lld_port_add, int, (struct spdk_nvmf_fc_port *fc_port), 0); DEFINE_STUB(nvmf_fc_lld_port_add, int, (struct spdk_nvmf_fc_port *fc_port), 0);
DEFINE_STUB(nvmf_fc_lld_port_remove, int, (struct spdk_nvmf_fc_port *fc_port), 0);
const char * const char *
spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype) spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype)