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:
parent
5a5630acb2
commit
388e310150
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user