vhost: changed dev_construct()/destruct() to dev_load()/unload()

Since vhost_scsi::new_device() would look mostly the same in vhost_blk,
most of it's logic has been moved into spdk_vhost_dev_construct(),
which is now renamed to spdk_vhost_dev_load().

Change-Id: Ic6db93273f916bd021c2ff68946706d055a514d6
Signed-off-by: Dariusz Stojaczyk <dariuszx.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/362547
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK Automated Test System <sys_sgsw@intel.com>
Reviewed-by: Daniel Verkamp <daniel.verkamp@intel.com>
This commit is contained in:
Dariusz Stojaczyk 2017-05-25 16:12:31 +02:00 committed by Daniel Verkamp
parent d7054e23b7
commit 3671543a5b
3 changed files with 86 additions and 89 deletions

View File

@ -166,62 +166,6 @@ spdk_vhost_dev_find_by_vid(int vid)
return NULL; return NULL;
} }
void
spdk_vhost_dev_destruct(struct spdk_vhost_dev *vdev)
{
struct rte_vhost_vring *q;
uint16_t i;
for (i = 0; i < vdev->num_queues; i++) {
q = &vdev->virtqueue[i];
rte_vhost_set_vhost_vring_last_idx(vdev->vid, i, q->last_avail_idx, q->last_used_idx);
}
free(vdev->mem);
}
int
spdk_vhost_dev_construct(struct spdk_vhost_dev *vdev)
{
int vid = vdev->vid;
uint16_t num_queues = rte_vhost_get_vring_num(vid);
uint16_t i;
if (num_queues > MAX_VHOST_VRINGS) {
SPDK_ERRLOG("vhost device %d: Too many queues (%"PRIu16"). Max %"PRIu16"\n", vid, num_queues,
MAX_VHOST_VRINGS);
return -1;
}
for (i = 0; i < num_queues; i++) {
if (rte_vhost_get_vhost_vring(vid, i, &vdev->virtqueue[i])) {
SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i);
return -1;
}
/* Disable notifications. */
if (rte_vhost_enable_guest_notification(vid, i, 0) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to disable guest notification on queue %"PRIu16"\n", vid, i);
return -1;
}
}
vdev->num_queues = num_queues;
if (rte_vhost_get_negotiated_features(vid, &vdev->negotiated_features) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
return -1;
}
if (rte_vhost_get_mem_table(vid, &vdev->mem) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid);
return -1;
}
return 0;
}
#define SHIFT_2MB 21 #define SHIFT_2MB 21
#define SIZE_2MB (1ULL << SHIFT_2MB) #define SIZE_2MB (1ULL << SHIFT_2MB)
#define FLOOR_2MB(x) (((uintptr_t)x) / SIZE_2MB) << SHIFT_2MB #define FLOOR_2MB(x) (((uintptr_t)x) / SIZE_2MB) << SHIFT_2MB
@ -283,7 +227,7 @@ spdk_vhost_dev_task_unref(struct spdk_vhost_dev *vdev)
vdev->task_cnt--; vdev->task_cnt--;
} }
void static void
spdk_vhost_free_reactor(uint32_t lcore) spdk_vhost_free_reactor(uint32_t lcore)
{ {
g_num_ctrlrs[lcore]--; g_num_ctrlrs[lcore]--;
@ -487,7 +431,7 @@ spdk_vhost_dev_get_cpumask(struct spdk_vhost_dev *vdev)
return vdev->cpumask; return vdev->cpumask;
} }
uint32_t static uint32_t
spdk_vhost_allocate_reactor(uint64_t cpumask) spdk_vhost_allocate_reactor(uint64_t cpumask)
{ {
uint32_t i, selected_core; uint32_t i, selected_core;
@ -517,6 +461,86 @@ spdk_vhost_allocate_reactor(uint64_t cpumask)
return selected_core; return selected_core;
} }
void
spdk_vhost_dev_unload(struct spdk_vhost_dev *vdev)
{
struct rte_vhost_vring *q;
uint16_t i;
for (i = 0; i < vdev->num_queues; i++) {
q = &vdev->virtqueue[i];
rte_vhost_set_vhost_vring_last_idx(vdev->vid, i, q->last_avail_idx, q->last_used_idx);
}
free(vdev->mem);
spdk_vhost_free_reactor(vdev->lcore);
vdev->lcore = -1;
}
struct spdk_vhost_dev *
spdk_vhost_dev_load(int vid)
{
struct spdk_vhost_dev *vdev;
char ifname[PATH_MAX];
uint16_t num_queues = rte_vhost_get_vring_num(vid);
uint16_t i;
if (rte_vhost_get_ifname(vid, ifname, PATH_MAX) < 0) {
SPDK_ERRLOG("Couldn't get a valid ifname for device %d\n", vid);
return NULL;
}
vdev = spdk_vhost_dev_find(ifname);
if (vdev == NULL) {
SPDK_ERRLOG("Controller %s not found.\n", ifname);
return NULL;
}
if (vdev->lcore != -1) {
SPDK_ERRLOG("Controller %s already connected.\n", ifname);
return NULL;
}
if (num_queues > MAX_VHOST_VRINGS) {
SPDK_ERRLOG("vhost device %d: Too many queues (%"PRIu16"). Max %"PRIu16"\n", vid, num_queues,
MAX_VHOST_VRINGS);
return NULL;
}
for (i = 0; i < num_queues; i++) {
if (rte_vhost_get_vhost_vring(vid, i, &vdev->virtqueue[i])) {
SPDK_ERRLOG("vhost device %d: Failed to get information of queue %"PRIu16"\n", vid, i);
return NULL;
}
/* Disable notifications. */
if (rte_vhost_enable_guest_notification(vid, i, 0) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to disable guest notification on queue %"PRIu16"\n", vid, i);
return NULL;
}
}
vdev->vid = vid;
vdev->num_queues = num_queues;
if (rte_vhost_get_negotiated_features(vid, &vdev->negotiated_features) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to get negotiated driver features\n", vid);
return NULL;
}
if (rte_vhost_get_mem_table(vid, &vdev->mem) != 0) {
SPDK_ERRLOG("vhost device %d: Failed to get guest memory table\n", vid);
return NULL;
}
vdev->lcore = spdk_vhost_allocate_reactor(vdev->cpumask);
return vdev;
}
void void
spdk_vhost_startup(void *arg1, void *arg2) spdk_vhost_startup(void *arg1, void *arg2)
{ {

View File

@ -66,15 +66,11 @@ struct spdk_vhost_dev_backend {
const struct vhost_device_ops ops; const struct vhost_device_ops ops;
}; };
void spdk_vhost_dev_mem_register(struct spdk_vhost_dev *vdev); void spdk_vhost_dev_mem_register(struct spdk_vhost_dev *vdev);
void spdk_vhost_dev_mem_unregister(struct spdk_vhost_dev *vdev); void spdk_vhost_dev_mem_unregister(struct spdk_vhost_dev *vdev);
void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr); void *spdk_vhost_gpa_to_vva(struct spdk_vhost_dev *vdev, uint64_t addr);
uint32_t spdk_vhost_allocate_reactor(uint64_t cpumask);
void spdk_vhost_free_reactor(uint32_t lcore);
uint16_t spdk_vhost_vq_avail_ring_get(struct rte_vhost_vring *vq, uint16_t *reqs, uint16_t spdk_vhost_vq_avail_ring_get(struct rte_vhost_vring *vq, uint16_t *reqs,
uint16_t reqs_len); uint16_t reqs_len);
bool spdk_vhost_vq_should_notify(struct spdk_vhost_dev *vdev, struct rte_vhost_vring *vq); bool spdk_vhost_vq_should_notify(struct spdk_vhost_dev *vdev, struct rte_vhost_vring *vq);
@ -89,10 +85,10 @@ struct vring_desc *spdk_vhost_vring_desc_get_next(struct vring_desc *vq_desc,
bool spdk_vhost_vring_desc_is_wr(struct vring_desc *cur_desc); bool spdk_vhost_vring_desc_is_wr(struct vring_desc *cur_desc);
struct spdk_vhost_dev *spdk_vhost_dev_find_by_vid(int vid); struct spdk_vhost_dev *spdk_vhost_dev_find_by_vid(int vid);
int spdk_vhost_dev_construct(struct spdk_vhost_dev *dev); struct spdk_vhost_dev *spdk_vhost_dev_load(int vid);
int spdk_vhost_dev_register(struct spdk_vhost_dev *dev, int spdk_vhost_dev_register(struct spdk_vhost_dev *dev,
const struct spdk_vhost_dev_backend *backend); const struct spdk_vhost_dev_backend *backend);
int spdk_vhost_dev_unregister(struct spdk_vhost_dev *vdev); int spdk_vhost_dev_unregister(struct spdk_vhost_dev *vdev);
void spdk_vhost_dev_destruct(struct spdk_vhost_dev *dev); void spdk_vhost_dev_unload(struct spdk_vhost_dev *dev);
#endif /* SPDK_VHOST_INTERNAL_H */ #endif /* SPDK_VHOST_INTERNAL_H */

View File

@ -850,33 +850,13 @@ new_device(int vid)
{ {
struct spdk_vhost_dev *vdev = NULL; struct spdk_vhost_dev *vdev = NULL;
struct spdk_event *event; struct spdk_event *event;
char ifname[PATH_MAX];
sem_t added; sem_t added;
if (rte_vhost_get_ifname(vid, ifname, PATH_MAX) < 0) { vdev = spdk_vhost_dev_load(vid);
SPDK_ERRLOG("Couldn't get a valid ifname for device %d\n", vid);
return -1;
}
vdev = spdk_vhost_dev_find(ifname);
if (vdev == NULL) { if (vdev == NULL) {
SPDK_ERRLOG("Controller %s not found.\n", ifname);
return -1; return -1;
} }
if (vdev->lcore != -1) {
SPDK_ERRLOG("Controller %s already connected.\n", ifname);
return -1;
}
vdev->vid = vid;
if (spdk_vhost_dev_construct(vdev) != 0) {
return -1;
}
vdev->lcore = spdk_vhost_allocate_reactor(vdev->cpumask);
event = vhost_sem_event_alloc(vdev->lcore, add_vdev_cb, vdev, &added); event = vhost_sem_event_alloc(vdev->lcore, add_vdev_cb, vdev, &added);
spdk_event_call(event); spdk_event_call(event);
if (vhost_sem_timedwait(&added, 1)) if (vhost_sem_timedwait(&added, 1))
@ -923,10 +903,7 @@ destroy_device(int vid)
if (vhost_sem_timedwait(&done_sem, 1)) if (vhost_sem_timedwait(&done_sem, 1))
rte_panic("%s: failed to unregister poller.\n", vdev->name); rte_panic("%s: failed to unregister poller.\n", vdev->name);
spdk_vhost_free_reactor(vdev->lcore); spdk_vhost_dev_unload(vdev);
vdev->lcore = -1;
spdk_vhost_dev_destruct(vdev);
} }
SPDK_LOG_REGISTER_TRACE_FLAG("vhost", SPDK_TRACE_VHOST) SPDK_LOG_REGISTER_TRACE_FLAG("vhost", SPDK_TRACE_VHOST)