@@ -1761,6 +1761,53 @@ CXL_EXPORT int cxl_memdev_disable_invalidate(struct cxl_memdev *memdev)
return 0;
}
+CXL_EXPORT int cxl_memdev_trigger_poison_list(struct cxl_memdev *memdev)
+{
+ struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
+ char *path = memdev->dev_buf;
+ int len = memdev->buf_len, rc;
+
+ if (snprintf(path, len, "%s/trigger_poison_list",
+ memdev->dev_path) >= len) {
+ err(ctx, "%s: buffer too small\n",
+ cxl_memdev_get_devname(memdev));
+ return -ENXIO;
+ }
+ rc = sysfs_write_attr(ctx, path, "1\n");
+ if (rc < 0) {
+ fprintf(stderr,
+ "%s: Failed write sysfs attr trigger_poison_list\n",
+ cxl_memdev_get_devname(memdev));
+ return rc;
+ }
+ return 0;
+}
+
+CXL_EXPORT int cxl_region_trigger_poison_list(struct cxl_region *region)
+{
+ struct cxl_memdev_mapping *mapping;
+ int rc;
+
+ cxl_mapping_foreach(region, mapping) {
+ struct cxl_decoder *decoder;
+ struct cxl_memdev *memdev;
+
+ decoder = cxl_mapping_get_decoder(mapping);
+ if (!decoder)
+ continue;
+
+ memdev = cxl_decoder_get_memdev(decoder);
+ if (!memdev)
+ continue;
+
+ rc = cxl_memdev_trigger_poison_list(memdev);
+ if (rc)
+ return rc;
+ }
+
+ return 0;
+}
+
CXL_EXPORT int cxl_memdev_enable(struct cxl_memdev *memdev)
{
struct cxl_ctx *ctx = cxl_memdev_get_ctx(memdev);
@@ -280,4 +280,6 @@ global:
cxl_memdev_get_pmem_qos_class;
cxl_memdev_get_ram_qos_class;
cxl_region_qos_class_mismatch;
+ cxl_memdev_trigger_poison_list;
+ cxl_region_trigger_poison_list;
} LIBCXL_6;
@@ -467,6 +467,8 @@ enum cxl_setpartition_mode {
int cxl_cmd_partition_set_mode(struct cxl_cmd *cmd,
enum cxl_setpartition_mode mode);
+int cxl_memdev_trigger_poison_list(struct cxl_memdev *memdev);
+int cxl_region_trigger_poison_list(struct cxl_region *region);
int cxl_cmd_alert_config_set_life_used_prog_warn_threshold(struct cxl_cmd *cmd,
int threshold);