[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 56/56] hw/block/nvme: refactor the logic for zone write checks
From: |
Klaus Jensen |
Subject: |
[PULL 56/56] hw/block/nvme: refactor the logic for zone write checks |
Date: |
Tue, 9 Feb 2021 08:31:01 +0100 |
From: Klaus Jensen <k.jensen@samsung.com>
Refactor the zone write check logic such that the most "meaningful"
error is returned first. That is, first, if the zone is not writable,
return an appropriate status code for that. Then, make sure we are
actually writing at the write pointer and finally check that we do not
cross the zone write boundary. This aligns with the "priority" of status
codes for zone read checks.
Also add a couple of additional descriptive trace events and remove an
always true assert.
Cc: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Tested-by: Niklas Cassel <niklas.cassel@wdc.com>
Tested-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Reviewed-by: Dmitry Fomichev <dmitry.fomichev@wdc.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Klaus Jensen <k.jensen@samsung.com>
---
hw/block/nvme.c | 49 ++++++++++++++++++++-----------------------
hw/block/trace-events | 5 +++++
2 files changed, 28 insertions(+), 26 deletions(-)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index cedb4ad9ffd3..5ce21b7100b3 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -1161,56 +1161,53 @@ static inline NvmeZone
*nvme_get_zone_by_slba(NvmeNamespace *ns, uint64_t slba)
static uint16_t nvme_check_zone_state_for_write(NvmeZone *zone)
{
- uint16_t status;
+ uint64_t zslba = zone->d.zslba;
switch (nvme_get_zone_state(zone)) {
case NVME_ZONE_STATE_EMPTY:
case NVME_ZONE_STATE_IMPLICITLY_OPEN:
case NVME_ZONE_STATE_EXPLICITLY_OPEN:
case NVME_ZONE_STATE_CLOSED:
- status = NVME_SUCCESS;
- break;
+ return NVME_SUCCESS;
case NVME_ZONE_STATE_FULL:
- status = NVME_ZONE_FULL;
- break;
+ trace_pci_nvme_err_zone_is_full(zslba);
+ return NVME_ZONE_FULL;
case NVME_ZONE_STATE_OFFLINE:
- status = NVME_ZONE_OFFLINE;
- break;
+ trace_pci_nvme_err_zone_is_offline(zslba);
+ return NVME_ZONE_OFFLINE;
case NVME_ZONE_STATE_READ_ONLY:
- status = NVME_ZONE_READ_ONLY;
- break;
+ trace_pci_nvme_err_zone_is_read_only(zslba);
+ return NVME_ZONE_READ_ONLY;
default:
assert(false);
}
- return status;
+ return NVME_INTERNAL_DEV_ERROR;
}
static uint16_t nvme_check_zone_write(NvmeCtrl *n, NvmeNamespace *ns,
NvmeZone *zone, uint64_t slba,
uint32_t nlb)
{
+ uint64_t zcap = nvme_zone_wr_boundary(zone);
uint16_t status;
- if (unlikely((slba + nlb) > nvme_zone_wr_boundary(zone))) {
- status = NVME_ZONE_BOUNDARY_ERROR;
- } else {
- status = nvme_check_zone_state_for_write(zone);
- }
-
+ status = nvme_check_zone_state_for_write(zone);
if (status) {
- trace_pci_nvme_err_zone_write_not_ok(slba, nlb, status);
- } else {
- assert(nvme_wp_is_valid(zone));
-
- if (unlikely(slba != zone->w_ptr)) {
- trace_pci_nvme_err_write_not_at_wp(slba, zone->d.zslba,
- zone->w_ptr);
- status = NVME_ZONE_INVALID_WRITE;
- }
+ return status;
}
- return status;
+ if (unlikely(slba != zone->w_ptr)) {
+ trace_pci_nvme_err_write_not_at_wp(slba, zone->d.zslba, zone->w_ptr);
+ return NVME_ZONE_INVALID_WRITE;
+ }
+
+ if (unlikely((slba + nlb) > zcap)) {
+ trace_pci_nvme_err_zone_boundary(slba, nlb, zcap);
+ return NVME_ZONE_BOUNDARY_ERROR;
+ }
+
+ return NVME_SUCCESS;
}
static uint16_t nvme_check_zone_state_for_read(NvmeZone *zone)
diff --git a/hw/block/trace-events b/hw/block/trace-events
index 87ab6c509045..d32475c3989e 100644
--- a/hw/block/trace-events
+++ b/hw/block/trace-events
@@ -129,6 +129,11 @@ pci_nvme_err_unaligned_zone_cmd(uint8_t action, uint64_t
slba, uint64_t zslba) "
pci_nvme_err_invalid_zone_state_transition(uint8_t action, uint64_t slba,
uint8_t attrs) "action=0x%"PRIx8", slba=%"PRIu64", attrs=0x%"PRIx32""
pci_nvme_err_write_not_at_wp(uint64_t slba, uint64_t zone, uint64_t wp)
"writing at slba=%"PRIu64", zone=%"PRIu64", but wp=%"PRIu64""
pci_nvme_err_append_not_at_start(uint64_t slba, uint64_t zone) "appending at
slba=%"PRIu64", but zone=%"PRIu64""
+pci_nvme_err_zone_is_full(uint64_t zslba) "zslba 0x%"PRIx64""
+pci_nvme_err_zone_is_read_only(uint64_t zslba) "zslba 0x%"PRIx64""
+pci_nvme_err_zone_is_offline(uint64_t zslba) "zslba 0x%"PRIx64""
+pci_nvme_err_zone_boundary(uint64_t slba, uint32_t nlb, uint64_t zcap) "lba
0x%"PRIx64" nlb %"PRIu32" zcap 0x%"PRIx64""
+pci_nvme_err_zone_invalid_write(uint64_t slba, uint64_t wp) "lba 0x%"PRIx64"
wp 0x%"PRIx64""
pci_nvme_err_zone_write_not_ok(uint64_t slba, uint32_t nlb, uint16_t status)
"slba=%"PRIu64", nlb=%"PRIu32", status=0x%"PRIx16""
pci_nvme_err_zone_read_not_ok(uint64_t slba, uint32_t nlb, uint16_t status)
"slba=%"PRIu64", nlb=%"PRIu32", status=0x%"PRIx16""
pci_nvme_err_append_too_large(uint64_t slba, uint32_t nlb, uint8_t zasl)
"slba=%"PRIu64", nlb=%"PRIu32", zasl=%"PRIu8""
--
2.30.0
- [PULL 33/56] hw/block/nvme: remove unused argument in nvme_ns_setup, (continued)
- [PULL 33/56] hw/block/nvme: remove unused argument in nvme_ns_setup, Klaus Jensen, 2021/02/09
- [PULL 38/56] hw/block/nvme: add size to mmio read/write trace events, Klaus Jensen, 2021/02/09
- [PULL 32/56] hw/block/nvme: split setup and register for namespace, Klaus Jensen, 2021/02/09
- [PULL 35/56] nvme: introduce bit 5 for critical warning, Klaus Jensen, 2021/02/09
- [PULL 42/56] hw/block/nvme: allow cmb and pmr to coexist, Klaus Jensen, 2021/02/09
- [PULL 46/56] hw/block/nvme: add PMR RDS/WDS support, Klaus Jensen, 2021/02/09
- [PULL 50/56] hw/block/nvme: error if drive less than a zone size, Klaus Jensen, 2021/02/09
- [PULL 37/56] hw/block/nvme: trigger async event during injecting smart warning, Klaus Jensen, 2021/02/09
- [PULL 47/56] hw/block/nvme: move cmb logic to v1.4, Klaus Jensen, 2021/02/09
- [PULL 54/56] hw/block/nvme: fix wrong parameter name 'cross_read', Klaus Jensen, 2021/02/09
- [PULL 56/56] hw/block/nvme: refactor the logic for zone write checks,
Klaus Jensen <=
- [PULL 43/56] hw/block/nvme: rename PMR/CMB shift/mask fields, Klaus Jensen, 2021/02/09
- [PULL 36/56] hw/block/nvme: add smart_critical_warning property, Klaus Jensen, 2021/02/09
- [PULL 34/56] hw/block/nvme: fix zone write finalize, Klaus Jensen, 2021/02/09
- [PULL 51/56] hw/block/nvme: fix set feature for error recovery, Klaus Jensen, 2021/02/09
- [PULL 44/56] hw/block/nvme: remove redundant zeroing of PMR registers, Klaus Jensen, 2021/02/09
- [PULL 49/56] hw/block/nvme: lift cmb restrictions, Klaus Jensen, 2021/02/09
- [PULL 53/56] hw/block/nvme: align with existing style, Klaus Jensen, 2021/02/09
- [PULL 55/56] hw/block/nvme: fix zone boundary check for append, Klaus Jensen, 2021/02/09
- [PULL 52/56] hw/block/nvme: fix set feature save field check, Klaus Jensen, 2021/02/09
- Re: [PULL 00/56] emulated nvme patches, Peter Maydell, 2021/02/09