Message ID | 20230908073152.4386-3-dave@stgolabs.net |
---|---|
State | New, archived |
Headers | show |
Series | hw/cxl: Support for scan media | expand |
On Fri, Sep 08, 2023 at 12:31:50AM -0700, Davidlohr Bueso wrote: > Use simple heuristics to determine the cost of scanning any given > chunk, assuming cost is equal across the whole device, without > differentiating between volatile or persistent partitions. This > is aligned to the fact that these constraints are not enforced > in respective poison query commands. > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> > --- > hw/cxl/cxl-mailbox-utils.c | 53 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c > index 4e8651ebe2e9..3073222060ab 100644 > --- a/hw/cxl/cxl-mailbox-utils.c > +++ b/hw/cxl/cxl-mailbox-utils.c > @@ -80,6 +80,7 @@ enum { > #define GET_POISON_LIST 0x0 > #define INJECT_POISON 0x1 > #define CLEAR_POISON 0x2 > + #define GET_SCAN_MEDIA_CAPABILITIES 0x3 > DCD_CONFIG = 0x48, > #define GET_DC_CONFIG 0x0 > #define GET_DYN_CAP_EXT_LIST 0x1 > @@ -1174,6 +1175,56 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd, > return CXL_MBOX_SUCCESS; > } > > +/* > + * CXL r3.0 section 8.2.9.8.4.4: Get Scan Media Capabilities > + */ > +static CXLRetCode > +cmd_media_get_scan_media_capabilities(const struct cxl_cmd *cmd, > + uint8_t *payload_in, > + size_t len_in, > + uint8_t *payload_out, > + size_t *len_out, > + CXLCCI *cci) > +{ > + struct get_scan_media_capabilities_pl { > + uint64_t pa; > + uint64_t length; > + } QEMU_PACKED; > + > + struct get_scan_media_capabilities_out_pl { > + uint32_t estimated_runtime_ms; > + } QEMU_PACKED; > + > + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); > + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate; > + struct get_scan_media_capabilities_pl *in = (void *)payload_in; > + struct get_scan_media_capabilities_out_pl *out = (void *)payload_out; > + uint64_t query_start; > + uint64_t query_length; > + > + query_start = ldq_le_p(&in->pa); > + /* 64 byte alignment required */ > + if (query_start & 0x3f) { > + return CXL_MBOX_INVALID_INPUT; From the spec, it is not clear to me whether we should return invalid input or invalid PA. Fan > + } > + query_length = ldq_le_p(&in->length) * CXL_CACHE_LINE_SIZE; > + > + if (query_start + query_length > cxl_dstate->static_mem_size) { > + return CXL_MBOX_INVALID_PA; > + } > + > + /* > + * Just use 400 nanosecond access/read latency + 100 ns for > + * the cost of updating the poison list. For small enough > + * chunks return at least 1 ms. > + */ > + stl_le_p(&out->estimated_runtime_ms, > + MAX(1, query_length * (0.0005L/64))); > + > + *len_out = sizeof(*out); > + return CXL_MBOX_SUCCESS; > +} > + > /* > * CXL r3.0 section 8.2.9.8.9.1: Dynamic Capacity Configuration > */ > @@ -1602,6 +1653,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { > cmd_media_inject_poison, 8, 0 }, > [MEDIA_AND_POISON][CLEAR_POISON] = { "MEDIA_AND_POISON_CLEAR_POISON", > cmd_media_clear_poison, 72, 0 }, > + [MEDIA_AND_POISON][GET_SCAN_MEDIA_CAPABILITIES] = { "MEDIA_AND_POISON_GET_SCAN_MEDIA_CAPABILITIES", > + cmd_media_get_scan_media_capabilities, 16, 0 }, > }; > > static const struct cxl_cmd cxl_cmd_set_dcd[256][256] = { > -- > 2.42.0 >
On Fri, 08 Sep 2023, Fan Ni wrote: >On Fri, Sep 08, 2023 at 12:31:50AM -0700, Davidlohr Bueso wrote: >> +static CXLRetCode >> +cmd_media_get_scan_media_capabilities(const struct cxl_cmd *cmd, >> + uint8_t *payload_in, >> + size_t len_in, >> + uint8_t *payload_out, >> + size_t *len_out, >> + CXLCCI *cci) >> +{ >> + struct get_scan_media_capabilities_pl { >> + uint64_t pa; >> + uint64_t length; >> + } QEMU_PACKED; >> + >> + struct get_scan_media_capabilities_out_pl { >> + uint32_t estimated_runtime_ms; >> + } QEMU_PACKED; >> + >> + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); >> + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate; >> + struct get_scan_media_capabilities_pl *in = (void *)payload_in; >> + struct get_scan_media_capabilities_out_pl *out = (void *)payload_out; >> + uint64_t query_start; >> + uint64_t query_length; >> + >> + query_start = ldq_le_p(&in->pa); >> + /* 64 byte alignment required */ >> + if (query_start & 0x3f) { >> + return CXL_MBOX_INVALID_INPUT; > >From the spec, it is not clear to me whether we should return invalid >input or invalid PA. The way I interpret it, which is also what get poison list does, is invalid input is better served as invalid pa mostly means that the actual address is invalid to the dpa space in question. Thanks, Davidlohr
On Fri, 8 Sep 2023 00:31:50 -0700 Davidlohr Bueso <dave@stgolabs.net> wrote: > Use simple heuristics to determine the cost of scanning any given > chunk, assuming cost is equal across the whole device, without > differentiating between volatile or persistent partitions. This > is aligned to the fact that these constraints are not enforced > in respective poison query commands. > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> Looks good to me I'll queue this up on my gitlab tree for now given it is dependent on the CCI rework at least. I should figure out how to move that forward independent of solving the question of how to provide the MCTP hosts adapters. Still need the NVME series to land first though and seems that has had some more feedback today. I might shuffle the tree around to pull this ahead of DCD (possibly carrying the rename of static_mem_size along with it to simplify the rebase). I suspect this will be easier to get upstream as it is short and sweet. Jonathan > --- > hw/cxl/cxl-mailbox-utils.c | 53 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c > index 4e8651ebe2e9..3073222060ab 100644 > --- a/hw/cxl/cxl-mailbox-utils.c > +++ b/hw/cxl/cxl-mailbox-utils.c > @@ -80,6 +80,7 @@ enum { > #define GET_POISON_LIST 0x0 > #define INJECT_POISON 0x1 > #define CLEAR_POISON 0x2 > + #define GET_SCAN_MEDIA_CAPABILITIES 0x3 > DCD_CONFIG = 0x48, > #define GET_DC_CONFIG 0x0 > #define GET_DYN_CAP_EXT_LIST 0x1 > @@ -1174,6 +1175,56 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd, > return CXL_MBOX_SUCCESS; > } > > +/* > + * CXL r3.0 section 8.2.9.8.4.4: Get Scan Media Capabilities > + */ > +static CXLRetCode > +cmd_media_get_scan_media_capabilities(const struct cxl_cmd *cmd, > + uint8_t *payload_in, > + size_t len_in, > + uint8_t *payload_out, > + size_t *len_out, > + CXLCCI *cci) > +{ > + struct get_scan_media_capabilities_pl { > + uint64_t pa; > + uint64_t length; > + } QEMU_PACKED; > + > + struct get_scan_media_capabilities_out_pl { > + uint32_t estimated_runtime_ms; > + } QEMU_PACKED; > + > + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); > + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate; > + struct get_scan_media_capabilities_pl *in = (void *)payload_in; > + struct get_scan_media_capabilities_out_pl *out = (void *)payload_out; > + uint64_t query_start; > + uint64_t query_length; > + > + query_start = ldq_le_p(&in->pa); > + /* 64 byte alignment required */ > + if (query_start & 0x3f) { > + return CXL_MBOX_INVALID_INPUT; > + } > + query_length = ldq_le_p(&in->length) * CXL_CACHE_LINE_SIZE; > + > + if (query_start + query_length > cxl_dstate->static_mem_size) { > + return CXL_MBOX_INVALID_PA; > + } > + > + /* > + * Just use 400 nanosecond access/read latency + 100 ns for > + * the cost of updating the poison list. For small enough > + * chunks return at least 1 ms. > + */ > + stl_le_p(&out->estimated_runtime_ms, > + MAX(1, query_length * (0.0005L/64))); > + > + *len_out = sizeof(*out); > + return CXL_MBOX_SUCCESS; > +} > + > /* > * CXL r3.0 section 8.2.9.8.9.1: Dynamic Capacity Configuration > */ > @@ -1602,6 +1653,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { > cmd_media_inject_poison, 8, 0 }, > [MEDIA_AND_POISON][CLEAR_POISON] = { "MEDIA_AND_POISON_CLEAR_POISON", > cmd_media_clear_poison, 72, 0 }, > + [MEDIA_AND_POISON][GET_SCAN_MEDIA_CAPABILITIES] = { "MEDIA_AND_POISON_GET_SCAN_MEDIA_CAPABILITIES", > + cmd_media_get_scan_media_capabilities, 16, 0 }, > }; > > static const struct cxl_cmd cxl_cmd_set_dcd[256][256] = {
On Fri, 8 Sep 2023 00:31:50 -0700 Davidlohr Bueso <dave@stgolabs.net> wrote: > Use simple heuristics to determine the cost of scanning any given > chunk, assuming cost is equal across the whole device, without > differentiating between volatile or persistent partitions. This > is aligned to the fact that these constraints are not enforced > in respective poison query commands. > > Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> > --- > hw/cxl/cxl-mailbox-utils.c | 53 ++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c > index 4e8651ebe2e9..3073222060ab 100644 > --- a/hw/cxl/cxl-mailbox-utils.c > +++ b/hw/cxl/cxl-mailbox-utils.c > @@ -80,6 +80,7 @@ enum { > #define GET_POISON_LIST 0x0 > #define INJECT_POISON 0x1 > #define CLEAR_POISON 0x2 > + #define GET_SCAN_MEDIA_CAPABILITIES 0x3 > DCD_CONFIG = 0x48, > #define GET_DC_CONFIG 0x0 > #define GET_DYN_CAP_EXT_LIST 0x1 > @@ -1174,6 +1175,56 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd, > return CXL_MBOX_SUCCESS; > } > > +/* > + * CXL r3.0 section 8.2.9.8.4.4: Get Scan Media Capabilities > + */ > +static CXLRetCode > +cmd_media_get_scan_media_capabilities(const struct cxl_cmd *cmd, > + uint8_t *payload_in, > + size_t len_in, > + uint8_t *payload_out, > + size_t *len_out, > + CXLCCI *cci) > +{ > + struct get_scan_media_capabilities_pl { > + uint64_t pa; > + uint64_t length; > + } QEMU_PACKED; > + > + struct get_scan_media_capabilities_out_pl { > + uint32_t estimated_runtime_ms; > + } QEMU_PACKED; > + > + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); > + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate; > + struct get_scan_media_capabilities_pl *in = (void *)payload_in; > + struct get_scan_media_capabilities_out_pl *out = (void *)payload_out; > + uint64_t query_start; > + uint64_t query_length; > + > + query_start = ldq_le_p(&in->pa); > + /* 64 byte alignment required */ > + if (query_start & 0x3f) { > + return CXL_MBOX_INVALID_INPUT; > + } > + query_length = ldq_le_p(&in->length) * CXL_CACHE_LINE_SIZE; > + > + if (query_start + query_length > cxl_dstate->static_mem_size) { > + return CXL_MBOX_INVALID_PA; > + } > + > + /* > + * Just use 400 nanosecond access/read latency + 100 ns for > + * the cost of updating the poison list. For small enough > + * chunks return at least 1 ms. > + */ > + stl_le_p(&out->estimated_runtime_ms, > + MAX(1, query_length * (0.0005L/64))); Forgot to say I added spaces around the / > + > + *len_out = sizeof(*out); > + return CXL_MBOX_SUCCESS; > +} > + > /* > * CXL r3.0 section 8.2.9.8.9.1: Dynamic Capacity Configuration > */ > @@ -1602,6 +1653,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { > cmd_media_inject_poison, 8, 0 }, > [MEDIA_AND_POISON][CLEAR_POISON] = { "MEDIA_AND_POISON_CLEAR_POISON", > cmd_media_clear_poison, 72, 0 }, > + [MEDIA_AND_POISON][GET_SCAN_MEDIA_CAPABILITIES] = { "MEDIA_AND_POISON_GET_SCAN_MEDIA_CAPABILITIES", I rewrapped this to keep under 80 chars. Jonathan > + cmd_media_get_scan_media_capabilities, 16, 0 }, > }; > > static const struct cxl_cmd cxl_cmd_set_dcd[256][256] = {
diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 4e8651ebe2e9..3073222060ab 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -80,6 +80,7 @@ enum { #define GET_POISON_LIST 0x0 #define INJECT_POISON 0x1 #define CLEAR_POISON 0x2 + #define GET_SCAN_MEDIA_CAPABILITIES 0x3 DCD_CONFIG = 0x48, #define GET_DC_CONFIG 0x0 #define GET_DYN_CAP_EXT_LIST 0x1 @@ -1174,6 +1175,56 @@ static CXLRetCode cmd_media_clear_poison(const struct cxl_cmd *cmd, return CXL_MBOX_SUCCESS; } +/* + * CXL r3.0 section 8.2.9.8.4.4: Get Scan Media Capabilities + */ +static CXLRetCode +cmd_media_get_scan_media_capabilities(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + struct get_scan_media_capabilities_pl { + uint64_t pa; + uint64_t length; + } QEMU_PACKED; + + struct get_scan_media_capabilities_out_pl { + uint32_t estimated_runtime_ms; + } QEMU_PACKED; + + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); + CXLDeviceState *cxl_dstate = &ct3d->cxl_dstate; + struct get_scan_media_capabilities_pl *in = (void *)payload_in; + struct get_scan_media_capabilities_out_pl *out = (void *)payload_out; + uint64_t query_start; + uint64_t query_length; + + query_start = ldq_le_p(&in->pa); + /* 64 byte alignment required */ + if (query_start & 0x3f) { + return CXL_MBOX_INVALID_INPUT; + } + query_length = ldq_le_p(&in->length) * CXL_CACHE_LINE_SIZE; + + if (query_start + query_length > cxl_dstate->static_mem_size) { + return CXL_MBOX_INVALID_PA; + } + + /* + * Just use 400 nanosecond access/read latency + 100 ns for + * the cost of updating the poison list. For small enough + * chunks return at least 1 ms. + */ + stl_le_p(&out->estimated_runtime_ms, + MAX(1, query_length * (0.0005L/64))); + + *len_out = sizeof(*out); + return CXL_MBOX_SUCCESS; +} + /* * CXL r3.0 section 8.2.9.8.9.1: Dynamic Capacity Configuration */ @@ -1602,6 +1653,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { cmd_media_inject_poison, 8, 0 }, [MEDIA_AND_POISON][CLEAR_POISON] = { "MEDIA_AND_POISON_CLEAR_POISON", cmd_media_clear_poison, 72, 0 }, + [MEDIA_AND_POISON][GET_SCAN_MEDIA_CAPABILITIES] = { "MEDIA_AND_POISON_GET_SCAN_MEDIA_CAPABILITIES", + cmd_media_get_scan_media_capabilities, 16, 0 }, }; static const struct cxl_cmd cxl_cmd_set_dcd[256][256] = {
Use simple heuristics to determine the cost of scanning any given chunk, assuming cost is equal across the whole device, without differentiating between volatile or persistent partitions. This is aligned to the fact that these constraints are not enforced in respective poison query commands. Signed-off-by: Davidlohr Bueso <dave@stgolabs.net> --- hw/cxl/cxl-mailbox-utils.c | 53 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)