vhost: call start/stop backend callbacks directly on the DPDK thread

Particular backends will now be responsible for sending
events to vsession->lcore. This was previously done by
the generic vhost layer, but since some backends will
need different lcore assignment policies soon, we need
to give them more power now.

Change-Id: I72cbbccb9d5a5b2358acca6d4b6bb882131937af
Signed-off-by: Darek Stojaczyk <dariusz.stojaczyk@intel.com>
Reviewed-on: https://review.gerrithub.io/c/441580
Reviewed-by: Pawel Wodkowski <pawelx.wodkowski@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Changpeng Liu <changpeng.liu@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
This commit is contained in:
Darek Stojaczyk 2019-01-22 12:57:09 +01:00 committed by Jim Harris
parent 6307086792
commit 14a6ca08db
5 changed files with 104 additions and 45 deletions

View File

@ -819,7 +819,7 @@ spdk_vhost_allocate_reactor(struct spdk_cpuset *cpumask)
}
void
spdk_vhost_dev_backend_event_done(void *event_ctx, int response)
spdk_vhost_session_event_done(void *event_ctx, int response)
{
struct spdk_vhost_session_fn_ctx *ctx = event_ctx;
@ -883,9 +883,10 @@ out_unlock:
free(ctx);
}
static int
_spdk_vhost_event_send(struct spdk_vhost_session *vsession, spdk_vhost_session_fn cb_fn,
unsigned timeout_sec, const char *errmsg)
int
spdk_vhost_session_send_event(struct spdk_vhost_session *vsession,
spdk_vhost_session_fn cb_fn, unsigned timeout_sec,
const char *errmsg)
{
struct spdk_vhost_session_fn_ctx ev_ctx = {0};
struct spdk_event *ev;
@ -969,7 +970,7 @@ stop_device(int vid)
return;
}
rc = _spdk_vhost_event_send(vsession, vdev->backend->stop_session, 3, "stop session");
rc = vdev->backend->stop_session(vsession);
if (rc != 0) {
SPDK_ERRLOG("Couldn't stop device with vid %d.\n", vid);
pthread_mutex_unlock(&g_spdk_vhost_mutex);
@ -1064,7 +1065,7 @@ start_device(int vid)
spdk_vhost_session_set_coalescing(vdev, vsession, NULL);
vsession->lcore = spdk_vhost_allocate_reactor(vdev->cpumask);
spdk_vhost_session_mem_register(vsession);
rc = _spdk_vhost_event_send(vsession, vdev->backend->start_session, 3, "start session");
rc = vdev->backend->start_session(vsession);
if (rc != 0) {
spdk_vhost_session_mem_unregister(vsession);
free(vsession->mem);

View File

@ -665,8 +665,8 @@ alloc_task_pool(struct spdk_vhost_blk_session *bvsession)
}
static int
spdk_vhost_blk_start(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
spdk_vhost_blk_start_cb(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
{
struct spdk_vhost_blk_dev *bvdev;
struct spdk_vhost_blk_session *bvsession;
@ -712,10 +712,17 @@ spdk_vhost_blk_start(struct spdk_vhost_dev *vdev,
SPDK_INFOLOG(SPDK_LOG_VHOST, "Started poller for vhost controller %s on lcore %d\n",
vdev->name, vsession->lcore);
out:
spdk_vhost_dev_backend_event_done(event_ctx, rc);
spdk_vhost_session_event_done(event_ctx, rc);
return rc;
}
static int
spdk_vhost_blk_start(struct spdk_vhost_session *vsession)
{
return spdk_vhost_session_send_event(vsession, spdk_vhost_blk_start_cb,
3, "start session");
}
static int
destroy_session_poller_cb(void *arg)
{
@ -741,14 +748,14 @@ destroy_session_poller_cb(void *arg)
free_task_pool(bvsession);
spdk_poller_unregister(&bvsession->destroy_ctx.poller);
spdk_vhost_dev_backend_event_done(bvsession->destroy_ctx.event_ctx, 0);
spdk_vhost_session_event_done(bvsession->destroy_ctx.event_ctx, 0);
return -1;
}
static int
spdk_vhost_blk_stop(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
spdk_vhost_blk_stop_cb(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
{
struct spdk_vhost_blk_session *bvsession;
@ -765,10 +772,17 @@ spdk_vhost_blk_stop(struct spdk_vhost_dev *vdev,
return 0;
err:
spdk_vhost_dev_backend_event_done(event_ctx, -1);
spdk_vhost_session_event_done(event_ctx, -1);
return -1;
}
static int
spdk_vhost_blk_stop(struct spdk_vhost_session *vsession)
{
return spdk_vhost_session_send_event(vsession, spdk_vhost_blk_stop_cb,
3, "stop session");
}
static void
spdk_vhost_blk_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
{

View File

@ -201,13 +201,8 @@ struct spdk_vhost_dev_backend {
*/
size_t session_ctx_size;
/**
* Callbacks for starting and pausing a session.
* The third param is an event context that has to be
* passed to spdk_vhost_dev_backend_event_done().
*/
spdk_vhost_session_fn start_session;
spdk_vhost_session_fn stop_session;
int (*start_session)(struct spdk_vhost_session *vsession);
int (*stop_session)(struct spdk_vhost_session *vsession);
int (*vhost_get_config)(struct spdk_vhost_dev *vdev, uint8_t *config, uint32_t len);
int (*vhost_set_config)(struct spdk_vhost_dev *vdev, uint8_t *config,
@ -311,7 +306,35 @@ void spdk_vhost_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_wri
*/
void spdk_vhost_dev_foreach_session(struct spdk_vhost_dev *dev,
spdk_vhost_session_fn fn, void *arg);
void spdk_vhost_dev_backend_event_done(void *event_ctx, int response);
/**
* Call the provided function on the session's lcore and block until
* spdk_vhost_session_event_done() is called.
*
* As an optimization, this function will unlock the vhost mutex
* while it's waiting, which makes it prone to data races.
* Practically, it is only useful for session start/stop and still
* has to be used with extra caution.
*
* \param vsession vhost session
* \param cb_fn the function to call. The void *arg parameter in cb_fn
* must be passed to spdk_vhost_session_event_done().
* \param timeout_sec timeout in seconds. This function will still
* block after the timeout expires, but will print the provided errmsg.
* \param errmsg error message to print once the timeout expires
* \return return the code passed to spdk_vhost_session_event_done().
*/
int spdk_vhost_session_send_event(struct spdk_vhost_session *vsession,
spdk_vhost_session_fn cb_fn, unsigned timeout_sec, const char *errmsg);
/**
* Finish a blocking spdk_vhost_session_send_event() call.
*
* \param event_ctx event context
* \param response return code
*/
void spdk_vhost_session_event_done(void *event_ctx, int response);
void spdk_vhost_lock(void);
void spdk_vhost_unlock(void);
int spdk_remove_vhost_controller(struct spdk_vhost_dev *vdev);

View File

@ -1066,12 +1066,9 @@ alloc_task_pool(struct spdk_vhost_nvme_dev *nvme)
return 0;
}
/* new device means enable the
* virtual NVMe controller
*/
static int
spdk_vhost_nvme_start_device(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
spdk_vhost_nvme_start_cb(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
{
struct spdk_vhost_nvme_dev *nvme = to_nvme_dev(vdev);
struct spdk_vhost_nvme_ns *ns_dev;
@ -1099,10 +1096,17 @@ spdk_vhost_nvme_start_device(struct spdk_vhost_dev *vdev,
/* Start the NVMe Poller */
nvme->requestq_poller = spdk_poller_register(nvme_worker, nvme, 0);
spdk_vhost_dev_backend_event_done(event_ctx, 0);
spdk_vhost_session_event_done(event_ctx, 0);
return 0;
}
static int
spdk_vhost_nvme_start(struct spdk_vhost_session *vsession)
{
return spdk_vhost_session_send_event(vsession, spdk_vhost_nvme_start_cb,
3, "start session");
}
static void
spdk_vhost_nvme_deactive_ns(struct spdk_vhost_nvme_ns *ns)
{
@ -1155,16 +1159,14 @@ destroy_device_poller_cb(void *arg)
}
spdk_poller_unregister(&nvme->destroy_ctx.poller);
spdk_vhost_dev_backend_event_done(nvme->destroy_ctx.event_ctx, 0);
spdk_vhost_session_event_done(nvme->destroy_ctx.event_ctx, 0);
return -1;
}
/* Disable NVMe controller
*/
static int
spdk_vhost_nvme_stop_device(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
spdk_vhost_nvme_stop_cb(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
{
struct spdk_vhost_nvme_dev *nvme = to_nvme_dev(vdev);
@ -1182,6 +1184,13 @@ spdk_vhost_nvme_stop_device(struct spdk_vhost_dev *vdev,
return 0;
}
static int
spdk_vhost_nvme_stop(struct spdk_vhost_session *vsession)
{
return spdk_vhost_session_send_event(vsession, spdk_vhost_nvme_stop_cb,
3, "start session");
}
static void
spdk_vhost_nvme_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
{
@ -1252,8 +1261,8 @@ spdk_vhost_nvme_write_config_json(struct spdk_vhost_dev *vdev, struct spdk_json_
static const struct spdk_vhost_dev_backend spdk_vhost_nvme_device_backend = {
.session_ctx_size = 0,
.start_session = spdk_vhost_nvme_start_device,
.stop_session = spdk_vhost_nvme_stop_device,
.start_session = spdk_vhost_nvme_start,
.stop_session = spdk_vhost_nvme_stop,
.dump_info_json = spdk_vhost_nvme_dump_info_json,
.write_config_json = spdk_vhost_nvme_write_config_json,
.remove_device = spdk_vhost_nvme_dev_remove,

View File

@ -113,10 +113,8 @@ struct spdk_vhost_scsi_task {
struct spdk_vhost_virtqueue *vq;
};
static int spdk_vhost_scsi_start(struct spdk_vhost_dev *dev,
struct spdk_vhost_session *vsession, void *);
static int spdk_vhost_scsi_stop(struct spdk_vhost_dev *,
struct spdk_vhost_session *vsession, void *);
static int spdk_vhost_scsi_start(struct spdk_vhost_session *vsession);
static int spdk_vhost_scsi_stop(struct spdk_vhost_session *vsession);
static void spdk_vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev,
struct spdk_json_write_ctx *w);
static void spdk_vhost_scsi_write_config_json(struct spdk_vhost_dev *vdev,
@ -1209,8 +1207,8 @@ alloc_task_pool(struct spdk_vhost_scsi_session *svsession)
}
static int
spdk_vhost_scsi_start(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
spdk_vhost_scsi_start_cb(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
{
struct spdk_vhost_scsi_dev *svdev;
struct spdk_vhost_scsi_session *svsession;
@ -1261,10 +1259,17 @@ spdk_vhost_scsi_start(struct spdk_vhost_dev *vdev,
MGMT_POLL_PERIOD_US);
}
out:
spdk_vhost_dev_backend_event_done(event_ctx, rc);
spdk_vhost_session_event_done(event_ctx, rc);
return rc;
}
static int
spdk_vhost_scsi_start(struct spdk_vhost_session *vsession)
{
return spdk_vhost_session_send_event(vsession, spdk_vhost_scsi_start_cb,
3, "start session");
}
static int
destroy_session_poller_cb(void *arg)
{
@ -1295,14 +1300,14 @@ destroy_session_poller_cb(void *arg)
free_task_pool(svsession);
spdk_poller_unregister(&svsession->destroy_ctx.poller);
spdk_vhost_dev_backend_event_done(svsession->destroy_ctx.event_ctx, 0);
spdk_vhost_session_event_done(svsession->destroy_ctx.event_ctx, 0);
return -1;
}
static int
spdk_vhost_scsi_stop(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
spdk_vhost_scsi_stop_cb(struct spdk_vhost_dev *vdev,
struct spdk_vhost_session *vsession, void *event_ctx)
{
struct spdk_vhost_scsi_session *svsession;
@ -1321,10 +1326,17 @@ spdk_vhost_scsi_stop(struct spdk_vhost_dev *vdev,
return 0;
err:
spdk_vhost_dev_backend_event_done(event_ctx, -1);
spdk_vhost_session_event_done(event_ctx, -1);
return -1;
}
static int
spdk_vhost_scsi_stop(struct spdk_vhost_session *vsession)
{
return spdk_vhost_session_send_event(vsession, spdk_vhost_scsi_stop_cb,
3, "stop session");
}
static void
spdk_vhost_scsi_dump_info_json(struct spdk_vhost_dev *vdev, struct spdk_json_write_ctx *w)
{