From 8047421868d3497ba0a4c7f1c22c6e70d6bd346e Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Fri, 25 Apr 2025 11:41:44 +1000 Subject: [PATCH] Protect some variables in iscsi_context by the spinlock Signed-off-by: Ronnie Sahlberg --- include/iscsi-private.h | 12 ++++++------ lib/iscsi-command.c | 13 ++++++++----- lib/nop.c | 11 +++++++---- lib/pdu.c | 10 ++++++++-- 4 files changed, 29 insertions(+), 17 deletions(-) diff --git a/include/iscsi-private.h b/include/iscsi-private.h index f68a37a..99febae 100644 --- a/include/iscsi-private.h +++ b/include/iscsi-private.h @@ -131,12 +131,12 @@ struct iscsi_context { enum iscsi_session_type session_type; unsigned char isid[6]; uint8_t rdma_ack_timeout; - uint32_t itt; // multithreading todo: may need mutex - uint32_t cmdsn; // multithreading todo: may need mutex - uint32_t min_cmdsn_waiting; // multithreading todo: may need mutex - uint32_t expcmdsn; // multithreading todo: may need mutex - uint32_t maxcmdsn; // multithreading todo: may need mutex - uint32_t statsn; // multithreading todo: may need mutex + uint32_t itt; /* Protected by iscsi_lock */ + uint32_t cmdsn; /* Protected by iscsi_lock */ + uint32_t min_cmdsn_waiting; /* Protected by iscsi_lock */ + uint32_t expcmdsn; /* Protected by iscsi_lock */ + uint32_t maxcmdsn; /* Protected by iscsi_lock */ + uint32_t statsn; /* Protected by iscsi_lock */ enum iscsi_header_digest want_header_digest; enum iscsi_header_digest header_digest; enum iscsi_data_digest want_data_digest; diff --git a/lib/iscsi-command.c b/lib/iscsi-command.c index 5fe6135..8b20534 100644 --- a/lib/iscsi-command.c +++ b/lib/iscsi-command.c @@ -261,6 +261,9 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, } iscsi_pdu_set_pduflags(pdu, flags); + pdu->callback = iscsi_scsi_response_cb; + pdu->private_data = &pdu->scsi_cbdata; + /* lun */ iscsi_pdu_set_lun(pdu, lun); pdu->lun = lun; @@ -269,16 +272,14 @@ iscsi_scsi_command_async(struct iscsi_context *iscsi, int lun, iscsi_pdu_set_expxferlen(pdu, task->expxferlen); /* cmdsn */ - iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn); + iscsi_mt_spin_lock(&iscsi->iscsi_lock); + iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn++); + iscsi_mt_spin_unlock(&iscsi->iscsi_lock); /* cdb */ iscsi_pdu_set_cdb(pdu, task); - pdu->callback = iscsi_scsi_response_cb; - pdu->private_data = &pdu->scsi_cbdata; - iscsi_queue_pdu(iscsi, pdu); - iscsi->cmdsn++; /* The F flag is not set. This means we haven't sent all the unsolicited * data yet. Sent as much as we are allowed as a train of DATA-OUT PDUs. @@ -2730,7 +2731,9 @@ iscsi_scsi_cancel_task(struct iscsi_context *iscsi, } if (!(pdu->outdata.data[0] & ISCSI_PDU_IMMEDIATE) && (pdu->outdata.data[0] & 0x3f) != ISCSI_PDU_DATA_OUT) { + iscsi_mt_spin_lock(&iscsi->iscsi_lock); iscsi->cmdsn--; + iscsi_mt_spin_unlock(&iscsi->iscsi_lock); cmdsn_gap++; } iscsi->drv->free_pdu(iscsi, pdu); diff --git a/lib/nop.c b/lib/nop.c index 9e62fae..e648f46 100644 --- a/lib/nop.c +++ b/lib/nop.c @@ -54,6 +54,9 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, return -1; } + pdu->callback = cb; + pdu->private_data = private_data; + /* flags */ iscsi_pdu_set_pduflags(pdu, 0x80); @@ -64,22 +67,22 @@ iscsi_nop_out_async(struct iscsi_context *iscsi, iscsi_command_cb cb, iscsi_pdu_set_lun(pdu, 0); /* cmdsn */ + iscsi_mt_spin_lock(&iscsi->iscsi_lock); iscsi_pdu_set_cmdsn(pdu, iscsi->cmdsn); - pdu->callback = cb; - pdu->private_data = private_data; - if (data != NULL && len > 0) { if (iscsi_pdu_add_data(iscsi, pdu, data, len) != 0) { + iscsi_mt_spin_unlock(&iscsi->iscsi_lock); iscsi_set_error(iscsi, "Failed to add outdata to nop-out"); iscsi->drv->free_pdu(iscsi, pdu); return -1; } } + iscsi->cmdsn++; + iscsi_mt_spin_unlock(&iscsi->iscsi_lock); iscsi_queue_pdu(iscsi, pdu); - iscsi->cmdsn++; iscsi->nops_in_flight++; ISCSI_LOG(iscsi, (iscsi->nops_in_flight > 1) ? 1 : 6, "NOP Out Send (nops_in_flight: %d, pdu->cmdsn %08x, pdu->itt %08x, pdu->ttt %08x, iscsi->maxcmdsn %08x, iscsi->expcmdsn %08x)", diff --git a/lib/pdu.c b/lib/pdu.c index 3c0aa71..323fc5a 100644 --- a/lib/pdu.c +++ b/lib/pdu.c @@ -70,12 +70,15 @@ iscsi_serial32_compare(uint32_t s1, uint32_t s2) { uint32_t iscsi_itt_post_increment(struct iscsi_context *iscsi) { - uint32_t old_itt = iscsi->itt; - iscsi->itt++; + uint32_t old_itt; + + iscsi_mt_spin_lock(&iscsi->iscsi_lock); + old_itt = iscsi->itt++; /* 0xffffffff is a reserved value */ if (iscsi->itt == 0xffffffff) { iscsi->itt = 0; } + iscsi_mt_spin_unlock(&iscsi->iscsi_lock); return old_itt; } @@ -500,6 +503,7 @@ static void iscsi_process_pdu_serials(struct iscsi_context *iscsi, struct iscsi_ return; } + iscsi_mt_spin_lock(&iscsi->iscsi_lock); if (iscsi_serial32_compare(maxcmdsn, iscsi->maxcmdsn) > 0) { iscsi->maxcmdsn = maxcmdsn; } @@ -510,6 +514,7 @@ static void iscsi_process_pdu_serials(struct iscsi_context *iscsi, struct iscsi_ /* RFC3720 10.7.3 (StatSN is invalid if S bit unset in flags) */ if (opcode == ISCSI_PDU_DATA_IN && !(flags & ISCSI_PDU_DATA_CONTAINS_STATUS)) { + iscsi_mt_spin_unlock(&iscsi->iscsi_lock); return; } @@ -520,6 +525,7 @@ static void iscsi_process_pdu_serials(struct iscsi_context *iscsi, struct iscsi_ if (iscsi_serial32_compare(statsn, iscsi->statsn) > 0) { iscsi->statsn = statsn; } + iscsi_mt_spin_unlock(&iscsi->iscsi_lock); } int