nvmf: add free_req function pointer.

At times, it may be necessary to free requests without completing them.
For example, when freeing a qpair, one needs to free the AER sent from
the host before deleting the qpair. It is important not to send a
completion for the AER because:
1. According to the spec, this will trigger the host to send another AER
2. No Asynchronous Events have occured, so we should not complete the
AER.

Change-Id: I92e163f0fed0ee2bc942569a647cb3c1967edec9
Signed-off-by: Seth Howell <seth.howell@intel.com>
Reviewed-on: https://review.gerrithub.io/419732
Chandler-Test-Pool: SPDK Automated Test System <sys_sgsw@intel.com>
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Seth Howell 2018-07-18 08:47:16 -07:00 committed by Jim Harris
parent 5a5630acb2
commit 388e310150
7 changed files with 76 additions and 11 deletions

View File

@ -268,6 +268,7 @@ int spdk_nvmf_poll_group_pause_subsystem(struct spdk_nvmf_poll_group *group,
int spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group, int spdk_nvmf_poll_group_resume_subsystem(struct spdk_nvmf_poll_group *group,
struct spdk_nvmf_subsystem *subsystem); struct spdk_nvmf_subsystem *subsystem);
void spdk_nvmf_request_exec(struct spdk_nvmf_request *req); void spdk_nvmf_request_exec(struct spdk_nvmf_request *req);
int spdk_nvmf_request_free(struct spdk_nvmf_request *req);
int spdk_nvmf_request_complete(struct spdk_nvmf_request *req); int spdk_nvmf_request_complete(struct spdk_nvmf_request *req);
void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt, void spdk_nvmf_get_discovery_log_page(struct spdk_nvmf_tgt *tgt,

View File

@ -2390,6 +2390,29 @@ spdk_nvmf_rdma_poll_group_remove(struct spdk_nvmf_transport_poll_group *group,
return 0; return 0;
} }
static int
spdk_nvmf_rdma_request_free(struct spdk_nvmf_request *req)
{
struct spdk_nvmf_rdma_request *rdma_req = SPDK_CONTAINEROF(req, struct spdk_nvmf_rdma_request, req);
struct spdk_nvmf_rdma_transport *rtransport = SPDK_CONTAINEROF(req->qpair->transport,
struct spdk_nvmf_rdma_transport, transport);
if (rdma_req->data_from_pool) {
/* Put the buffer/s back in the pool */
for (uint32_t i = 0; i < rdma_req->req.iovcnt; i++) {
spdk_mempool_put(rtransport->data_buf_pool, rdma_req->data.buffers[i]);
rdma_req->req.iov[i].iov_base = NULL;
rdma_req->data.buffers[i] = NULL;
}
rdma_req->data_from_pool = false;
}
rdma_req->req.length = 0;
rdma_req->req.iovcnt = 0;
rdma_req->req.data = NULL;
spdk_nvmf_rdma_request_set_state(rdma_req, RDMA_REQUEST_STATE_FREE);
return 0;
}
static int static int
spdk_nvmf_rdma_request_complete(struct spdk_nvmf_request *req) spdk_nvmf_rdma_request_complete(struct spdk_nvmf_request *req)
{ {
@ -2606,6 +2629,7 @@ const struct spdk_nvmf_transport_ops spdk_nvmf_transport_rdma = {
.poll_group_remove = spdk_nvmf_rdma_poll_group_remove, .poll_group_remove = spdk_nvmf_rdma_poll_group_remove,
.poll_group_poll = spdk_nvmf_rdma_poll_group_poll, .poll_group_poll = spdk_nvmf_rdma_poll_group_poll,
.req_free = spdk_nvmf_rdma_request_free,
.req_complete = spdk_nvmf_rdma_request_complete, .req_complete = spdk_nvmf_rdma_request_complete,
.qpair_fini = spdk_nvmf_rdma_close_qpair, .qpair_fini = spdk_nvmf_rdma_close_qpair,

View File

@ -45,6 +45,35 @@
#include "spdk_internal/assert.h" #include "spdk_internal/assert.h"
#include "spdk_internal/log.h" #include "spdk_internal/log.h"
static void
spdk_nvmf_qpair_request_cleanup(struct spdk_nvmf_qpair *qpair)
{
if (qpair->state == SPDK_NVMF_QPAIR_DEACTIVATING) {
assert(qpair->state_cb != NULL);
if (TAILQ_EMPTY(&qpair->outstanding)) {
qpair->state_cb(qpair->state_cb_arg, 0);
}
} else {
assert(qpair->state == SPDK_NVMF_QPAIR_ACTIVE);
}
}
int
spdk_nvmf_request_free(struct spdk_nvmf_request *req)
{
struct spdk_nvmf_qpair *qpair = req->qpair;
TAILQ_REMOVE(&qpair->outstanding, req, link);
if (spdk_nvmf_transport_req_free(req)) {
SPDK_ERRLOG("Unable to free transport level request resources.\n");
}
spdk_nvmf_qpair_request_cleanup(qpair);
return 0;
}
int int
spdk_nvmf_request_complete(struct spdk_nvmf_request *req) spdk_nvmf_request_complete(struct spdk_nvmf_request *req)
{ {
@ -67,16 +96,7 @@ spdk_nvmf_request_complete(struct spdk_nvmf_request *req)
SPDK_ERRLOG("Transport request completion error!\n"); SPDK_ERRLOG("Transport request completion error!\n");
} }
if (qpair->state == SPDK_NVMF_QPAIR_DEACTIVATING) { spdk_nvmf_qpair_request_cleanup(qpair);
assert(qpair->state_cb != NULL);
if (TAILQ_EMPTY(&qpair->outstanding)) {
qpair->state_cb(qpair->state_cb_arg, 0);
}
} else {
assert(qpair->state == SPDK_NVMF_QPAIR_ACTIVE);
}
return 0; return 0;
} }

View File

@ -160,6 +160,12 @@ spdk_nvmf_transport_poll_group_poll(struct spdk_nvmf_transport_poll_group *group
return group->transport->ops->poll_group_poll(group); return group->transport->ops->poll_group_poll(group);
} }
int
spdk_nvmf_transport_req_free(struct spdk_nvmf_request *req)
{
return req->qpair->transport->ops->req_free(req);
}
int int
spdk_nvmf_transport_req_complete(struct spdk_nvmf_request *req) spdk_nvmf_transport_req_complete(struct spdk_nvmf_request *req)
{ {

View File

@ -114,6 +114,12 @@ struct spdk_nvmf_transport_ops {
*/ */
int (*poll_group_poll)(struct spdk_nvmf_transport_poll_group *group); int (*poll_group_poll)(struct spdk_nvmf_transport_poll_group *group);
/*
* Free the request without sending a response
* to the originator. Release memory tied to this request.
*/
int (*req_free)(struct spdk_nvmf_request *req);
/* /*
* Signal request completion, which sends a response * Signal request completion, which sends a response
* to the originator. * to the originator.
@ -160,6 +166,8 @@ int spdk_nvmf_transport_poll_group_remove(struct spdk_nvmf_transport_poll_group
int spdk_nvmf_transport_poll_group_poll(struct spdk_nvmf_transport_poll_group *group); int spdk_nvmf_transport_poll_group_poll(struct spdk_nvmf_transport_poll_group *group);
int spdk_nvmf_transport_req_free(struct spdk_nvmf_request *req);
int spdk_nvmf_transport_req_complete(struct spdk_nvmf_request *req); int spdk_nvmf_transport_req_complete(struct spdk_nvmf_request *req);
void spdk_nvmf_transport_qpair_fini(struct spdk_nvmf_qpair *qpair); void spdk_nvmf_transport_qpair_fini(struct spdk_nvmf_qpair *qpair);

View File

@ -128,7 +128,7 @@ DEFINE_STUB(spdk_nvmf_request_complete,
(struct spdk_nvmf_request *req), (struct spdk_nvmf_request *req),
-1); -1);
DEFINE_STUB(spdk_nvmf_request_abort, DEFINE_STUB(spdk_nvmf_request_free,
int, int,
(struct spdk_nvmf_request *req), (struct spdk_nvmf_request *req),
-1); -1);

View File

@ -44,6 +44,12 @@ void spdk_trace_record(uint16_t tpoint_id, uint16_t poller_id, uint32_t size,
{ {
} }
int
spdk_nvmf_transport_req_free(struct spdk_nvmf_request *req)
{
return 0;
}
int int
spdk_nvmf_transport_req_complete(struct spdk_nvmf_request *req) spdk_nvmf_transport_req_complete(struct spdk_nvmf_request *req)
{ {