[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v3 4/4] hw/blocl/nvme: trigger async event during injecting smart
From: |
zhenwei pi |
Subject: |
[PATCH v3 4/4] hw/blocl/nvme: trigger async event during injecting smart warning |
Date: |
Thu, 14 Jan 2021 15:22:51 +0800 |
During smart critical warning injection by setting property from QMP
command, also try to trigger asynchronous event.
Signed-off-by: zhenwei pi <pizhenwei@bytedance.com>
---
hw/block/nvme.c | 47 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 40 insertions(+), 7 deletions(-)
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index ce9a9c9023..1feb603471 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -847,6 +847,36 @@ static void nvme_enqueue_event(NvmeCtrl *n, uint8_t
event_type,
nvme_process_aers(n);
}
+static void nvme_enqueue_smart_event(NvmeCtrl *n, uint8_t event)
+{
+ uint8_t aer_info;
+
+ if (!(NVME_AEC_SMART(n->features.async_config) & event)) {
+ return;
+ }
+
+ /* Ref SPEC <Asynchronous Event Information â SMART / Health Status> */
+ switch (event) {
+ case NVME_SMART_SPARE:
+ aer_info = NVME_AER_INFO_SMART_SPARE_THRESH;
+ break;
+ case NVME_SMART_TEMPERATURE:
+ aer_info = NVME_AER_INFO_SMART_TEMP_THRESH;
+ break;
+ case NVME_SMART_RELIABILITY:
+ case NVME_SMART_MEDIA_READ_ONLY:
+ case NVME_SMART_FAILED_VOLATILE_MEDIA:
+ aer_info = NVME_AER_INFO_SMART_RELIABILITY;
+ break;
+ case NVME_SMART_PMR_UNRELIABLE:
+ /* TODO if NVME_SMART_PMR_UNRELIABLE is defined in future */
+ default:
+ return;
+ }
+
+ nvme_enqueue_event(n, NVME_AER_TYPE_SMART, aer_info, NVME_LOG_SMART_INFO);
+}
+
static void nvme_clear_events(NvmeCtrl *n, uint8_t event_type)
{
n->aer_mask &= ~(1 << event_type);
@@ -1824,12 +1854,9 @@ static uint16_t nvme_set_feature(NvmeCtrl *n,
NvmeRequest *req)
return NVME_INVALID_FIELD | NVME_DNR;
}
- if (((n->temperature >= n->features.temp_thresh_hi) ||
- (n->temperature <= n->features.temp_thresh_low)) &&
- NVME_AEC_SMART(n->features.async_config) & NVME_SMART_TEMPERATURE)
{
- nvme_enqueue_event(n, NVME_AER_TYPE_SMART,
- NVME_AER_INFO_SMART_TEMP_THRESH,
- NVME_LOG_SMART_INFO);
+ if ((n->temperature >= n->features.temp_thresh_hi) ||
+ (n->temperature <= n->features.temp_thresh_low)) {
+ nvme_enqueue_smart_event(n, NVME_AER_INFO_SMART_TEMP_THRESH);
}
break;
@@ -2841,7 +2868,7 @@ static void nvme_set_smart_warning(Object *obj, Visitor
*v, const char *name,
void *opaque, Error **errp)
{
NvmeCtrl *s = NVME(obj);
- uint8_t value, cap = 0;
+ uint8_t value, cap = 0, event;
uint64_t pmr_cap = CAP_PMR_MASK;
if (!visit_type_uint8(v, name, &value, errp)) {
@@ -2860,6 +2887,12 @@ static void nvme_set_smart_warning(Object *obj, Visitor
*v, const char *name,
}
s->smart_critical_warning = value;
+
+ /* test each bit of uint8_t for smart.critical_warning */
+ for (event = 0; event < 8; event++) {
+ if (value & (1 << event))
+ nvme_enqueue_smart_event(s, 1 << event);
+ }
}
static const VMStateDescription nvme_vmstate = {
--
2.25.1