nvme/opal: use asynchronous security send/receive transport APIs

opal_send_recv() is a wrapper implementation to use the asynchronous
security send/receive APIs, it can be used in a session context, but
from the view of one session, the opal_send_recv() is still executed
synchronously, but if the drive can support more than one session,
opal_send_recv() can be called from different sessions or threads.

Change-Id: I3a4b2ec14cb7706c39565a6b4fb8a3a4862f3d4c
Signed-off-by: Changpeng Liu <changpeng.liu@intel.com>
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/1670
Tested-by: SPDK CI Jenkins <sys_sgci@intel.com>
Community-CI: Broadcom CI
Reviewed-by: Jim Harris <james.r.harris@intel.com>
Reviewed-by: Ben Walker <benjamin.walker@intel.com>
This commit is contained in:
Changpeng Liu 2020-04-03 20:50:59 +08:00 committed by Tomasz Zawadzki
parent 71327bfef8
commit e51a2aaf3f
2 changed files with 103 additions and 41 deletions

View File

@ -37,40 +37,71 @@
#include "nvme_opal_internal.h" #include "nvme_opal_internal.h"
static int static void
opal_security_send(struct spdk_opal_dev *dev, struct opal_session *sess) opal_nvme_security_recv_done(void *arg, const struct spdk_nvme_cpl *cpl)
{ {
return spdk_nvme_ctrlr_security_send(dev->ctrlr, SPDK_SCSI_SECP_TCG, dev->comid, struct opal_session *sess = arg;
0, sess->cmd, IO_BUFFER_LENGTH); struct spdk_opal_dev *dev = sess->dev;
void *response = sess->resp;
struct spdk_opal_compacket *header = response;
int ret;
if (spdk_nvme_cpl_is_error(cpl)) {
sess->sess_cb(sess, -EIO, sess->cb_arg);
return;
}
if (!header->outstanding_data && !header->min_transfer) {
sess->sess_cb(sess, 0, sess->cb_arg);
return;
}
memset(response, 0, IO_BUFFER_LENGTH);
ret = spdk_nvme_ctrlr_cmd_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG,
dev->comid, 0, sess->resp, IO_BUFFER_LENGTH,
opal_nvme_security_recv_done, sess);
if (ret) {
sess->sess_cb(sess, ret, sess->cb_arg);
}
}
static void
opal_nvme_security_send_done(void *arg, const struct spdk_nvme_cpl *cpl)
{
struct opal_session *sess = arg;
struct spdk_opal_dev *dev = sess->dev;
int ret;
if (spdk_nvme_cpl_is_error(cpl)) {
sess->sess_cb(sess, -EIO, sess->cb_arg);
return;
}
ret = spdk_nvme_ctrlr_cmd_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG,
dev->comid, 0, sess->resp, IO_BUFFER_LENGTH,
opal_nvme_security_recv_done, sess);
if (ret) {
sess->sess_cb(sess, ret, sess->cb_arg);
}
} }
static int static int
opal_security_recv(struct spdk_opal_dev *dev, struct opal_session *sess) opal_nvme_security_send(struct spdk_opal_dev *dev, struct opal_session *sess,
opal_sess_cb sess_cb, void *cb_arg)
{ {
void *response = sess->resp; sess->sess_cb = sess_cb;
struct spdk_opal_compacket *header = response; sess->cb_arg = cb_arg;
int ret = 0;
do { return spdk_nvme_ctrlr_cmd_security_send(dev->ctrlr, SPDK_SCSI_SECP_TCG, dev->comid,
memset(response, 0, IO_BUFFER_LENGTH); 0, sess->cmd, IO_BUFFER_LENGTH,
ret = spdk_nvme_ctrlr_security_receive(dev->ctrlr, SPDK_SCSI_SECP_TCG, dev->comid, opal_nvme_security_send_done, sess);
0, sess->resp, IO_BUFFER_LENGTH); }
if (ret) {
SPDK_ERRLOG("Security Receive Error on dev = %p\n", dev);
return ret;
}
SPDK_DEBUGLOG(SPDK_LOG_OPAL, "outstanding_data=%d, minTransfer=%d\n",
header->outstanding_data,
header->min_transfer);
if (header->outstanding_data == 0 && static void
header->min_transfer == 0) { opal_send_recv_done(struct opal_session *sess, int status, void *ctx)
/* return if all the response data are ready by tper and received by host */ {
return 0; sess->status = status;
} sess->done = true;
} while (true);
return 0;
} }
static int static int
@ -78,12 +109,31 @@ opal_send_recv(struct spdk_opal_dev *dev, struct opal_session *sess)
{ {
int ret; int ret;
ret = opal_security_send(dev, sess); sess->done = false;
ret = opal_nvme_security_send(dev, sess, opal_send_recv_done, NULL);
if (ret) { if (ret) {
return ret; return ret;
} }
return opal_security_recv(dev, sess); while (!sess->done) {
spdk_nvme_ctrlr_process_admin_completions(dev->ctrlr);
}
return sess->status;
}
static struct opal_session *
opal_alloc_session(struct spdk_opal_dev *dev)
{
struct opal_session *sess;
sess = calloc(1, sizeof(*sess));
if (!sess) {
return NULL;
}
sess->dev = dev;
return sess;
} }
static void static void
@ -1721,7 +1771,7 @@ spdk_opal_cmd_take_ownership(struct spdk_opal_dev *dev, char *new_passwd)
return -ENODEV; return -ENODEV;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -1748,6 +1798,7 @@ spdk_opal_cmd_take_ownership(struct spdk_opal_dev *dev, char *new_passwd)
/* reuse the session structure */ /* reuse the session structure */
memset(sess, 0, sizeof(*sess)); memset(sess, 0, sizeof(*sess));
sess->dev = dev;
ret = opal_start_generic_session(dev, sess, UID_SID, UID_ADMINSP, ret = opal_start_generic_session(dev, sess, UID_SID, UID_ADMINSP,
opal_key.key, opal_key.key_len); opal_key.key, opal_key.key_len);
if (ret) { if (ret) {
@ -2008,7 +2059,7 @@ spdk_opal_cmd_revert_tper(struct spdk_opal_dev *dev, const char *passwd)
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2062,7 +2113,7 @@ spdk_opal_cmd_activate_locking_sp(struct spdk_opal_dev *dev, const char *passwd)
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2117,7 +2168,7 @@ spdk_opal_cmd_lock_unlock(struct spdk_opal_dev *dev, enum spdk_opal_user user,
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2164,7 +2215,7 @@ spdk_opal_cmd_setup_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2214,7 +2265,7 @@ spdk_opal_cmd_get_max_ranges(struct spdk_opal_dev *dev, const char *passwd)
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2262,7 +2313,7 @@ spdk_opal_cmd_get_locking_range_info(struct spdk_opal_dev *dev, const char *pass
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2308,7 +2359,7 @@ spdk_opal_cmd_enable_user(struct spdk_opal_dev *dev, enum spdk_opal_user user_id
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2356,7 +2407,7 @@ spdk_opal_cmd_add_user_to_locking_range(struct spdk_opal_dev *dev, enum spdk_opa
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2409,7 +2460,7 @@ spdk_opal_cmd_set_new_passwd(struct spdk_opal_dev *dev, enum spdk_opal_user user
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2456,7 +2507,7 @@ spdk_opal_cmd_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_opal_user
return ret; return ret;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
return -ENOMEM; return -ENOMEM;
} }
@ -2508,7 +2559,7 @@ spdk_opal_cmd_secure_erase_locking_range(struct spdk_opal_dev *dev, enum spdk_op
return -ENOMEM; return -ENOMEM;
} }
sess = calloc(1, sizeof(*sess)); sess = opal_alloc_session(dev);
if (!sess) { if (!sess) {
free(active_key); free(active_key);
return -ENOMEM; return -ENOMEM;

View File

@ -238,6 +238,11 @@ struct spdk_opal_header {
struct spdk_opal_data_subpacket sub_packet; struct spdk_opal_data_subpacket sub_packet;
}; };
struct opal_session;
struct spdk_opal_dev;
typedef void (*opal_sess_cb)(struct opal_session *sess, int status, void *ctx);
struct opal_session { struct opal_session {
uint32_t hsn; uint32_t hsn;
uint32_t tsn; uint32_t tsn;
@ -245,6 +250,12 @@ struct opal_session {
uint8_t cmd[IO_BUFFER_LENGTH]; uint8_t cmd[IO_BUFFER_LENGTH];
uint8_t resp[IO_BUFFER_LENGTH]; uint8_t resp[IO_BUFFER_LENGTH];
struct spdk_opal_resp_parsed parsed_resp; struct spdk_opal_resp_parsed parsed_resp;
opal_sess_cb sess_cb;
void *cb_arg;
bool done;
int status;
struct spdk_opal_dev *dev;
}; };
struct spdk_opal_dev { struct spdk_opal_dev {