Skip to content

Commit 4b759dd

Browse files
djbwdavejiang
authored andcommitted
cxl/core: Fix potential payload size confusion in cxl_mem_get_poison()
A recent change to cxl_mem_get_records_log() [1] highlighted a subtle nuance of looping calls to cxl_internal_send_cmd(), i.e. that cxl_internal_send_cmd() modifies the 'size_out' member of the @mbox_cmd argument. That mechanism is useful for communicating underflow, but it is unwanted when reusing @mbox_cmd for a subsequent submission. It turns out that cxl_xfer_log() avoids this scenario by always redefining @mbox_cmd each iteration. Update cxl_mem_get_records_log() and cxl_mem_get_poison() to follow the same style as cxl_xfer_log(), i.e. re-define @mbox_cmd each iteration. The cxl_mem_get_records_log() change is just a style fixup, but the cxl_mem_get_poison() change is a potential fix, per Alison [2]: Poison list retrieval can hit this case if the MORE flag is set and a follow on read of the list delivers more records than the previous read. ie. device gives one record, sets the _MORE flag, then gives 5. Not an urgent fix since this behavior has not been seen in the wild, but worth tracking as a fix. Cc: Kwangjin Ko <[email protected]> Cc: Alison Schofield <[email protected]> Fixes: ed83f7c ("cxl/mbox: Add GET_POISON_LIST mailbox command") Link: http://lore.kernel.org/r/[email protected] [1] Link: http://lore.kernel.org/r/ZhAhAL/GOaWFrauw@aschofie-mobl2 [2] Signed-off-by: Dan Williams <[email protected]> Reviewed-by: Ira Weiny <[email protected]> Reviewed-by: Alison Schofield <[email protected]> Link: https://lore.kernel.org/r/171235441633.2716581.12330082428680958635.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dave Jiang <[email protected]>
1 parent ed30a4a commit 4b759dd

File tree

1 file changed

+17
-21
lines changed

1 file changed

+17
-21
lines changed

drivers/cxl/core/mbox.c

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -946,25 +946,22 @@ static void cxl_mem_get_records_log(struct cxl_memdev_state *mds,
946946
struct cxl_memdev *cxlmd = mds->cxlds.cxlmd;
947947
struct device *dev = mds->cxlds.dev;
948948
struct cxl_get_event_payload *payload;
949-
struct cxl_mbox_cmd mbox_cmd;
950949
u8 log_type = type;
951950
u16 nr_rec;
952951

953952
mutex_lock(&mds->event.log_lock);
954953
payload = mds->event.buf;
955954

956-
mbox_cmd = (struct cxl_mbox_cmd) {
957-
.opcode = CXL_MBOX_OP_GET_EVENT_RECORD,
958-
.payload_in = &log_type,
959-
.size_in = sizeof(log_type),
960-
.payload_out = payload,
961-
.min_out = struct_size(payload, records, 0),
962-
};
963-
964955
do {
965956
int rc, i;
966-
967-
mbox_cmd.size_out = mds->payload_size;
957+
struct cxl_mbox_cmd mbox_cmd = (struct cxl_mbox_cmd) {
958+
.opcode = CXL_MBOX_OP_GET_EVENT_RECORD,
959+
.payload_in = &log_type,
960+
.size_in = sizeof(log_type),
961+
.payload_out = payload,
962+
.size_out = mds->payload_size,
963+
.min_out = struct_size(payload, records, 0),
964+
};
968965

969966
rc = cxl_internal_send_cmd(mds, &mbox_cmd);
970967
if (rc) {
@@ -1297,7 +1294,6 @@ int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
12971294
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
12981295
struct cxl_mbox_poison_out *po;
12991296
struct cxl_mbox_poison_in pi;
1300-
struct cxl_mbox_cmd mbox_cmd;
13011297
int nr_records = 0;
13021298
int rc;
13031299

@@ -1309,16 +1305,16 @@ int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
13091305
pi.offset = cpu_to_le64(offset);
13101306
pi.length = cpu_to_le64(len / CXL_POISON_LEN_MULT);
13111307

1312-
mbox_cmd = (struct cxl_mbox_cmd) {
1313-
.opcode = CXL_MBOX_OP_GET_POISON,
1314-
.size_in = sizeof(pi),
1315-
.payload_in = &pi,
1316-
.size_out = mds->payload_size,
1317-
.payload_out = po,
1318-
.min_out = struct_size(po, record, 0),
1319-
};
1320-
13211308
do {
1309+
struct cxl_mbox_cmd mbox_cmd = (struct cxl_mbox_cmd){
1310+
.opcode = CXL_MBOX_OP_GET_POISON,
1311+
.size_in = sizeof(pi),
1312+
.payload_in = &pi,
1313+
.size_out = mds->payload_size,
1314+
.payload_out = po,
1315+
.min_out = struct_size(po, record, 0),
1316+
};
1317+
13221318
rc = cxl_internal_send_cmd(mds, &mbox_cmd);
13231319
if (rc)
13241320
break;

0 commit comments

Comments
 (0)