Skip to content

Commit be5cbd0

Browse files
djbwdavejiang
authored andcommitted
cxl: Kill enum cxl_decoder_mode
Now that the operational mode of DPA capacity (ram vs pmem... etc) is tracked in the partition, and no code paths have dependencies on the mode implying the partition index, the ambiguous 'enum cxl_decoder_mode' can be cleaned up, specifically this ambiguity on whether the operation mode implied anything about the partition order. Endpoint decoders simply reference their assigned partition where the operational mode can be retrieved as partition mode. With this in place PMEM can now be partition0 which happens today when the RAM capacity size is zero. Dynamic RAM can appear above PMEM when DCD arrives, etc. Code sequences that hard coded the "PMEM after RAM" assumption can now just iterate partitions and consult the partition mode after the fact. Reviewed-by: Ira Weiny <ira.weiny@intel.com> Reviewed-by: Alejandro Lucero <alucerop@amd.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Signed-off-by: Dan Williams <dan.j.williams@intel.com> Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Tested-by: Alejandro Lucero <alucerop@amd.com> Link: https://patch.msgid.link/173864306972.668823.3327008645125276726.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 991d98f commit be5cbd0

File tree

8 files changed

+134
-175
lines changed

8 files changed

+134
-175
lines changed

drivers/cxl/core/cdat.c

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -579,23 +579,15 @@ static bool dpa_perf_contains(struct cxl_dpa_perf *perf,
579579
return range_contains(&perf->dpa_range, &dpa);
580580
}
581581

582-
static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxled,
583-
enum cxl_decoder_mode mode)
582+
static struct cxl_dpa_perf *cxled_get_dpa_perf(struct cxl_endpoint_decoder *cxled)
584583
{
585584
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
586585
struct cxl_dev_state *cxlds = cxlmd->cxlds;
587586
struct cxl_dpa_perf *perf;
588587

589-
switch (mode) {
590-
case CXL_DECODER_RAM:
591-
perf = to_ram_perf(cxlds);
592-
break;
593-
case CXL_DECODER_PMEM:
594-
perf = to_pmem_perf(cxlds);
595-
break;
596-
default:
588+
if (cxled->part < 0)
597589
return ERR_PTR(-EINVAL);
598-
}
590+
perf = &cxlds->part[cxled->part].perf;
599591

600592
if (!perf)
601593
return ERR_PTR(-EINVAL);
@@ -659,7 +651,7 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr,
659651
if (cxlds->rcd)
660652
return -ENODEV;
661653

662-
perf = cxled_get_dpa_perf(cxled, cxlr->mode);
654+
perf = cxled_get_dpa_perf(cxled);
663655
if (IS_ERR(perf))
664656
return PTR_ERR(perf);
665657

@@ -1065,7 +1057,7 @@ void cxl_region_perf_data_calculate(struct cxl_region *cxlr,
10651057

10661058
lockdep_assert_held(&cxl_dpa_rwsem);
10671059

1068-
perf = cxled_get_dpa_perf(cxled, cxlr->mode);
1060+
perf = cxled_get_dpa_perf(cxled);
10691061
if (IS_ERR(perf))
10701062
return;
10711063

drivers/cxl/core/core.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr,
7272
resource_size_t length);
7373

7474
struct dentry *cxl_debugfs_create_dir(const char *dir);
75-
int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
76-
enum cxl_decoder_mode mode);
75+
int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
76+
enum cxl_partition_mode mode);
7777
int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size);
7878
int cxl_dpa_free(struct cxl_endpoint_decoder *cxled);
7979
resource_size_t cxl_dpa_size(struct cxl_endpoint_decoder *cxled);

drivers/cxl/core/hdm.c

Lines changed: 29 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,6 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
359359
struct cxl_port *port = cxled_to_port(cxled);
360360
struct cxl_dev_state *cxlds = cxlmd->cxlds;
361361
struct device *dev = &port->dev;
362-
enum cxl_decoder_mode mode;
363362
struct resource *res;
364363
int rc;
365364

@@ -406,17 +405,21 @@ static int __cxl_dpa_reserve(struct cxl_endpoint_decoder *cxled,
406405
cxled->dpa_res = res;
407406
cxled->skip = skipped;
408407

409-
mode = CXL_DECODER_NONE;
410-
for (int i = 0; cxlds->nr_partitions; i++)
411-
if (resource_contains(&cxlds->part[i].res, res)) {
412-
mode = cxl_part_mode(cxlds->part[i].mode);
413-
break;
414-
}
408+
/*
409+
* When allocating new capacity, ->part is already set, when
410+
* discovering decoder settings at initial enumeration, ->part
411+
* is not set.
412+
*/
413+
if (cxled->part < 0)
414+
for (int i = 0; cxlds->nr_partitions; i++)
415+
if (resource_contains(&cxlds->part[i].res, res)) {
416+
cxled->part = i;
417+
break;
418+
}
415419

416-
if (mode == CXL_DECODER_NONE)
420+
if (cxled->part < 0)
417421
dev_warn(dev, "decoder%d.%d: %pr does not map any partition\n",
418422
port->id, cxled->cxld.id, res);
419-
cxled->mode = mode;
420423

421424
port->hdm_end++;
422425
get_device(&cxled->cxld.dev);
@@ -583,40 +586,33 @@ int cxl_dpa_free(struct cxl_endpoint_decoder *cxled)
583586
return rc;
584587
}
585588

586-
int cxl_dpa_set_mode(struct cxl_endpoint_decoder *cxled,
587-
enum cxl_decoder_mode mode)
589+
int cxl_dpa_set_part(struct cxl_endpoint_decoder *cxled,
590+
enum cxl_partition_mode mode)
588591
{
589592
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
590593
struct cxl_dev_state *cxlds = cxlmd->cxlds;
591594
struct device *dev = &cxled->cxld.dev;
592-
593-
switch (mode) {
594-
case CXL_DECODER_RAM:
595-
case CXL_DECODER_PMEM:
596-
break;
597-
default:
598-
dev_dbg(dev, "unsupported mode: %d\n", mode);
599-
return -EINVAL;
600-
}
595+
int part;
601596

602597
guard(rwsem_write)(&cxl_dpa_rwsem);
603598
if (cxled->cxld.flags & CXL_DECODER_F_ENABLE)
604599
return -EBUSY;
605600

606-
/*
607-
* Only allow modes that are supported by the current partition
608-
* configuration
609-
*/
610-
if (mode == CXL_DECODER_PMEM && !cxl_pmem_size(cxlds)) {
611-
dev_dbg(dev, "no available pmem capacity\n");
612-
return -ENXIO;
601+
for (part = 0; part < cxlds->nr_partitions; part++)
602+
if (cxlds->part[part].mode == mode)
603+
break;
604+
605+
if (part >= cxlds->nr_partitions) {
606+
dev_dbg(dev, "unsupported mode: %d\n", mode);
607+
return -EINVAL;
613608
}
614-
if (mode == CXL_DECODER_RAM && !cxl_ram_size(cxlds)) {
615-
dev_dbg(dev, "no available ram capacity\n");
609+
610+
if (!resource_size(&cxlds->part[part].res)) {
611+
dev_dbg(dev, "no available capacity for mode: %d\n", mode);
616612
return -ENXIO;
617613
}
618614

619-
cxled->mode = mode;
615+
cxled->part = part;
620616
return 0;
621617
}
622618

@@ -645,15 +641,9 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
645641
goto out;
646642
}
647643

648-
part = -1;
649-
for (int i = 0; i < cxlds->nr_partitions; i++) {
650-
if (cxled->mode == cxl_part_mode(cxlds->part[i].mode)) {
651-
part = i;
652-
break;
653-
}
654-
}
655-
644+
part = cxled->part;
656645
if (part < 0) {
646+
dev_dbg(dev, "partition not set\n");
657647
rc = -EBUSY;
658648
goto out;
659649
}
@@ -694,7 +684,7 @@ int cxl_dpa_alloc(struct cxl_endpoint_decoder *cxled, unsigned long long size)
694684

695685
if (size > avail) {
696686
dev_dbg(dev, "%pa exceeds available %s capacity: %pa\n", &size,
697-
cxl_decoder_mode_name(cxled->mode), &avail);
687+
res->name, &avail);
698688
rc = -ENOSPC;
699689
goto out;
700690
}

drivers/cxl/core/memdev.c

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -198,17 +198,8 @@ static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
198198
int rc = 0;
199199

200200
/* CXL 3.0 Spec 8.2.9.8.4.1 Separate pmem and ram poison requests */
201-
if (cxl_pmem_size(cxlds)) {
202-
const struct resource *res = to_pmem_res(cxlds);
203-
204-
offset = res->start;
205-
length = resource_size(res);
206-
rc = cxl_mem_get_poison(cxlmd, offset, length, NULL);
207-
if (rc)
208-
return rc;
209-
}
210-
if (cxl_ram_size(cxlds)) {
211-
const struct resource *res = to_ram_res(cxlds);
201+
for (int i = 0; i < cxlds->nr_partitions; i++) {
202+
const struct resource *res = &cxlds->part[i].res;
212203

213204
offset = res->start;
214205
length = resource_size(res);
@@ -217,7 +208,7 @@ static int cxl_get_poison_by_memdev(struct cxl_memdev *cxlmd)
217208
* Invalid Physical Address is not an error for
218209
* volatile addresses. Device support is optional.
219210
*/
220-
if (rc == -EFAULT)
211+
if (rc == -EFAULT && cxlds->part[i].mode == CXL_PARTMODE_RAM)
221212
rc = 0;
222213
}
223214
return rc;

drivers/cxl/core/port.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -194,25 +194,35 @@ static ssize_t mode_show(struct device *dev, struct device_attribute *attr,
194194
char *buf)
195195
{
196196
struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
197+
struct cxl_memdev *cxlmd = cxled_to_memdev(cxled);
198+
struct cxl_dev_state *cxlds = cxlmd->cxlds;
199+
/* without @cxl_dpa_rwsem, make sure @part is not reloaded */
200+
int part = READ_ONCE(cxled->part);
201+
const char *desc;
202+
203+
if (part < 0)
204+
desc = "none";
205+
else
206+
desc = cxlds->part[part].res.name;
197207

198-
return sysfs_emit(buf, "%s\n", cxl_decoder_mode_name(cxled->mode));
208+
return sysfs_emit(buf, "%s\n", desc);
199209
}
200210

201211
static ssize_t mode_store(struct device *dev, struct device_attribute *attr,
202212
const char *buf, size_t len)
203213
{
204214
struct cxl_endpoint_decoder *cxled = to_cxl_endpoint_decoder(dev);
205-
enum cxl_decoder_mode mode;
215+
enum cxl_partition_mode mode;
206216
ssize_t rc;
207217

208218
if (sysfs_streq(buf, "pmem"))
209-
mode = CXL_DECODER_PMEM;
219+
mode = CXL_PARTMODE_PMEM;
210220
else if (sysfs_streq(buf, "ram"))
211-
mode = CXL_DECODER_RAM;
221+
mode = CXL_PARTMODE_RAM;
212222
else
213223
return -EINVAL;
214224

215-
rc = cxl_dpa_set_mode(cxled, mode);
225+
rc = cxl_dpa_set_part(cxled, mode);
216226
if (rc)
217227
return rc;
218228

@@ -1899,6 +1909,7 @@ struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port)
18991909
return ERR_PTR(-ENOMEM);
19001910

19011911
cxled->pos = -1;
1912+
cxled->part = -1;
19021913
cxld = &cxled->cxld;
19031914
rc = cxl_decoder_init(port, cxld);
19041915
if (rc) {

0 commit comments

Comments
 (0)