From 20618744743e85bde33e153adbcb8eb4b1a4bdb3 Mon Sep 17 00:00:00 2001 From: Anil Veerabhadrappa <anil.veerabhadrappa@broadcom.com> Date: Sun, 28 Apr 2019 23:03:32 -0700 Subject: [PATCH] lib/nvmf: Validate requested SQ size for both admin and IO queue During connect call based on queue type (AQ or IOQ), SQ size should be validated against max sq size for that particular queue type. Change-Id: I977d7556e4d04e37004d16c87efffd3b467fa62c Signed-off-by: Anil Veerabhadrappa <anil.veerabhadrappa@broadcom.com> Reviewed-on: https://review.gerrithub.io/c/spdk/spdk/+/452376 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Reviewed-by: Ben Walker <benjamin.walker@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com> Reviewed-by: Ziye Yang <ziye.yang@intel.com> Reviewed-by: Shuhei Matsumoto <shuhei.matsumoto.xt@hitachi.com> --- lib/nvmf/ctrlr.c | 25 ++++++++++++++++++++----- test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c | 1 + 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/lib/nvmf/ctrlr.c b/lib/nvmf/ctrlr.c index a6ba27e8e3..c211104002 100644 --- a/lib/nvmf/ctrlr.c +++ b/lib/nvmf/ctrlr.c @@ -461,7 +461,8 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req) struct spdk_nvmf_fabric_connect_cmd *cmd = &req->cmd->connect_cmd; struct spdk_nvmf_fabric_connect_rsp *rsp = &req->rsp->connect_rsp; struct spdk_nvmf_qpair *qpair = req->qpair; - struct spdk_nvmf_tgt *tgt = qpair->transport->tgt; + struct spdk_nvmf_transport *transport = qpair->transport; + struct spdk_nvmf_tgt *tgt = transport->tgt; struct spdk_nvmf_ctrlr *ctrlr; struct spdk_nvmf_subsystem *subsystem; const char *subnqn, *hostnqn; @@ -555,14 +556,28 @@ spdk_nvmf_ctrlr_connect(struct spdk_nvmf_request *req) /* * SQSIZE is a 0-based value, so it must be at least 1 (minimum queue depth is 2) and - * strictly less than max_queue_depth. + * strictly less than max_aq_depth (admin queues) or max_queue_depth (io queues). */ - if (cmd->sqsize == 0 || cmd->sqsize >= qpair->transport->opts.max_queue_depth) { - SPDK_ERRLOG("Invalid SQSIZE %u (min 1, max %u)\n", - cmd->sqsize, qpair->transport->opts.max_queue_depth - 1); + if (cmd->sqsize == 0) { + SPDK_ERRLOG("Invalid SQSIZE = 0\n"); SPDK_NVMF_INVALID_CONNECT_CMD(rsp, sqsize); return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; } + + if (spdk_nvmf_qpair_is_admin_queue(qpair)) { + if (cmd->sqsize >= transport->opts.max_aq_depth) { + SPDK_ERRLOG("Invalid SQSIZE for admin queue %u (min 1, max %u)\n", + cmd->sqsize, transport->opts.max_aq_depth - 1); + SPDK_NVMF_INVALID_CONNECT_CMD(rsp, sqsize); + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + } else if (cmd->sqsize >= transport->opts.max_queue_depth) { + SPDK_ERRLOG("Invalid SQSIZE %u (min 1, max %u)\n", + cmd->sqsize, transport->opts.max_queue_depth - 1); + SPDK_NVMF_INVALID_CONNECT_CMD(rsp, sqsize); + return SPDK_NVMF_REQUEST_EXEC_STATUS_COMPLETE; + } + qpair->sq_head_max = cmd->sqsize; qpair->qid = cmd->qid; diff --git a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c index a601101af9..4b02f3c0d0 100644 --- a/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c +++ b/test/unit/lib/nvmf/ctrlr.c/ctrlr_ut.c @@ -313,6 +313,7 @@ test_connect(void) memset(&tgt, 0, sizeof(tgt)); memset(&transport, 0, sizeof(transport)); + transport.opts.max_aq_depth = 32; transport.opts.max_queue_depth = 64; transport.opts.max_qpairs_per_ctrlr = 3; transport.tgt = &tgt;