Commit e3c78a64 authored by Naresh Gottumukkala's avatar Naresh Gottumukkala Committed by Tomasz Zawadzki
Browse files

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: default avatarNaresh 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: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarShuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
parent dc0d8962
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -936,6 +936,17 @@ nvmf_fc_port_add(struct spdk_nvmf_fc_port *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 *
nvmf_fc_port_lookup(uint8_t port_hdl)
{
@@ -2813,6 +2824,75 @@ abort_port_init:
		      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.
 */
@@ -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;
		break;

	case SPDK_FC_HW_PORT_FREE:
		event_fn = nvmf_fc_adm_evnt_hw_port_free;
		break;

	case SPDK_FC_HW_PORT_ONLINE:
		event_fn = nvmf_fc_adm_evnt_hw_port_online;
		break;
+6 −0
Original line number Diff line number Diff line
@@ -633,6 +633,7 @@ struct spdk_nvmf_fc_poller_api_queue_sync_args {
 */
enum spdk_fc_event {
	SPDK_FC_HW_PORT_INIT,
	SPDK_FC_HW_PORT_FREE,
	SPDK_FC_HW_PORT_ONLINE,
	SPDK_FC_HW_PORT_OFFLINE,
	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_hw_port_free_args {
	uint8_t port_handle;
	void    *cb_ctx;
};

/**
 * Callback function to the FCT driver.
 */
+1 −0
Original line number Diff line number Diff line
@@ -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_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_remove, int, (struct spdk_nvmf_fc_port *fc_port), 0);

const char *
spdk_nvme_transport_id_trtype_str(enum spdk_nvme_transport_type trtype)