aboutsummaryrefslogtreecommitdiff
path: root/sys/cam/ctl/ctl_backend_ramdisk.c
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2020-05-02 16:54:59 +0000
committerAlexander Motin <mav@FreeBSD.org>2020-05-02 16:54:59 +0000
commit34144c2c7153ceb7deb6732434aaf3de5522e7d0 (patch)
tree9fa9c4d93dc1488c494dd9304e3b2e4072bc22fd /sys/cam/ctl/ctl_backend_ramdisk.c
parent41b23744320e2f661fb4fc5677038ddf337ca453 (diff)
downloadsrc-34144c2c7153ceb7deb6732434aaf3de5522e7d0.tar.gz
src-34144c2c7153ceb7deb6732434aaf3de5522e7d0.zip
Cleanup LUN addition/removal.
- Make ctl_add_lun() synchronous. Asynchronous addition was used by Copan's proprietary code long ago and never for upstream FreeBSD. - Move LUN enable/disable calls from backends to CTL core. - Serialize LUN modification and partially removal to avoid double frees. - Slightly unify backends code. MFC after: 2 weeks Sponsored by: iXsystems, Inc.
Notes
Notes: svn path=/head/; revision=360564
Diffstat (limited to 'sys/cam/ctl/ctl_backend_ramdisk.c')
-rw-r--r--sys/cam/ctl/ctl_backend_ramdisk.c216
1 files changed, 58 insertions, 158 deletions
diff --git a/sys/cam/ctl/ctl_backend_ramdisk.c b/sys/cam/ctl/ctl_backend_ramdisk.c
index 52c983080a7e..96ab28d6381e 100644
--- a/sys/cam/ctl/ctl_backend_ramdisk.c
+++ b/sys/cam/ctl/ctl_backend_ramdisk.c
@@ -102,13 +102,11 @@ typedef enum {
typedef enum {
CTL_BE_RAMDISK_LUN_UNCONFIGURED = 0x01,
- CTL_BE_RAMDISK_LUN_CONFIG_ERR = 0x02,
CTL_BE_RAMDISK_LUN_WAITING = 0x04
} ctl_be_ramdisk_lun_flags;
struct ctl_be_ramdisk_lun {
struct ctl_lun_create_params params;
- char lunname[32];
int indir;
uint8_t **pages;
uint8_t *zero_page;
@@ -121,7 +119,7 @@ struct ctl_be_ramdisk_lun {
uint64_t cap_used;
struct ctl_be_ramdisk_softc *softc;
ctl_be_ramdisk_lun_flags flags;
- STAILQ_ENTRY(ctl_be_ramdisk_lun) links;
+ SLIST_ENTRY(ctl_be_ramdisk_lun) links;
struct ctl_be_lun cbe_lun;
struct taskqueue *io_taskqueue;
struct task io_task;
@@ -130,9 +128,10 @@ struct ctl_be_ramdisk_lun {
};
struct ctl_be_ramdisk_softc {
+ struct sx modify_lock;
struct mtx lock;
int num_luns;
- STAILQ_HEAD(, ctl_be_ramdisk_lun) lun_list;
+ SLIST_HEAD(, ctl_be_ramdisk_lun) lun_list;
};
static struct ctl_be_ramdisk_softc rd_softc;
@@ -157,8 +156,6 @@ static int ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
static int ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc,
struct ctl_lun_req *req);
static void ctl_backend_ramdisk_lun_shutdown(void *be_lun);
-static void ctl_backend_ramdisk_lun_config_status(void *be_lun,
- ctl_lun_config_status status);
static struct ctl_backend_driver ctl_be_ramdisk_driver =
{
@@ -174,7 +171,7 @@ static struct ctl_backend_driver ctl_be_ramdisk_driver =
.lun_attr = ctl_backend_ramdisk_lun_attr,
};
-MALLOC_DEFINE(M_RAMDISK, "ramdisk", "Memory used for CTL RAMdisk");
+MALLOC_DEFINE(M_RAMDISK, "ctlramdisk", "Memory used for CTL RAMdisk");
CTL_BACKEND_DECLARE(cbr, ctl_be_ramdisk_driver);
static int
@@ -183,8 +180,9 @@ ctl_backend_ramdisk_init(void)
struct ctl_be_ramdisk_softc *softc = &rd_softc;
memset(softc, 0, sizeof(*softc));
- mtx_init(&softc->lock, "ctlramdisk", NULL, MTX_DEF);
- STAILQ_INIT(&softc->lun_list);
+ sx_init(&softc->modify_lock, "ctlrammod");
+ mtx_init(&softc->lock, "ctlram", NULL, MTX_DEF);
+ SLIST_INIT(&softc->lun_list);
return (0);
}
@@ -192,22 +190,24 @@ static int
ctl_backend_ramdisk_shutdown(void)
{
struct ctl_be_ramdisk_softc *softc = &rd_softc;
- struct ctl_be_ramdisk_lun *lun, *next_lun;
+ struct ctl_be_ramdisk_lun *lun;
mtx_lock(&softc->lock);
- STAILQ_FOREACH_SAFE(lun, &softc->lun_list, links, next_lun) {
+ while ((lun = SLIST_FIRST(&softc->lun_list)) != NULL) {
+ SLIST_REMOVE_HEAD(&softc->lun_list, links);
+ softc->num_luns--;
/*
- * Drop our lock here. Since ctl_invalidate_lun() can call
+ * Drop our lock here. Since ctl_remove_lun() can call
* back into us, this could potentially lead to a recursive
* lock of the same mutex, which would cause a hang.
*/
mtx_unlock(&softc->lock);
- ctl_disable_lun(&lun->cbe_lun);
- ctl_invalidate_lun(&lun->cbe_lun);
+ ctl_remove_lun(&lun->cbe_lun);
mtx_lock(&softc->lock);
}
mtx_unlock(&softc->lock);
mtx_destroy(&softc->lock);
+ sx_destroy(&softc->modify_lock);
return (0);
}
@@ -889,12 +889,18 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc,
int retval;
params = &req->reqdata.rm;
+ sx_xlock(&softc->modify_lock);
mtx_lock(&softc->lock);
- STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
- if (be_lun->cbe_lun.lun_id == params->lun_id)
+ SLIST_FOREACH(be_lun, &softc->lun_list, links) {
+ if (be_lun->cbe_lun.lun_id == params->lun_id) {
+ SLIST_REMOVE(&softc->lun_list, be_lun,
+ ctl_be_ramdisk_lun, links);
+ softc->num_luns--;
break;
+ }
}
mtx_unlock(&softc->lock);
+ sx_xunlock(&softc->modify_lock);
if (be_lun == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
"%s: LUN %u is not managed by the ramdisk backend",
@@ -902,14 +908,6 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc,
goto bailout_error;
}
- retval = ctl_disable_lun(&be_lun->cbe_lun);
- if (retval != 0) {
- snprintf(req->error_str, sizeof(req->error_str),
- "%s: error %d returned from ctl_disable_lun() for "
- "LUN %d", __func__, retval, params->lun_id);
- goto bailout_error;
- }
-
/*
* Set the waiting flag before we invalidate the LUN. Our shutdown
* routine can be called any time after we invalidate the LUN,
@@ -922,10 +920,10 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc,
be_lun->flags |= CTL_BE_RAMDISK_LUN_WAITING;
mtx_unlock(&softc->lock);
- retval = ctl_invalidate_lun(&be_lun->cbe_lun);
+ retval = ctl_remove_lun(&be_lun->cbe_lun);
if (retval != 0) {
snprintf(req->error_str, sizeof(req->error_str),
- "%s: error %d returned from ctl_invalidate_lun() for "
+ "%s: error %d returned from ctl_remove_lun() for "
"LUN %d", __func__, retval, params->lun_id);
mtx_lock(&softc->lock);
be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING;
@@ -935,35 +933,17 @@ ctl_backend_ramdisk_rm(struct ctl_be_ramdisk_softc *softc,
mtx_lock(&softc->lock);
while ((be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) == 0) {
- retval = msleep(be_lun, &softc->lock, PCATCH, "ctlram", 0);
+ retval = msleep(be_lun, &softc->lock, PCATCH, "ctlramrm", 0);
if (retval == EINTR)
break;
}
be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING;
-
- /*
- * We only remove this LUN from the list and free it (below) if
- * retval == 0. If the user interrupted the wait, we just bail out
- * without actually freeing the LUN. We let the shutdown routine
- * free the LUN if that happens.
- */
- if (retval == 0) {
- STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun,
- links);
- softc->num_luns--;
- }
-
- mtx_unlock(&softc->lock);
-
- if (retval == 0) {
- taskqueue_drain_all(be_lun->io_taskqueue);
- taskqueue_free(be_lun->io_taskqueue);
- nvlist_destroy(be_lun->cbe_lun.options);
- free(be_lun->zero_page, M_RAMDISK);
- ctl_backend_ramdisk_freeallpages(be_lun->pages, be_lun->indir);
- sx_destroy(&be_lun->page_lock);
- mtx_destroy(&be_lun->queue_lock);
+ if (be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) {
+ mtx_unlock(&softc->lock);
free(be_lun, M_RAMDISK);
+ } else {
+ mtx_unlock(&softc->lock);
+ return (EINTR);
}
req->status = CTL_LUN_OK;
@@ -995,13 +975,12 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
cbe_lun->options = nvlist_clone(req->args_nvl);
be_lun->params = req->reqdata.create;
be_lun->softc = softc;
- sprintf(be_lun->lunname, "cram%d", softc->num_luns);
if (params->flags & CTL_LUN_FLAG_DEV_TYPE)
cbe_lun->lun_type = params->device_type;
else
cbe_lun->lun_type = T_DIRECT;
- be_lun->flags = CTL_BE_RAMDISK_LUN_UNCONFIGURED;
+ be_lun->flags = 0;
cbe_lun->flags = 0;
value = dnvlist_get_string(cbe_lun->options, "ha_role", NULL);
if (value != NULL) {
@@ -1097,7 +1076,6 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
cbe_lun->req_lun_id = 0;
cbe_lun->lun_shutdown = ctl_backend_ramdisk_lun_shutdown;
- cbe_lun->lun_config_status = ctl_backend_ramdisk_lun_config_status;
cbe_lun->be = &ctl_be_ramdisk_driver;
if ((params->flags & CTL_LUN_FLAG_SERIAL_NUM) == 0) {
snprintf(tmpstr, sizeof(tmpstr), "MYSERIAL%04d",
@@ -1128,18 +1106,18 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
}
STAILQ_INIT(&be_lun->cont_queue);
- sx_init(&be_lun->page_lock, "cram page lock");
+ sx_init(&be_lun->page_lock, "ctlram page");
if (be_lun->cap_bytes == 0) {
be_lun->indir = 0;
be_lun->pages = malloc(be_lun->pblocksize, M_RAMDISK, M_WAITOK);
}
be_lun->zero_page = malloc(be_lun->pblocksize, M_RAMDISK,
M_WAITOK|M_ZERO);
- mtx_init(&be_lun->queue_lock, "cram queue lock", NULL, MTX_DEF);
+ mtx_init(&be_lun->queue_lock, "ctlram queue", NULL, MTX_DEF);
TASK_INIT(&be_lun->io_task, /*priority*/0, ctl_backend_ramdisk_worker,
be_lun);
- be_lun->io_taskqueue = taskqueue_create(be_lun->lunname, M_WAITOK,
+ be_lun->io_taskqueue = taskqueue_create("ctlramtq", M_WAITOK,
taskqueue_thread_enqueue, /*context*/&be_lun->io_taskqueue);
if (be_lun->io_taskqueue == NULL) {
snprintf(req->error_str, sizeof(req->error_str),
@@ -1151,23 +1129,12 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
/*num threads*/1,
/*priority*/PUSER,
/*proc*/control_softc->ctl_proc,
- /*thread name*/
- "%s taskq", be_lun->lunname);
+ /*thread name*/"ramdisk");
if (retval != 0)
goto bailout_error;
- mtx_lock(&softc->lock);
- softc->num_luns++;
- STAILQ_INSERT_TAIL(&softc->lun_list, be_lun, links);
- mtx_unlock(&softc->lock);
-
retval = ctl_add_lun(&be_lun->cbe_lun);
if (retval != 0) {
- mtx_lock(&softc->lock);
- STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun,
- links);
- softc->num_luns--;
- mtx_unlock(&softc->lock);
snprintf(req->error_str, sizeof(req->error_str),
"%s: ctl_add_lun() returned error %d, see dmesg for "
"details", __func__, retval);
@@ -1176,34 +1143,12 @@ ctl_backend_ramdisk_create(struct ctl_be_ramdisk_softc *softc,
}
mtx_lock(&softc->lock);
-
- /*
- * Tell the config_status routine that we're waiting so it won't
- * clean up the LUN in the event of an error.
- */
- be_lun->flags |= CTL_BE_RAMDISK_LUN_WAITING;
-
- while (be_lun->flags & CTL_BE_RAMDISK_LUN_UNCONFIGURED) {
- retval = msleep(be_lun, &softc->lock, PCATCH, "ctlram", 0);
- if (retval == EINTR)
- break;
- }
- be_lun->flags &= ~CTL_BE_RAMDISK_LUN_WAITING;
-
- if (be_lun->flags & CTL_BE_RAMDISK_LUN_CONFIG_ERR) {
- snprintf(req->error_str, sizeof(req->error_str),
- "%s: LUN configuration error, see dmesg for details",
- __func__);
- STAILQ_REMOVE(&softc->lun_list, be_lun, ctl_be_ramdisk_lun,
- links);
- softc->num_luns--;
- mtx_unlock(&softc->lock);
- goto bailout_error;
- } else {
- params->req_lun_id = cbe_lun->lun_id;
- }
+ softc->num_luns++;
+ SLIST_INSERT_HEAD(&softc->lun_list, be_lun, links);
mtx_unlock(&softc->lock);
+ params->req_lun_id = cbe_lun->lun_id;
+
req->status = CTL_LUN_OK;
return (retval);
@@ -1234,9 +1179,9 @@ ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc,
int wasprim;
params = &req->reqdata.modify;
-
+ sx_xlock(&softc->modify_lock);
mtx_lock(&softc->lock);
- STAILQ_FOREACH(be_lun, &softc->lun_list, links) {
+ SLIST_FOREACH(be_lun, &softc->lun_list, links) {
if (be_lun->cbe_lun.lun_id == params->lun_id)
break;
}
@@ -1290,80 +1235,35 @@ ctl_backend_ramdisk_modify(struct ctl_be_ramdisk_softc *softc,
/* Tell the user the exact size we ended up using */
params->lun_size_bytes = be_lun->size_bytes;
+ sx_xunlock(&softc->modify_lock);
req->status = CTL_LUN_OK;
return (0);
bailout_error:
+ sx_xunlock(&softc->modify_lock);
req->status = CTL_LUN_ERROR;
return (0);
}
static void
-ctl_backend_ramdisk_lun_shutdown(void *be_lun)
+ctl_backend_ramdisk_lun_shutdown(void *lun)
{
- struct ctl_be_ramdisk_lun *lun = be_lun;
- struct ctl_be_ramdisk_softc *softc = lun->softc;
-
- mtx_lock(&softc->lock);
- lun->flags |= CTL_BE_RAMDISK_LUN_UNCONFIGURED;
- if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) {
- wakeup(lun);
- } else {
- STAILQ_REMOVE(&softc->lun_list, lun, ctl_be_ramdisk_lun,
- links);
- softc->num_luns--;
- free(be_lun, M_RAMDISK);
- }
- mtx_unlock(&softc->lock);
-}
-
-static void
-ctl_backend_ramdisk_lun_config_status(void *be_lun,
- ctl_lun_config_status status)
-{
- struct ctl_be_ramdisk_lun *lun;
- struct ctl_be_ramdisk_softc *softc;
-
- lun = (struct ctl_be_ramdisk_lun *)be_lun;
- softc = lun->softc;
-
- if (status == CTL_LUN_CONFIG_OK) {
- mtx_lock(&softc->lock);
- lun->flags &= ~CTL_BE_RAMDISK_LUN_UNCONFIGURED;
- if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING)
- wakeup(lun);
- mtx_unlock(&softc->lock);
-
- /*
- * We successfully added the LUN, attempt to enable it.
- */
- if (ctl_enable_lun(&lun->cbe_lun) != 0) {
- printf("%s: ctl_enable_lun() failed!\n", __func__);
- if (ctl_invalidate_lun(&lun->cbe_lun) != 0) {
- printf("%s: ctl_invalidate_lun() failed!\n",
- __func__);
- }
- }
-
- return;
- }
+ struct ctl_be_ramdisk_lun *be_lun = lun;
+ struct ctl_be_ramdisk_softc *softc = be_lun->softc;
+ taskqueue_drain_all(be_lun->io_taskqueue);
+ taskqueue_free(be_lun->io_taskqueue);
+ nvlist_destroy(be_lun->cbe_lun.options);
+ free(be_lun->zero_page, M_RAMDISK);
+ ctl_backend_ramdisk_freeallpages(be_lun->pages, be_lun->indir);
+ sx_destroy(&be_lun->page_lock);
+ mtx_destroy(&be_lun->queue_lock);
mtx_lock(&softc->lock);
- lun->flags &= ~CTL_BE_RAMDISK_LUN_UNCONFIGURED;
-
- /*
- * If we have a user waiting, let him handle the cleanup. If not,
- * clean things up here.
- */
- if (lun->flags & CTL_BE_RAMDISK_LUN_WAITING) {
- lun->flags |= CTL_BE_RAMDISK_LUN_CONFIG_ERR;
- wakeup(lun);
- } else {
- STAILQ_REMOVE(&softc->lun_list, lun, ctl_be_ramdisk_lun,
- links);
- softc->num_luns--;
- free(lun, M_RAMDISK);
- }
+ be_lun->flags |= CTL_BE_RAMDISK_LUN_UNCONFIGURED;
+ if (be_lun->flags & CTL_BE_RAMDISK_LUN_WAITING)
+ wakeup(be_lun);
+ else
+ free(be_lun, M_RAMDISK);
mtx_unlock(&softc->lock);
}