Commit 364ee9f3 authored by Ira Weiny's avatar Ira Weiny Committed by Dave Jiang

cxl/test: Enhance event testing

An issue was found in the processing of event logs when the output
buffer length was not reset.[1]

This bug was not caught with cxl-test for 2 reasons.  First, the test
harness mbox_send command [mock_get_event()] does not set the output
size based on the amount of data returned like the hardware command
does.  Second, the simplistic event log testing always returned the same
number of elements per-get command.

Enhance the simulation of the event log mailbox to better match the bug
found with real hardware to cover potential regressions.

NOTE: These changes will cause cxl-events.sh in ndctl to fail without
the fix from Kwangjin.  However, no changes to the user space test was
required.  Therefore ndctl itself will be compatible with old or new
kernels once both patches land in the new kernel.

[1] Link: https://lore.kernel.org/all/20240401091057.1044-1-kwangjin.ko@sk.com/

Cc: Kwangjin Ko <kwangjin.ko@sk.com>
Signed-off-by: default avatarIra Weiny <ira.weiny@intel.com>
Reviewed-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
Link: https://lore.kernel.org/r/20240401-enhance-event-test-v1-1-6669a524ed38@intel.comSigned-off-by: default avatarDave Jiang <dave.jiang@intel.com>
parent 54e8dd59
...@@ -127,7 +127,7 @@ static struct { ...@@ -127,7 +127,7 @@ static struct {
#define CXL_TEST_EVENT_CNT_MAX 15 #define CXL_TEST_EVENT_CNT_MAX 15
/* Set a number of events to return at a time for simulation. */ /* Set a number of events to return at a time for simulation. */
#define CXL_TEST_EVENT_CNT 3 #define CXL_TEST_EVENT_RET_MAX 4
struct mock_event_log { struct mock_event_log {
u16 clear_idx; u16 clear_idx;
...@@ -222,6 +222,12 @@ static void mes_add_event(struct mock_event_store *mes, ...@@ -222,6 +222,12 @@ static void mes_add_event(struct mock_event_store *mes,
log->nr_events++; log->nr_events++;
} }
/*
* Vary the number of events returned to simulate events occuring while the
* logs are being read.
*/
static int ret_limit = 0;
static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd) static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd)
{ {
struct cxl_get_event_payload *pl; struct cxl_get_event_payload *pl;
...@@ -233,14 +239,18 @@ static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd) ...@@ -233,14 +239,18 @@ static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd)
if (cmd->size_in != sizeof(log_type)) if (cmd->size_in != sizeof(log_type))
return -EINVAL; return -EINVAL;
if (cmd->size_out < struct_size(pl, records, CXL_TEST_EVENT_CNT)) ret_limit = (ret_limit + 1) % CXL_TEST_EVENT_RET_MAX;
if (!ret_limit)
ret_limit = 1;
if (cmd->size_out < struct_size(pl, records, ret_limit))
return -EINVAL; return -EINVAL;
log_type = *((u8 *)cmd->payload_in); log_type = *((u8 *)cmd->payload_in);
if (log_type >= CXL_EVENT_TYPE_MAX) if (log_type >= CXL_EVENT_TYPE_MAX)
return -EINVAL; return -EINVAL;
memset(cmd->payload_out, 0, cmd->size_out); memset(cmd->payload_out, 0, struct_size(pl, records, 0));
log = event_find_log(dev, log_type); log = event_find_log(dev, log_type);
if (!log || event_log_empty(log)) if (!log || event_log_empty(log))
...@@ -248,7 +258,7 @@ static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd) ...@@ -248,7 +258,7 @@ static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd)
pl = cmd->payload_out; pl = cmd->payload_out;
for (i = 0; i < CXL_TEST_EVENT_CNT && !event_log_empty(log); i++) { for (i = 0; i < ret_limit && !event_log_empty(log); i++) {
memcpy(&pl->records[i], event_get_current(log), memcpy(&pl->records[i], event_get_current(log),
sizeof(pl->records[i])); sizeof(pl->records[i]));
pl->records[i].event.generic.hdr.handle = pl->records[i].event.generic.hdr.handle =
...@@ -256,6 +266,7 @@ static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd) ...@@ -256,6 +266,7 @@ static int mock_get_event(struct device *dev, struct cxl_mbox_cmd *cmd)
log->cur_idx++; log->cur_idx++;
} }
cmd->size_out = struct_size(pl, records, i);
pl->record_count = cpu_to_le16(i); pl->record_count = cpu_to_le16(i);
if (!event_log_empty(log)) if (!event_log_empty(log))
pl->flags |= CXL_GET_EVENT_FLAG_MORE_RECORDS; pl->flags |= CXL_GET_EVENT_FLAG_MORE_RECORDS;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment