Loading drivers/cxl/core/hdm.c +28 −41 Original line number Diff line number Diff line Loading @@ -213,13 +213,12 @@ void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds) { struct resource *p1, *p2; down_read(&cxl_dpa_rwsem); guard(rwsem_read)(&cxl_dpa_rwsem); for (p1 = cxlds->dpa_res.child; p1; p1 = p1->sibling) { __cxl_dpa_debug(file, p1, 0); for (p2 = p1->child; p2; p2 = p2->sibling) __cxl_dpa_debug(file, p2, 1); } up_read(&cxl_dpa_rwsem); } EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, "CXL"); Loading Loading @@ -281,9 +280,8 @@ static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled) static void cxl_dpa_release(void *cxled) { down_write(&cxl_dpa_rwsem); guard(rwsem_write)(&cxl_dpa_rwsem); __cxl_dpa_release(cxled); up_write(&cxl_dpa_rwsem); } /* Loading Loading @@ -530,14 +528,11 @@ EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, "CXL"); resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled) { resource_size_t size = 0; down_read(&cxl_dpa_rwsem); guard(rwsem_read)(&cxl_dpa_rwsem); if (cxled->dpa_res) size = resource_size(cxled->dpa_res); up_read(&cxl_dpa_rwsem); return resource_size(cxled->dpa_res); return size; return 0; } resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled) Loading @@ -555,35 +550,27 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled) { struct cxl_port *port = cxled_to_port(cxled); struct device *dev = &cxled->cxld.dev; int rc; down_write(&cxl_dpa_rwsem); if (!cxled->dpa_res) { rc = 0; goto out; } guard(rwsem_write)(&cxl_dpa_rwsem); if (!cxled->dpa_res) return 0; if (cxled->cxld.region) { dev_dbg(dev, "decoder assigned to: %s\n", dev_name(&cxled->cxld.region->dev)); rc = -EBUSY; goto out; return -EBUSY; } if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) { dev_dbg(dev, "decoder enabled\n"); rc = -EBUSY; goto out; return -EBUSY; } if (cxled->cxld.id != port->hdm_end) { dev_dbg(dev, "expected decoder%d.%d\n", port->id, port->hdm_end); rc = -EBUSY; goto out; return -EBUSY; } devm_cxl_dpa_release(cxled); rc = 0; out: up_write(&cxl_dpa_rwsem); return rc; return 0; } int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled, Loading Loading @@ -616,36 +603,32 @@ int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled, return 0; } int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) static int __cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); struct cxl_port *port = cxled_to_port(cxled); struct cxl_dev_state *cxlds = cxlmd->cxlds; struct device *dev = &cxled->cxld.dev; struct resource *res, *prev = NULL; resource_size_t start, avail, skip, skip_start; struct resource *p, *last; int part, rc; int part; down_write(&cxl_dpa_rwsem); guard(rwsem_write)(&cxl_dpa_rwsem); if (cxled->cxld.region) { dev_dbg(dev, "decoder attached to %s\n", dev_name(&cxled->cxld.region->dev)); rc = -EBUSY; goto out; return -EBUSY; } if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) { dev_dbg(dev, "decoder enabled\n"); rc = -EBUSY; goto out; return -EBUSY; } part = cxled->part; if (part < 0) { dev_dbg(dev, "partition not set\n"); rc = -EBUSY; goto out; return -EBUSY; } res = &cxlds->part[part].res; Loading Loading @@ -685,14 +668,18 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) if (size > avail) { dev_dbg(dev, "%pa exceeds available %s capacity: %pa\n", &size, res->name, &avail); rc = -ENOSPC; goto out; return -ENOSPC; } rc = __cxl_dpa_reserve(cxled, start, size, skip); out: up_write(&cxl_dpa_rwsem); return __cxl_dpa_reserve(cxled, start, size, skip); } int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) { struct cxl_port *port = cxled_to_port(cxled); int rc; rc = __cxl_dpa_alloc(cxled, size); if (rc) return rc; Loading drivers/cxl/core/mbox.c +3 −7 Original line number Diff line number Diff line Loading @@ -1218,23 +1218,19 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd) { struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct cxl_port *endpoint; int rc; /* synchronize with cxl_mem_probe() and decoder write operations */ guard(device)(&cxlmd->dev); endpoint = cxlmd->endpoint; down_read(&cxl_region_rwsem); guard(rwsem_read)(&cxl_region_rwsem); /* * Require an endpoint to be safe otherwise the driver can not * be sure that the device is unmapped. */ if (endpoint && cxl_num_decoders_committed(endpoint) == 0) rc = __cxl_mem_sanitize(mds, cmd); else rc = -EBUSY; up_read(&cxl_region_rwsem); return __cxl_mem_sanitize(mds, cmd); return rc; return -EBUSY; } static void add_part(struct cxl_dpa_info *info, u64 start, u64 size, enum cxl_partition_mode mode) Loading drivers/cxl/core/memdev.c +6 −11 Original line number Diff line number Diff line Loading @@ -580,10 +580,9 @@ EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL"); void set_exclusive_cxl_commands(struct cxl_memdev_state *mds, unsigned long *cmds) { down_write(&cxl_memdev_rwsem); guard(rwsem_write)(&cxl_memdev_rwsem); bitmap_or(mds->exclusive_cmds, mds->exclusive_cmds, cmds, CXL_MEM_COMMAND_ID_MAX); up_write(&cxl_memdev_rwsem); } EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL"); Loading @@ -595,10 +594,9 @@ EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL"); void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds, unsigned long *cmds) { down_write(&cxl_memdev_rwsem); guard(rwsem_write)(&cxl_memdev_rwsem); bitmap_andnot(mds->exclusive_cmds, mds->exclusive_cmds, cmds, CXL_MEM_COMMAND_ID_MAX); up_write(&cxl_memdev_rwsem); } EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, "CXL"); Loading @@ -606,9 +604,8 @@ static void cxl_memdev_shutdown(struct device *dev) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); down_write(&cxl_memdev_rwsem); guard(rwsem_write)(&cxl_memdev_rwsem); cxlmd->cxlds = NULL; up_write(&cxl_memdev_rwsem); } static void cxl_memdev_unregister(void *_cxlmd) Loading Loading @@ -687,15 +684,13 @@ static long cxl_memdev_ioctl(struct file *file, unsigned int cmd, { struct cxl_memdev *cxlmd = file->private_data; struct cxl_dev_state *cxlds; int rc = -ENXIO; down_read(&cxl_memdev_rwsem); guard(rwsem_read)(&cxl_memdev_rwsem); cxlds = cxlmd->cxlds; if (cxlds && cxlds->type == CXL_DEVTYPE_CLASSMEM) rc = __cxl_memdev_ioctl(cxlmd, cmd, arg); up_read(&cxl_memdev_rwsem); return __cxl_memdev_ioctl(cxlmd, cmd, arg); return rc; return -ENXIO; } static int cxl_memdev_open(struct inode *inode, struct file *file) Loading drivers/cxl/core/port.c +2 −6 Original line number Diff line number Diff line Loading @@ -559,13 +559,9 @@ static ssize_t decoders_committed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cxl_port *port = to_cxl_port(dev); int rc; down_read(&cxl_region_rwsem); rc = sysfs_emit(buf, "%d\n", cxl_num_decoders_committed(port)); up_read(&cxl_region_rwsem); return rc; guard(rwsem_read)(&cxl_region_rwsem); return sysfs_emit(buf, "%d\n", cxl_num_decoders_committed(port)); } static DEVICE_ATTR_RO(decoders_committed); Loading drivers/cxl/core/region.c +49 −53 Original line number Diff line number Diff line Loading @@ -3037,17 +3037,13 @@ static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr) struct cxl_dax_region *cxlr_dax; struct device *dev; down_read(&cxl_region_rwsem); if (p->state != CXL_CONFIG_COMMIT) { cxlr_dax = ERR_PTR(-ENXIO); goto out; } guard(rwsem_read)(&cxl_region_rwsem); if (p->state != CXL_CONFIG_COMMIT) return ERR_PTR(-ENXIO); cxlr_dax = kzalloc(sizeof(*cxlr_dax), GFP_KERNEL); if (!cxlr_dax) { cxlr_dax = ERR_PTR(-ENOMEM); goto out; } if (!cxlr_dax) return ERR_PTR(-ENOMEM); cxlr_dax->hpa_range.start = p->res->start; cxlr_dax->hpa_range.end = p->res->end; Loading @@ -3060,8 +3056,6 @@ static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr) dev->parent = &cxlr->dev; dev->bus = &cxl_bus_type; dev->type = &cxl_dax_region_type; out: up_read(&cxl_region_rwsem); return cxlr_dax; } Loading Loading @@ -3207,7 +3201,6 @@ static int match_region_by_range(struct device *dev, const void *data) struct cxl_region_params *p; struct cxl_region *cxlr; const struct range *r = data; int rc = 0; if (!is_cxl_region(dev)) return 0; Loading @@ -3215,61 +3208,38 @@ static int match_region_by_range(struct device *dev, const void *data) cxlr = to_cxl_region(dev); p = &cxlr->params; down_read(&cxl_region_rwsem); guard(rwsem_read)(&cxl_region_rwsem); if (p->res && p->res->start == r->start && p->res->end == r->end) rc = 1; up_read(&cxl_region_rwsem); return 1; return rc; return 0; } /* Establish an empty region covering the given HPA range */ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, static int __construct_region(struct cxl_region *cxlr, struct cxl_root_decoder *cxlrd, struct cxl_endpoint_decoder *cxled) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); struct cxl_port *port = cxlrd_to_port(cxlrd); struct cxl_dev_state *cxlds = cxlmd->cxlds; struct range *hpa = &cxled->cxld.hpa_range; int rc, part = READ_ONCE(cxled->part); struct cxl_region_params *p; struct cxl_region *cxlr; struct resource *res; int rc; if (part < 0) return ERR_PTR(-EBUSY); do { cxlr = __create_region(cxlrd, cxlds->part[part].mode, atomic_read(&cxlrd->region_id)); } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY); if (IS_ERR(cxlr)) { dev_err(cxlmd->dev.parent, "%s:%s: %s failed assign region: %ld\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__, PTR_ERR(cxlr)); return cxlr; } down_write(&cxl_region_rwsem); guard(rwsem_write)(&cxl_region_rwsem); p = &cxlr->params; if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) { dev_err(cxlmd->dev.parent, "%s:%s: %s autodiscovery interrupted\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__); rc = -EBUSY; goto err; return -EBUSY; } set_bit(CXL_REGION_F_AUTO, &cxlr->flags); res = kmalloc(sizeof(*res), GFP_KERNEL); if (!res) { rc = -ENOMEM; goto err; } if (!res) return -ENOMEM; *res = DEFINE_RES_MEM_NAMED(hpa->start, range_len(hpa), dev_name(&cxlr->dev)); Loading @@ -3292,7 +3262,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, rc = sysfs_update_group(&cxlr->dev.kobj, get_cxl_region_target_group()); if (rc) goto err; return rc; dev_dbg(cxlmd->dev.parent, "%s:%s: %s %s res: %pr iw: %d ig: %d\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__, Loading @@ -3301,16 +3271,42 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, /* ...to match put_device() in cxl_add_to_region() */ get_device(&cxlr->dev); up_write(&cxl_region_rwsem); return 0; } /* Establish an empty region covering the given HPA range */ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, struct cxl_endpoint_decoder *cxled) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); struct cxl_port *port = cxlrd_to_port(cxlrd); struct cxl_dev_state *cxlds = cxlmd->cxlds; int rc, part = READ_ONCE(cxled->part); struct cxl_region *cxlr; do { cxlr = __create_region(cxlrd, cxlds->part[part].mode, atomic_read(&cxlrd->region_id)); } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY); if (IS_ERR(cxlr)) { dev_err(cxlmd->dev.parent, "%s:%s: %s failed assign region: %ld\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__, PTR_ERR(cxlr)); return cxlr; } err: up_write(&cxl_region_rwsem); rc = __construct_region(cxlr, cxlrd, cxled); if (rc) { devm_release_action(port->uport_dev, unregister_region, cxlr); return ERR_PTR(rc); } return cxlr; } int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); Loading Loading
drivers/cxl/core/hdm.c +28 −41 Original line number Diff line number Diff line Loading @@ -213,13 +213,12 @@ void cxl_dpa_debug(struct seq_file *file, struct cxl_dev_state *cxlds) { struct resource *p1, *p2; down_read(&cxl_dpa_rwsem); guard(rwsem_read)(&cxl_dpa_rwsem); for (p1 = cxlds->dpa_res.child; p1; p1 = p1->sibling) { __cxl_dpa_debug(file, p1, 0); for (p2 = p1->child; p2; p2 = p2->sibling) __cxl_dpa_debug(file, p2, 1); } up_read(&cxl_dpa_rwsem); } EXPORT_SYMBOL_NS_GPL(cxl_dpa_debug, "CXL"); Loading Loading @@ -281,9 +280,8 @@ static void __cxl_dpa_release(struct cxl_endpoint_decoder *cxled) static void cxl_dpa_release(void *cxled) { down_write(&cxl_dpa_rwsem); guard(rwsem_write)(&cxl_dpa_rwsem); __cxl_dpa_release(cxled); up_write(&cxl_dpa_rwsem); } /* Loading Loading @@ -530,14 +528,11 @@ EXPORT_SYMBOL_NS_GPL(devm_cxl_dpa_reserve, "CXL"); resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled) { resource_size_t size = 0; down_read(&cxl_dpa_rwsem); guard(rwsem_read)(&cxl_dpa_rwsem); if (cxled->dpa_res) size = resource_size(cxled->dpa_res); up_read(&cxl_dpa_rwsem); return resource_size(cxled->dpa_res); return size; return 0; } resource_size_t cxl_dpa_resource_start(struct cxl_endpoint_decoder *cxled) Loading @@ -555,35 +550,27 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled) { struct cxl_port *port = cxled_to_port(cxled); struct device *dev = &cxled->cxld.dev; int rc; down_write(&cxl_dpa_rwsem); if (!cxled->dpa_res) { rc = 0; goto out; } guard(rwsem_write)(&cxl_dpa_rwsem); if (!cxled->dpa_res) return 0; if (cxled->cxld.region) { dev_dbg(dev, "decoder assigned to: %s\n", dev_name(&cxled->cxld.region->dev)); rc = -EBUSY; goto out; return -EBUSY; } if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) { dev_dbg(dev, "decoder enabled\n"); rc = -EBUSY; goto out; return -EBUSY; } if (cxled->cxld.id != port->hdm_end) { dev_dbg(dev, "expected decoder%d.%d\n", port->id, port->hdm_end); rc = -EBUSY; goto out; return -EBUSY; } devm_cxl_dpa_release(cxled); rc = 0; out: up_write(&cxl_dpa_rwsem); return rc; return 0; } int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled, Loading Loading @@ -616,36 +603,32 @@ int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled, return 0; } int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) static int __cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); struct cxl_port *port = cxled_to_port(cxled); struct cxl_dev_state *cxlds = cxlmd->cxlds; struct device *dev = &cxled->cxld.dev; struct resource *res, *prev = NULL; resource_size_t start, avail, skip, skip_start; struct resource *p, *last; int part, rc; int part; down_write(&cxl_dpa_rwsem); guard(rwsem_write)(&cxl_dpa_rwsem); if (cxled->cxld.region) { dev_dbg(dev, "decoder attached to %s\n", dev_name(&cxled->cxld.region->dev)); rc = -EBUSY; goto out; return -EBUSY; } if (cxled->cxld.flags & CXL_DECODER_F_ENABLE) { dev_dbg(dev, "decoder enabled\n"); rc = -EBUSY; goto out; return -EBUSY; } part = cxled->part; if (part < 0) { dev_dbg(dev, "partition not set\n"); rc = -EBUSY; goto out; return -EBUSY; } res = &cxlds->part[part].res; Loading Loading @@ -685,14 +668,18 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) if (size > avail) { dev_dbg(dev, "%pa exceeds available %s capacity: %pa\n", &size, res->name, &avail); rc = -ENOSPC; goto out; return -ENOSPC; } rc = __cxl_dpa_reserve(cxled, start, size, skip); out: up_write(&cxl_dpa_rwsem); return __cxl_dpa_reserve(cxled, start, size, skip); } int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size) { struct cxl_port *port = cxled_to_port(cxled); int rc; rc = __cxl_dpa_alloc(cxled, size); if (rc) return rc; Loading
drivers/cxl/core/mbox.c +3 −7 Original line number Diff line number Diff line Loading @@ -1218,23 +1218,19 @@ int cxl_mem_sanitize(struct cxl_memdev *cxlmd, u16 cmd) { struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds); struct cxl_port *endpoint; int rc; /* synchronize with cxl_mem_probe() and decoder write operations */ guard(device)(&cxlmd->dev); endpoint = cxlmd->endpoint; down_read(&cxl_region_rwsem); guard(rwsem_read)(&cxl_region_rwsem); /* * Require an endpoint to be safe otherwise the driver can not * be sure that the device is unmapped. */ if (endpoint && cxl_num_decoders_committed(endpoint) == 0) rc = __cxl_mem_sanitize(mds, cmd); else rc = -EBUSY; up_read(&cxl_region_rwsem); return __cxl_mem_sanitize(mds, cmd); return rc; return -EBUSY; } static void add_part(struct cxl_dpa_info *info, u64 start, u64 size, enum cxl_partition_mode mode) Loading
drivers/cxl/core/memdev.c +6 −11 Original line number Diff line number Diff line Loading @@ -580,10 +580,9 @@ EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, "CXL"); void set_exclusive_cxl_commands(struct cxl_memdev_state *mds, unsigned long *cmds) { down_write(&cxl_memdev_rwsem); guard(rwsem_write)(&cxl_memdev_rwsem); bitmap_or(mds->exclusive_cmds, mds->exclusive_cmds, cmds, CXL_MEM_COMMAND_ID_MAX); up_write(&cxl_memdev_rwsem); } EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL"); Loading @@ -595,10 +594,9 @@ EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, "CXL"); void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds, unsigned long *cmds) { down_write(&cxl_memdev_rwsem); guard(rwsem_write)(&cxl_memdev_rwsem); bitmap_andnot(mds->exclusive_cmds, mds->exclusive_cmds, cmds, CXL_MEM_COMMAND_ID_MAX); up_write(&cxl_memdev_rwsem); } EXPORT_SYMBOL_NS_GPL(clear_exclusive_cxl_commands, "CXL"); Loading @@ -606,9 +604,8 @@ static void cxl_memdev_shutdown(struct device *dev) { struct cxl_memdev *cxlmd = to_cxl_memdev(dev); down_write(&cxl_memdev_rwsem); guard(rwsem_write)(&cxl_memdev_rwsem); cxlmd->cxlds = NULL; up_write(&cxl_memdev_rwsem); } static void cxl_memdev_unregister(void *_cxlmd) Loading Loading @@ -687,15 +684,13 @@ static long cxl_memdev_ioctl(struct file *file, unsigned int cmd, { struct cxl_memdev *cxlmd = file->private_data; struct cxl_dev_state *cxlds; int rc = -ENXIO; down_read(&cxl_memdev_rwsem); guard(rwsem_read)(&cxl_memdev_rwsem); cxlds = cxlmd->cxlds; if (cxlds && cxlds->type == CXL_DEVTYPE_CLASSMEM) rc = __cxl_memdev_ioctl(cxlmd, cmd, arg); up_read(&cxl_memdev_rwsem); return __cxl_memdev_ioctl(cxlmd, cmd, arg); return rc; return -ENXIO; } static int cxl_memdev_open(struct inode *inode, struct file *file) Loading
drivers/cxl/core/port.c +2 −6 Original line number Diff line number Diff line Loading @@ -559,13 +559,9 @@ static ssize_t decoders_committed_show(struct device *dev, struct device_attribute *attr, char *buf) { struct cxl_port *port = to_cxl_port(dev); int rc; down_read(&cxl_region_rwsem); rc = sysfs_emit(buf, "%d\n", cxl_num_decoders_committed(port)); up_read(&cxl_region_rwsem); return rc; guard(rwsem_read)(&cxl_region_rwsem); return sysfs_emit(buf, "%d\n", cxl_num_decoders_committed(port)); } static DEVICE_ATTR_RO(decoders_committed); Loading
drivers/cxl/core/region.c +49 −53 Original line number Diff line number Diff line Loading @@ -3037,17 +3037,13 @@ static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr) struct cxl_dax_region *cxlr_dax; struct device *dev; down_read(&cxl_region_rwsem); if (p->state != CXL_CONFIG_COMMIT) { cxlr_dax = ERR_PTR(-ENXIO); goto out; } guard(rwsem_read)(&cxl_region_rwsem); if (p->state != CXL_CONFIG_COMMIT) return ERR_PTR(-ENXIO); cxlr_dax = kzalloc(sizeof(*cxlr_dax), GFP_KERNEL); if (!cxlr_dax) { cxlr_dax = ERR_PTR(-ENOMEM); goto out; } if (!cxlr_dax) return ERR_PTR(-ENOMEM); cxlr_dax->hpa_range.start = p->res->start; cxlr_dax->hpa_range.end = p->res->end; Loading @@ -3060,8 +3056,6 @@ static struct cxl_dax_region *cxl_dax_region_alloc(struct cxl_region *cxlr) dev->parent = &cxlr->dev; dev->bus = &cxl_bus_type; dev->type = &cxl_dax_region_type; out: up_read(&cxl_region_rwsem); return cxlr_dax; } Loading Loading @@ -3207,7 +3201,6 @@ static int match_region_by_range(struct device *dev, const void *data) struct cxl_region_params *p; struct cxl_region *cxlr; const struct range *r = data; int rc = 0; if (!is_cxl_region(dev)) return 0; Loading @@ -3215,61 +3208,38 @@ static int match_region_by_range(struct device *dev, const void *data) cxlr = to_cxl_region(dev); p = &cxlr->params; down_read(&cxl_region_rwsem); guard(rwsem_read)(&cxl_region_rwsem); if (p->res && p->res->start == r->start && p->res->end == r->end) rc = 1; up_read(&cxl_region_rwsem); return 1; return rc; return 0; } /* Establish an empty region covering the given HPA range */ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, static int __construct_region(struct cxl_region *cxlr, struct cxl_root_decoder *cxlrd, struct cxl_endpoint_decoder *cxled) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); struct cxl_port *port = cxlrd_to_port(cxlrd); struct cxl_dev_state *cxlds = cxlmd->cxlds; struct range *hpa = &cxled->cxld.hpa_range; int rc, part = READ_ONCE(cxled->part); struct cxl_region_params *p; struct cxl_region *cxlr; struct resource *res; int rc; if (part < 0) return ERR_PTR(-EBUSY); do { cxlr = __create_region(cxlrd, cxlds->part[part].mode, atomic_read(&cxlrd->region_id)); } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY); if (IS_ERR(cxlr)) { dev_err(cxlmd->dev.parent, "%s:%s: %s failed assign region: %ld\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__, PTR_ERR(cxlr)); return cxlr; } down_write(&cxl_region_rwsem); guard(rwsem_write)(&cxl_region_rwsem); p = &cxlr->params; if (p->state >= CXL_CONFIG_INTERLEAVE_ACTIVE) { dev_err(cxlmd->dev.parent, "%s:%s: %s autodiscovery interrupted\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__); rc = -EBUSY; goto err; return -EBUSY; } set_bit(CXL_REGION_F_AUTO, &cxlr->flags); res = kmalloc(sizeof(*res), GFP_KERNEL); if (!res) { rc = -ENOMEM; goto err; } if (!res) return -ENOMEM; *res = DEFINE_RES_MEM_NAMED(hpa->start, range_len(hpa), dev_name(&cxlr->dev)); Loading @@ -3292,7 +3262,7 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, rc = sysfs_update_group(&cxlr->dev.kobj, get_cxl_region_target_group()); if (rc) goto err; return rc; dev_dbg(cxlmd->dev.parent, "%s:%s: %s %s res: %pr iw: %d ig: %d\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__, Loading @@ -3301,16 +3271,42 @@ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, /* ...to match put_device() in cxl_add_to_region() */ get_device(&cxlr->dev); up_write(&cxl_region_rwsem); return 0; } /* Establish an empty region covering the given HPA range */ static struct cxl_region *construct_region(struct cxl_root_decoder *cxlrd, struct cxl_endpoint_decoder *cxled) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); struct cxl_port *port = cxlrd_to_port(cxlrd); struct cxl_dev_state *cxlds = cxlmd->cxlds; int rc, part = READ_ONCE(cxled->part); struct cxl_region *cxlr; do { cxlr = __create_region(cxlrd, cxlds->part[part].mode, atomic_read(&cxlrd->region_id)); } while (IS_ERR(cxlr) && PTR_ERR(cxlr) == -EBUSY); if (IS_ERR(cxlr)) { dev_err(cxlmd->dev.parent, "%s:%s: %s failed assign region: %ld\n", dev_name(&cxlmd->dev), dev_name(&cxled->cxld.dev), __func__, PTR_ERR(cxlr)); return cxlr; } err: up_write(&cxl_region_rwsem); rc = __construct_region(cxlr, cxlrd, cxled); if (rc) { devm_release_action(port->uport_dev, unregister_region, cxlr); return ERR_PTR(rc); } return cxlr; } int cxl_add_to_region(struct cxl_port *root, struct cxl_endpoint_decoder *cxled) { struct cxl_memdev *cxlmd = cxled_to_memdev(cxled); Loading