nvme/cuse: Poll the io_msg queue when the admin queue is polled

Users already have to poll the admin queue, so embed the io_msg
queue polling there to simplify the API.

Signed-off-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/472833 (master)

(cherry picked from commit 11739f3cb1)
Change-Id: I4d4d3be100be0798bee4096e0bbda96e20d2405e
Signed-off-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com>
Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/472963
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
This commit is contained in:
Ben Walker 2019-10-30 11:58:33 -07:00 committed by Tomasz Zawadzki
parent 43890b3c4c
commit 5a472f2779
5 changed files with 42 additions and 31 deletions

View File

@ -283,11 +283,12 @@ locations:
~~~
Requests from CUSE are handled by pthreads when controller and namespaces are created.
Those pass the I/O or admin commands via a ring to a thread that processes them using
spdk_nvme_io_msg_process().
During the handling of CUSE requests, operations may be forwarded to an internal NVMe
queue pair. The user must poll this internal queue pair periodically by polling
the admin qpair for the associated NVMe controller.
Ioctls that request information attained when attaching NVMe controller receive an
immediate response, without passing them through the ring.
immediate response, without passing them to the internal queue pair.
This interface reserves one qpair for sending down the I/O for each controller.

View File

@ -1246,26 +1246,6 @@ int spdk_nvme_ctrlr_cmd_io_raw_with_md(struct spdk_nvme_ctrlr *ctrlr,
int32_t spdk_nvme_qpair_process_completions(struct spdk_nvme_qpair *qpair,
uint32_t max_completions);
/**
* Process IO message sent to controller from external module.
*
* This call process requests from the ring, send IO to an allocated qpair or
* admin commands in its context. This call is non-blocking and intended to be
* polled by SPDK thread to provide safe environment for NVMe request
* completition sent by external module to controller.
*
* The caller must ensure that each controller is polled by only one thread at
* a time.
*
* This function may be called at any point while the controller is attached to
* the SPDK NVMe driver.
*
* \param ctrlr Opaque handle to NVMe controller.
*
* \return number of processed external IO messages.
*/
int spdk_nvme_io_msg_process(struct spdk_nvme_ctrlr *ctrlr);
/**
* Send the given admin command to the NVMe controller.
*

View File

@ -34,6 +34,7 @@
#include "spdk/stdinc.h"
#include "nvme_internal.h"
#include "nvme_io_msg.h"
#include "spdk/env.h"
#include "spdk/string.h"
@ -2646,14 +2647,30 @@ int32_t
spdk_nvme_ctrlr_process_admin_completions(struct spdk_nvme_ctrlr *ctrlr)
{
int32_t num_completions;
int32_t rc;
nvme_robust_mutex_lock(&ctrlr->ctrlr_lock);
if (ctrlr->keep_alive_interval_ticks) {
nvme_ctrlr_keep_alive(ctrlr);
}
num_completions = spdk_nvme_qpair_process_completions(ctrlr->adminq, 0);
rc = spdk_nvme_io_msg_process(ctrlr);
if (rc < 0) {
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
return rc;
}
num_completions = rc;
rc = spdk_nvme_qpair_process_completions(ctrlr->adminq, 0);
nvme_robust_mutex_unlock(&ctrlr->ctrlr_lock);
if (rc < 0) {
num_completions = rc;
} else {
num_completions += rc;
}
return num_completions;
}

View File

@ -58,6 +58,26 @@ struct nvme_io_msg_producer {
int nvme_io_msg_send(struct spdk_nvme_ctrlr *ctrlr, uint32_t nsid, spdk_nvme_io_msg_fn fn,
void *arg);
/**
* Process IO message sent to controller from external module.
*
* This call process requests from the ring, send IO to an allocated qpair or
* admin commands in its context. This call is non-blocking and intended to be
* polled by SPDK thread to provide safe environment for NVMe request
* completition sent by external module to controller.
*
* The caller must ensure that each controller is polled by only one thread at
* a time.
*
* This function may be called at any point while the controller is attached to
* the SPDK NVMe driver.
*
* \param ctrlr Opaque handle to NVMe controller.
*
* \return number of processed external IO messages.
*/
int spdk_nvme_io_msg_process(struct spdk_nvme_ctrlr *ctrlr);
int nvme_io_msg_ctrlr_start(struct spdk_nvme_ctrlr *ctrlr,
struct nvme_io_msg_producer *io_msg_producer);
void nvme_io_msg_ctrlr_stop(struct spdk_nvme_ctrlr *ctrlr,

View File

@ -210,13 +210,6 @@ bdev_nvme_poll_adminq(void *arg)
{
struct spdk_nvme_ctrlr *ctrlr = arg;
/* Process io messages that were passed from non-polled mode threads
* to this ctrlr. This is used as part of nvme cuse support for surfacing
* /dev nodes that can be used by standard Linux management applications
* like nvme-cli.
*/
spdk_nvme_io_msg_process(ctrlr);
return spdk_nvme_ctrlr_process_admin_completions(ctrlr);
}