Commit fca35b7b authored by Cunyin Chang's avatar Cunyin Chang Committed by cunyinch
Browse files

scsi: Add support for hotplug in scsi layer.



Change-Id: Ic779a79d41d60b6998f9bd05ca4a59c1301a10ac
Signed-off-by: default avatarCunyin Chang <cunyin.chang@intel.com>
parent 4055a502
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -218,6 +218,15 @@ struct spdk_scsi_lun {
	/** Name for this LUN. */
	char name[SPDK_SCSI_LUN_MAX_NAME_LENGTH];

	/** Poller to release the resource of the lun when it is hot removed */
	struct spdk_poller *hotplug_poller;

	/** The core hotplug_poller is assigned */
	uint32_t			lcore;

	/** The LUN is removed */
	bool				removed;

	TAILQ_HEAD(tasks, spdk_scsi_task) tasks;			/* submitted tasks */
	TAILQ_HEAD(pending_tasks, spdk_scsi_task) pending_tasks;	/* pending tasks */
};
+34 −2
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include "scsi_internal.h"
#include "spdk/endian.h"
#include "spdk/io_channel.h"
#include "spdk/event.h"

void
spdk_scsi_lun_complete_task(struct spdk_scsi_lun *lun, struct spdk_scsi_task *task)
@@ -235,7 +236,15 @@ spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun)
		spdk_trace_record(TRACE_SCSI_TASK_START, lun->dev->id, task->length, (uintptr_t)task, 0);
		TAILQ_REMOVE(&lun->pending_tasks, task, scsi_link);
		TAILQ_INSERT_TAIL(&lun->tasks, task, scsi_link);
		if (!lun->removed) {
			rc = spdk_bdev_scsi_execute(lun->bdev, task);
		} else {
			spdk_scsi_task_set_status(task, SPDK_SCSI_STATUS_CHECK_CONDITION,
						  SPDK_SCSI_SENSE_ABORTED_COMMAND,
						  SPDK_SCSI_ASC_NO_ADDITIONAL_SENSE,
						  SPDK_SCSI_ASCQ_CAUSE_NOT_REPORTABLE);
			rc = SPDK_SCSI_TASK_COMPLETE;
		}

		switch (rc) {
		case SPDK_SCSI_TASK_PENDING:
@@ -251,6 +260,26 @@ spdk_scsi_lun_execute_tasks(struct spdk_scsi_lun *lun)
	}
}

static void
spdk_scsi_lun_hotplug(void *arg)
{
	struct spdk_scsi_lun *lun = (struct spdk_scsi_lun *)arg;

	if (TAILQ_EMPTY(&lun->pending_tasks) && TAILQ_EMPTY(&lun->tasks)) {
		spdk_scsi_lun_free_io_channel(lun);
		spdk_scsi_lun_delete(lun->name);
	}
}

static void spdk_scsi_lun_hot_remove(void *remove_ctx)
{
	struct spdk_scsi_lun *lun = (struct spdk_scsi_lun *)remove_ctx;

	lun->removed = true;
	spdk_poller_register(&lun->hotplug_poller, spdk_scsi_lun_hotplug, lun,
			     lun->lcore, 0);
}

/*!

\brief Constructs a new spdk_scsi_lun object based on the provided parameters.
@@ -285,7 +314,7 @@ spdk_scsi_lun_construct(const char *name, struct spdk_bdev *bdev)
		return NULL;
	}

	if (!spdk_bdev_claim(bdev, NULL, NULL)) {
	if (!spdk_bdev_claim(bdev, spdk_scsi_lun_hot_remove, lun)) {
		SPDK_ERRLOG("LUN %s: bdev %s is already claimed\n", name, bdev->name);
		free(lun);
		return NULL;
@@ -312,6 +341,7 @@ int
spdk_scsi_lun_destruct(struct spdk_scsi_lun *lun)
{
	spdk_bdev_unclaim(lun->bdev);
	spdk_poller_unregister(&lun->hotplug_poller, NULL);
	spdk_scsi_lun_db_delete(lun);

	free(lun);
@@ -394,6 +424,8 @@ int spdk_scsi_lun_allocate_io_channel(struct spdk_scsi_lun *lun)
		return -1;
	}

	lun->lcore = spdk_app_get_current_core();

	lun->io_channel = spdk_bdev_get_io_channel(lun->bdev, SPDK_IO_PRIORITY_DEFAULT);
	if (lun->io_channel == NULL) {
		return -1;
+18 −0
Original line number Diff line number Diff line
@@ -50,6 +50,24 @@ static bool g_lun_execute_fail = false;
static int g_lun_execute_status = SPDK_SCSI_TASK_PENDING;
static uint32_t g_task_count = 0;

void
spdk_poller_register(struct spdk_poller **ppoller, spdk_poller_fn fn, void *arg,
		     uint32_t lcore, uint64_t period_microseconds)
{
}

void
spdk_poller_unregister(struct spdk_poller **ppoller,
		       struct spdk_event *complete)
{
}

uint32_t
spdk_app_get_current_core(void)
{
	return 0;
}

void spdk_trace_record(uint16_t tpoint_id, uint16_t poller_id, uint32_t size,
		       uint64_t object_id, uint64_t arg1)
{