vhost: separate sessions from devices

Session struct will be now allocated inside the
`new_connection` rte_vhost callback. There can be
still only one connection per device, but this
change brings us one step towards supporting more.

Besides the obvious pointer changes, we'll now also
use the session pointer to check if the connection
actually exists. We used to set device vid to -1
when there was no connection but we no longer have
to do that.

Change-Id: I4d062c0b5f093fef132a6a2c9cc29458cbaad414
Signed-off-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/c/437776
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
Darek Stojaczyk 2018-12-14 14:44:46 +01:00 committed by Jim Harris
parent 4086464172
commit f82a175706
6 changed files with 91 additions and 74 deletions

View File

@ -516,8 +516,8 @@ spdk_vhost_session_find_by_vid(int vid)
struct spdk_vhost_dev *vdev;
TAILQ_FOREACH(vdev, &g_spdk_vhost_devices, tailq) {
if (vdev->session.vid == vid) {
return &vdev->session;
if (vdev->session && vdev->session->vid == vid) {
return vdev->session;
}
}
@ -750,7 +750,6 @@ spdk_vhost_dev_register(struct spdk_vhost_dev *vdev, const char *name, const cha
vdev->name = strdup(name);
vdev->path = strdup(path);
vdev->id = ctrlr_num++;
vdev->session.vid = -1;
vdev->lcore = -1;
vdev->cpumask = cpumask;
vdev->registered = true;
@ -775,7 +774,7 @@ out:
int
spdk_vhost_dev_unregister(struct spdk_vhost_dev *vdev)
{
if (vdev->session.vid != -1) {
if (vdev->session) {
SPDK_ERRLOG("Controller %s has still valid connection.\n", vdev->name);
return -EBUSY;
}
@ -1267,16 +1266,23 @@ new_connection(int vid)
return -1;
}
/* since pollers are not running it safe not to use spdk_event here */
vsession = &vdev->session;
if (vsession->vid != -1) {
SPDK_ERRLOG("Session with vid %d already exists.\n", vid);
if (vdev->session != NULL) {
SPDK_ERRLOG("Device %s is already connected.\n", vdev->name);
pthread_mutex_unlock(&g_spdk_vhost_mutex);
return -1;
}
vsession = spdk_dma_zmalloc(sizeof(struct spdk_vhost_session),
SPDK_CACHE_LINE_SIZE, NULL);
if (vsession == NULL) {
SPDK_ERRLOG("spdk_dma_zmalloc failed\n");
pthread_mutex_unlock(&g_spdk_vhost_mutex);
return -1;
}
vsession->vdev = vdev;
vsession->vid = vid;
vdev->session = vsession;
pthread_mutex_unlock(&g_spdk_vhost_mutex);
return 0;
}
@ -1294,8 +1300,8 @@ destroy_connection(int vid)
return;
}
/* since pollers are not running it safe not to use spdk_event here */
vsession->vid = -1;
vsession->vdev->session = NULL;
spdk_dma_free(vsession);
pthread_mutex_unlock(&g_spdk_vhost_mutex);
}

View File

@ -85,8 +85,8 @@ process_blk_request(struct spdk_vhost_blk_task *task, struct spdk_vhost_blk_dev
static void
blk_task_finish(struct spdk_vhost_blk_task *task)
{
assert(task->bvdev->vdev.session.task_cnt > 0);
task->bvdev->vdev.session.task_cnt--;
assert(task->bvdev->vdev.session->task_cnt > 0);
task->bvdev->vdev.session->task_cnt--;
task->used = false;
}
@ -97,7 +97,7 @@ invalid_blk_request(struct spdk_vhost_blk_task *task, uint8_t status)
*task->status = status;
}
spdk_vhost_vq_used_ring_enqueue(&task->bvdev->vdev.session, task->vq, task->req_idx,
spdk_vhost_vq_used_ring_enqueue(task->bvdev->vdev.session, task->vq, task->req_idx,
task->used_len);
blk_task_finish(task);
SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK_DATA, "Invalid request (status=%" PRIu8")\n", status);
@ -119,7 +119,7 @@ blk_iovs_setup(struct spdk_vhost_dev *vdev, struct spdk_vhost_virtqueue *vq, uin
uint32_t desc_table_size, len = 0;
int rc;
rc = spdk_vhost_vq_get_desc(&vdev->session, vq, req_idx, &desc, &desc_table, &desc_table_size);
rc = spdk_vhost_vq_get_desc(vdev->session, vq, req_idx, &desc, &desc_table, &desc_table_size);
if (rc != 0) {
SPDK_ERRLOG("%s: Invalid descriptor at index %"PRIu16".\n", vdev->name, req_idx);
return -1;
@ -136,7 +136,7 @@ blk_iovs_setup(struct spdk_vhost_dev *vdev, struct spdk_vhost_virtqueue *vq, uin
return -1;
}
if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(&vdev->session, iovs, &cnt, desc))) {
if (spdk_unlikely(spdk_vhost_vring_desc_to_iov(vdev->session, iovs, &cnt, desc))) {
SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "Invalid descriptor %" PRIu16" (req_idx = %"PRIu16").\n",
req_idx, cnt);
return -1;
@ -174,7 +174,7 @@ static void
blk_request_finish(bool success, struct spdk_vhost_blk_task *task)
{
*task->status = success ? VIRTIO_BLK_S_OK : VIRTIO_BLK_S_IOERR;
spdk_vhost_vq_used_ring_enqueue(&task->bvdev->vdev.session, task->vq, task->req_idx,
spdk_vhost_vq_used_ring_enqueue(task->bvdev->vdev.session, task->vq, task->req_idx,
task->used_len);
SPDK_DEBUGLOG(SPDK_LOG_VHOST_BLK, "Finished task (%p) req_idx=%d\n status: %s\n", task,
task->req_idx, success ? "OK" : "FAIL");
@ -377,7 +377,7 @@ static void
process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
{
struct spdk_vhost_blk_task *task;
struct spdk_vhost_session *vsession = &bvdev->vdev.session;
struct spdk_vhost_session *vsession = bvdev->vdev.session;
int rc;
uint16_t reqs[32];
uint16_t reqs_cnt, i;
@ -427,7 +427,7 @@ static int
vdev_worker(void *arg)
{
struct spdk_vhost_blk_dev *bvdev = arg;
struct spdk_vhost_session *vsession = &bvdev->vdev.session;
struct spdk_vhost_session *vsession = bvdev->vdev.session;
uint16_t q_idx;
for (q_idx = 0; q_idx < vsession->max_queues; q_idx++) {
@ -442,7 +442,7 @@ vdev_worker(void *arg)
static void
no_bdev_process_vq(struct spdk_vhost_blk_dev *bvdev, struct spdk_vhost_virtqueue *vq)
{
struct spdk_vhost_session *vsession = &bvdev->vdev.session;
struct spdk_vhost_session *vsession = bvdev->vdev.session;
struct iovec iovs[SPDK_VHOST_IOVS_MAX];
uint32_t length;
uint16_t iovcnt, req_idx;
@ -464,7 +464,7 @@ static int
no_bdev_vdev_worker(void *arg)
{
struct spdk_vhost_blk_dev *bvdev = arg;
struct spdk_vhost_session *vsession = &bvdev->vdev.session;
struct spdk_vhost_session *vsession = bvdev->vdev.session;
uint16_t q_idx;
for (q_idx = 0; q_idx < vsession->max_queues; q_idx++) {
@ -534,7 +534,7 @@ bdev_remove_cb(void *remove_ctx)
static void
free_task_pool(struct spdk_vhost_blk_dev *bvdev)
{
struct spdk_vhost_session *vsession = &bvdev->vdev.session;
struct spdk_vhost_session *vsession = bvdev->vdev.session;
struct spdk_vhost_virtqueue *vq;
uint16_t i;
@ -552,7 +552,7 @@ free_task_pool(struct spdk_vhost_blk_dev *bvdev)
static int
alloc_task_pool(struct spdk_vhost_blk_dev *bvdev)
{
struct spdk_vhost_session *vsession = &bvdev->vdev.session;
struct spdk_vhost_session *vsession = bvdev->vdev.session;
struct spdk_vhost_virtqueue *vq;
struct spdk_vhost_blk_task *task;
uint32_t task_cnt;
@ -602,7 +602,7 @@ static int
spdk_vhost_blk_start(struct spdk_vhost_dev *vdev, void *event_ctx)
{
struct spdk_vhost_blk_dev *bvdev;
struct spdk_vhost_session *vsession = &vdev->session;
struct spdk_vhost_session *vsession = vdev->session;
int i, rc = 0;
bvdev = to_blk_dev(vdev);
@ -650,7 +650,7 @@ static int
destroy_device_poller_cb(void *arg)
{
struct spdk_vhost_blk_dev *bvdev = arg;
struct spdk_vhost_session *vsession = &bvdev->vdev.session;
struct spdk_vhost_session *vsession = bvdev->vdev.session;
int i;
if (vsession->task_cnt > 0) {

View File

@ -133,6 +133,23 @@ struct spdk_vhost_dev_backend {
int (*remove_device)(struct spdk_vhost_dev *vdev);
};
struct spdk_vhost_session {
struct spdk_vhost_dev *vdev;
/* rte_vhost connection ID. */
int vid;
struct rte_vhost_memory *mem;
int task_cnt;
uint16_t max_queues;
uint64_t negotiated_features;
struct spdk_vhost_virtqueue virtqueue[SPDK_VHOST_MAX_VQUEUES];
};
struct spdk_vhost_dev {
char *name;
char *path;
@ -164,22 +181,7 @@ struct spdk_vhost_dev {
uint64_t stats_check_interval;
/* Active connection to the device */
struct spdk_vhost_session {
struct spdk_vhost_dev *vdev;
/* rte_vhost connection ID. */
int vid;
struct rte_vhost_memory *mem;
int task_cnt;
uint16_t max_queues;
uint64_t negotiated_features;
struct spdk_vhost_virtqueue virtqueue[SPDK_VHOST_MAX_VQUEUES];
} session;
struct spdk_vhost_session *session;
TAILQ_ENTRY(spdk_vhost_dev) tailq;
};

View File

@ -248,7 +248,7 @@ static int
spdk_nvme_map_prps(struct spdk_vhost_nvme_dev *nvme, struct spdk_nvme_cmd *cmd,
struct spdk_vhost_nvme_task *task, uint32_t len)
{
struct spdk_vhost_session *vsession = &nvme->vdev.session;
struct spdk_vhost_session *vsession = nvme->vdev.session;
uint64_t prp1, prp2;
void *vva;
uint32_t i;
@ -699,7 +699,7 @@ static int
vhost_nvme_doorbell_buffer_config(struct spdk_vhost_nvme_dev *nvme,
struct spdk_nvme_cmd *cmd, struct spdk_nvme_cpl *cpl)
{
struct spdk_vhost_session *vsession = &nvme->vdev.session;
struct spdk_vhost_session *vsession = nvme->vdev.session;
uint64_t dbs_dma_addr, eis_dma_addr;
dbs_dma_addr = cmd->dptr.prp.prp1;
@ -765,7 +765,7 @@ vhost_nvme_create_io_sq(struct spdk_vhost_nvme_dev *nvme,
sq->size = qsize + 1;
sq->sq_head = sq->sq_tail = 0;
requested_len = sizeof(struct spdk_nvme_cmd) * sq->size;
sq->sq_cmd = spdk_vhost_gpa_to_vva(&nvme->vdev.session, dma_addr, requested_len);
sq->sq_cmd = spdk_vhost_gpa_to_vva(nvme->vdev.session, dma_addr, requested_len);
if (!sq->sq_cmd) {
return -1;
}
@ -848,7 +848,7 @@ vhost_nvme_create_io_cq(struct spdk_vhost_nvme_dev *nvme,
cq->guest_signaled_cq_head = 0;
cq->need_signaled_cnt = 0;
requested_len = sizeof(struct spdk_nvme_cpl) * cq->size;
cq->cq_cqe = spdk_vhost_gpa_to_vva(&nvme->vdev.session, dma_addr, requested_len);
cq->cq_cqe = spdk_vhost_gpa_to_vva(nvme->vdev.session, dma_addr, requested_len);
if (!cq->cq_cqe) {
return -1;
}
@ -893,7 +893,7 @@ spdk_vhost_nvme_get_by_name(int vid)
struct spdk_vhost_nvme_dev *nvme;
TAILQ_FOREACH(nvme, &g_nvme_ctrlrs, tailq) {
if (nvme->vdev.session.vid == vid) {
if (nvme->vdev.session != NULL && nvme->vdev.session->vid == vid) {
return nvme;
}
}
@ -1084,7 +1084,7 @@ spdk_vhost_nvme_start_device(struct spdk_vhost_dev *vdev, void *event_ctx)
return -1;
}
SPDK_NOTICELOG("Start Device %u, Path %s, lcore %d\n", vdev->session.vid,
SPDK_NOTICELOG("Start Device %u, Path %s, lcore %d\n", vdev->session->vid,
vdev->path, vdev->lcore);
for (i = 0; i < nvme->num_ns; i++) {
@ -1171,7 +1171,7 @@ spdk_vhost_nvme_stop_device(struct spdk_vhost_dev *vdev, void *event_ctx)
}
free_task_pool(nvme);
SPDK_NOTICELOG("Stopping Device %u, Path %s\n", vdev->session.vid, vdev->path);
SPDK_NOTICELOG("Stopping Device %u, Path %s\n", vdev->session->vid, vdev->path);
nvme->destroy_ctx.event_ctx = event_ctx;
spdk_poller_unregister(&nvme->requestq_poller);

View File

@ -134,7 +134,7 @@ static void
spdk_vhost_scsi_task_free_cb(struct spdk_scsi_task *scsi_task)
{
struct spdk_vhost_scsi_task *task = SPDK_CONTAINEROF(scsi_task, struct spdk_vhost_scsi_task, scsi);
struct spdk_vhost_session *vsession = &task->svdev->vdev.session;
struct spdk_vhost_session *vsession = task->svdev->vdev.session;
assert(vsession->task_cnt > 0);
vsession->task_cnt--;
@ -170,7 +170,7 @@ static void
eventq_enqueue(struct spdk_vhost_scsi_dev *svdev, unsigned scsi_dev_num, uint32_t event,
uint32_t reason)
{
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
struct spdk_vhost_virtqueue *vq;
struct vring_desc *desc, *desc_table;
struct virtio_scsi_event *desc_ev;
@ -223,7 +223,7 @@ out:
static void
submit_completion(struct spdk_vhost_scsi_task *task)
{
struct spdk_vhost_session *vsession = &task->svdev->vdev.session;
struct spdk_vhost_session *vsession = task->svdev->vdev.session;
spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
task->used_len);
@ -280,7 +280,7 @@ mgmt_task_submit(struct spdk_vhost_scsi_task *task, enum spdk_scsi_task_func fun
static void
invalid_request(struct spdk_vhost_scsi_task *task)
{
struct spdk_vhost_session *vsession = &task->svdev->vdev.session;
struct spdk_vhost_session *vsession = task->svdev->vdev.session;
spdk_vhost_vq_used_ring_enqueue(vsession, task->vq, task->req_idx,
task->used_len);
@ -321,7 +321,7 @@ static void
process_ctrl_request(struct spdk_vhost_scsi_task *task)
{
struct spdk_vhost_dev *vdev = &task->svdev->vdev;
struct spdk_vhost_session *vsession = &vdev->session;
struct spdk_vhost_session *vsession = vdev->session;
struct vring_desc *desc, *desc_table;
struct virtio_scsi_ctrl_tmf_req *ctrl_req;
struct virtio_scsi_ctrl_an_resp *an_resp;
@ -423,7 +423,7 @@ task_data_setup(struct spdk_vhost_scsi_task *task,
struct virtio_scsi_cmd_req **req)
{
struct spdk_vhost_dev *vdev = &task->svdev->vdev;
struct spdk_vhost_session *vsession = &vdev->session;
struct spdk_vhost_session *vsession = vdev->session;
struct vring_desc *desc, *desc_table;
struct iovec *iovs = task->iovs;
uint16_t iovcnt = 0;
@ -586,7 +586,7 @@ process_request(struct spdk_vhost_scsi_task *task)
static void
process_controlq(struct spdk_vhost_scsi_dev *svdev, struct spdk_vhost_virtqueue *vq)
{
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
struct spdk_vhost_scsi_task *task;
uint16_t reqs[32];
uint16_t reqs_cnt, i;
@ -619,7 +619,7 @@ process_controlq(struct spdk_vhost_scsi_dev *svdev, struct spdk_vhost_virtqueue
static void
process_requestq(struct spdk_vhost_scsi_dev *svdev, struct spdk_vhost_virtqueue *vq)
{
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
struct spdk_vhost_scsi_task *task;
uint16_t reqs[32];
uint16_t reqs_cnt, i;
@ -673,7 +673,7 @@ static int
vdev_mgmt_worker(void *arg)
{
struct spdk_vhost_scsi_dev *svdev = arg;
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
process_removed_devs(svdev);
spdk_vhost_vq_used_signal(vsession, &vsession->virtqueue[VIRTIO_SCSI_EVENTQ]);
@ -688,7 +688,7 @@ static int
vdev_worker(void *arg)
{
struct spdk_vhost_scsi_dev *svdev = arg;
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
uint32_t q_idx;
for (q_idx = VIRTIO_SCSI_REQUESTQ; q_idx < vsession->max_queues; q_idx++) {
@ -793,7 +793,7 @@ spdk_vhost_scsi_lun_hotremove(const struct spdk_scsi_lun *lun, void *arg)
assert(lun != NULL);
assert(svdev != NULL);
if (svdev->vdev.lcore != -1 &&
!spdk_vhost_dev_has_feature(&svdev->vdev.session, VIRTIO_SCSI_F_HOTPLUG)) {
!spdk_vhost_dev_has_feature(svdev->vdev.session, VIRTIO_SCSI_F_HOTPLUG)) {
SPDK_WARNLOG("%s: hotremove is not enabled for this controller.\n", svdev->vdev.name);
return;
}
@ -873,7 +873,7 @@ spdk_vhost_scsi_dev_add_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_num,
spdk_scsi_dev_allocate_io_channels(svdev->scsi_dev[scsi_tgt_num]);
if (spdk_vhost_dev_has_feature(&vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
if (spdk_vhost_dev_has_feature(vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
eventq_enqueue(svdev, scsi_tgt_num, VIRTIO_SCSI_T_TRANSPORT_RESET,
VIRTIO_SCSI_EVT_RESET_RESCAN);
} else {
@ -922,7 +922,7 @@ spdk_vhost_scsi_dev_remove_tgt(struct spdk_vhost_dev *vdev, unsigned scsi_tgt_nu
return rc;
}
if (!spdk_vhost_dev_has_feature(&vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
if (!spdk_vhost_dev_has_feature(vdev->session, VIRTIO_SCSI_F_HOTPLUG)) {
SPDK_WARNLOG("%s: 'Target %u' is in use and hot-detach is not enabled for this controller.\n",
svdev->vdev.name, scsi_tgt_num);
return -ENOTSUP;
@ -1015,7 +1015,7 @@ spdk_vhost_scsi_controller_construct(void)
static void
free_task_pool(struct spdk_vhost_scsi_dev *svdev)
{
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
struct spdk_vhost_virtqueue *vq;
uint16_t i;
@ -1033,7 +1033,7 @@ free_task_pool(struct spdk_vhost_scsi_dev *svdev)
static int
alloc_task_pool(struct spdk_vhost_scsi_dev *svdev)
{
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
struct spdk_vhost_virtqueue *vq;
struct spdk_vhost_scsi_task *task;
uint32_t task_cnt;
@ -1082,7 +1082,7 @@ static int
spdk_vhost_scsi_start(struct spdk_vhost_dev *vdev, void *event_ctx)
{
struct spdk_vhost_scsi_dev *svdev;
struct spdk_vhost_session *vsession = &vdev->session;
struct spdk_vhost_session *vsession = vdev->session;
uint32_t i;
int rc;
@ -1132,7 +1132,7 @@ static int
destroy_device_poller_cb(void *arg)
{
struct spdk_vhost_scsi_dev *svdev = arg;
struct spdk_vhost_session *vsession = &svdev->vdev.session;
struct spdk_vhost_session *vsession = svdev->vdev.session;
uint32_t i;
if (vsession->task_cnt > 0) {

View File

@ -152,6 +152,7 @@ static void
start_vdev(struct spdk_vhost_dev *vdev)
{
struct rte_vhost_memory *mem;
int rc;
mem = calloc(1, sizeof(*mem) + 2 * sizeof(struct rte_vhost_mem_region));
SPDK_CU_ASSERT_FATAL(mem != NULL);
@ -164,22 +165,29 @@ start_vdev(struct spdk_vhost_dev *vdev)
mem->regions[1].host_user_addr = 0x2000000;
vdev->lcore = 0;
vdev->session.vid = 0;
vdev->session.mem = mem;
assert(vdev->session == NULL);
/* spdk_vhost_dev must be allocated on a cache line boundary. */
rc = posix_memalign((void **)&vdev->session, 64, sizeof(*vdev->session));
CU_ASSERT(rc == 0);
SPDK_CU_ASSERT_FATAL(vdev->session != NULL);
vdev->session->vid = 0;
vdev->session->mem = mem;
}
static void
stop_vdev(struct spdk_vhost_dev *vdev)
{
free(vdev->session.mem);
vdev->session.mem = NULL;
vdev->session.vid = -1;
free(vdev->session->mem);
free(vdev->session);
vdev->session = NULL;
}
static void
cleanup_vdev(struct spdk_vhost_dev *vdev)
{
stop_vdev(vdev);
if (vdev->session) {
stop_vdev(vdev);
}
spdk_vhost_dev_unregister(vdev);
free(vdev);
}
@ -198,7 +206,7 @@ desc_to_iov_test(void)
SPDK_CU_ASSERT_FATAL(rc == 0 && vdev);
start_vdev(vdev);
vsession = &vdev->session;
vsession = vdev->session;
/* Test simple case where iov falls fully within a 2MB page. */
desc.addr = 0x110000;
@ -310,12 +318,13 @@ session_find_by_vid_test(void)
rc = alloc_vdev(&vdev, "vdev_name_0", "0x1");
SPDK_CU_ASSERT_FATAL(rc == 0 && vdev);
start_vdev(vdev);
tmp = spdk_vhost_session_find_by_vid(vdev->session.vid);
CU_ASSERT(tmp == &vdev->session);
tmp = spdk_vhost_session_find_by_vid(vdev->session->vid);
CU_ASSERT(tmp == vdev->session);
/* Search for a device with incorrect vid */
tmp = spdk_vhost_session_find_by_vid(vdev->session.vid + 0xFF);
tmp = spdk_vhost_session_find_by_vid(vdev->session->vid + 0xFF);
CU_ASSERT(tmp == NULL);
cleanup_vdev(vdev);