Skip to content

Commit 02edab6

Browse files
committed
cxl: Add a cached copy of target_map to cxl_decoder
Add a cached copy of the hardware port-id list that is available at init before all @DPORT objects have been instantiated. Change is in preparation of delayed dport instantiation. Reviewed-by: Robert Richter <rrichter@amd.com> Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com> Tested-by: Robert Richter <rrichter@amd.com> Reviewed-by: Alison Schofield <alison.schofield@intel.com> Signed-off-by: Dave Jiang <dave.jiang@intel.com>
1 parent 8330671 commit 02edab6

6 files changed

Lines changed: 31 additions & 38 deletions

File tree

drivers/cxl/acpi.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,6 @@ DEFINE_FREE(del_cxl_resource, struct resource *, if (_T) del_cxl_resource(_T))
398398
static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
399399
struct cxl_cfmws_context *ctx)
400400
{
401-
int target_map[CXL_DECODER_MAX_INTERLEAVE];
402401
struct cxl_port *root_port = ctx->root_port;
403402
struct cxl_cxims_context cxims_ctx;
404403
struct device *dev = ctx->dev;
@@ -416,8 +415,6 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
416415
rc = eig_to_granularity(cfmws->granularity, &ig);
417416
if (rc)
418417
return rc;
419-
for (i = 0; i < ways; i++)
420-
target_map[i] = cfmws->interleave_targets[i];
421418

422419
struct resource *res __free(del_cxl_resource) = alloc_cxl_resource(
423420
cfmws->base_hpa, cfmws->window_size, ctx->id++);
@@ -443,6 +440,8 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
443440
.end = cfmws->base_hpa + cfmws->window_size - 1,
444441
};
445442
cxld->interleave_ways = ways;
443+
for (i = 0; i < ways; i++)
444+
cxld->target_map[i] = cfmws->interleave_targets[i];
446445
/*
447446
* Minimize the x1 granularity to advertise support for any
448447
* valid region granularity
@@ -475,7 +474,7 @@ static int __cxl_parse_cfmws(struct acpi_cedt_cfmws *cfmws,
475474
if (cfmws->interleave_arithmetic == ACPI_CEDT_CFMWS_ARITHMETIC_XOR)
476475
cxlrd->hpa_to_spa = cxl_xor_hpa_to_spa;
477476

478-
rc = cxl_decoder_add(cxld, target_map);
477+
rc = cxl_decoder_add(cxld);
479478
if (rc)
480479
return rc;
481480

drivers/cxl/core/hdm.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,11 @@ struct cxl_rwsem cxl_rwsem = {
2121
.dpa = __RWSEM_INITIALIZER(cxl_rwsem.dpa),
2222
};
2323

24-
static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
25-
int *target_map)
24+
static int add_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld)
2625
{
2726
int rc;
2827

29-
rc = cxl_decoder_add_locked(cxld, target_map);
28+
rc = cxl_decoder_add_locked(cxld);
3029
if (rc) {
3130
put_device(&cxld->dev);
3231
dev_err(&port->dev, "Failed to add decoder\n");
@@ -54,7 +53,6 @@ int devm_cxl_add_passthrough_decoder(struct cxl_port *port)
5453
{
5554
struct cxl_switch_decoder *cxlsd;
5655
struct cxl_dport *dport = NULL;
57-
int single_port_map[1];
5856
unsigned long index;
5957
struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev);
6058

@@ -73,9 +71,9 @@ int devm_cxl_add_passthrough_decoder(struct cxl_port *port)
7371

7472
xa_for_each(&port->dports, index, dport)
7573
break;
76-
single_port_map[0] = dport->port_id;
74+
cxlsd->cxld.target_map[0] = dport->port_id;
7775

78-
return add_hdm_decoder(port, &cxlsd->cxld, single_port_map);
76+
return add_hdm_decoder(port, &cxlsd->cxld);
7977
}
8078
EXPORT_SYMBOL_NS_GPL(devm_cxl_add_passthrough_decoder, "CXL");
8179

@@ -984,7 +982,7 @@ static int cxl_setup_hdm_decoder_from_dvsec(
984982
}
985983

986984
static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
987-
int *target_map, void __iomem *hdm, int which,
985+
void __iomem *hdm, int which,
988986
u64 *dpa_base, struct cxl_endpoint_dvsec_info *info)
989987
{
990988
struct cxl_endpoint_decoder *cxled = NULL;
@@ -1103,7 +1101,7 @@ static int init_hdm_decoder(struct cxl_port *port, struct cxl_decoder *cxld,
11031101
hi = readl(hdm + CXL_HDM_DECODER0_TL_HIGH(which));
11041102
target_list.value = (hi << 32) + lo;
11051103
for (i = 0; i < cxld->interleave_ways; i++)
1106-
target_map[i] = target_list.target_id[i];
1104+
cxld->target_map[i] = target_list.target_id[i];
11071105

11081106
return 0;
11091107
}
@@ -1179,7 +1177,6 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
11791177
cxl_settle_decoders(cxlhdm);
11801178

11811179
for (i = 0; i < cxlhdm->decoder_count; i++) {
1182-
int target_map[CXL_DECODER_MAX_INTERLEAVE] = { 0 };
11831180
int rc, target_count = cxlhdm->target_count;
11841181
struct cxl_decoder *cxld;
11851182

@@ -1207,16 +1204,15 @@ int devm_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
12071204
cxld = &cxlsd->cxld;
12081205
}
12091206

1210-
rc = init_hdm_decoder(port, cxld, target_map, hdm, i,
1211-
&dpa_base, info);
1207+
rc = init_hdm_decoder(port, cxld, hdm, i, &dpa_base, info);
12121208
if (rc) {
12131209
dev_warn(&port->dev,
12141210
"Failed to initialize decoder%d.%d\n",
12151211
port->id, i);
12161212
put_device(&cxld->dev);
12171213
return rc;
12181214
}
1219-
rc = add_hdm_decoder(port, cxld, target_map);
1215+
rc = add_hdm_decoder(port, cxld);
12201216
if (rc) {
12211217
dev_warn(&port->dev,
12221218
"Failed to add decoder%d.%d\n", port->id, i);

drivers/cxl/core/port.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,21 +1715,19 @@ struct cxl_port *cxl_mem_find_port(struct cxl_memdev *cxlmd,
17151715
EXPORT_SYMBOL_NS_GPL(cxl_mem_find_port, "CXL");
17161716

17171717
static int decoder_populate_targets(struct cxl_switch_decoder *cxlsd,
1718-
struct cxl_port *port, int *target_map)
1718+
struct cxl_port *port)
17191719
{
1720+
struct cxl_decoder *cxld = &cxlsd->cxld;
17201721
int i;
17211722

1722-
if (!target_map)
1723-
return 0;
1724-
17251723
device_lock_assert(&port->dev);
17261724

17271725
if (xa_empty(&port->dports))
17281726
return -EINVAL;
17291727

17301728
guard(rwsem_write)(&cxl_rwsem.region);
17311729
for (i = 0; i < cxlsd->cxld.interleave_ways; i++) {
1732-
struct cxl_dport *dport = find_dport(port, target_map[i]);
1730+
struct cxl_dport *dport = find_dport(port, cxld->target_map[i]);
17331731

17341732
if (!dport)
17351733
return -ENXIO;
@@ -1921,9 +1919,6 @@ EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, "CXL");
19211919
/**
19221920
* cxl_decoder_add_locked - Add a decoder with targets
19231921
* @cxld: The cxl decoder allocated by cxl_<type>_decoder_alloc()
1924-
* @target_map: A list of downstream ports that this decoder can direct memory
1925-
* traffic to. These numbers should correspond with the port number
1926-
* in the PCIe Link Capabilities structure.
19271922
*
19281923
* Certain types of decoders may not have any targets. The main example of this
19291924
* is an endpoint device. A more awkward example is a hostbridge whose root
@@ -1937,7 +1932,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_endpoint_decoder_alloc, "CXL");
19371932
* Return: Negative error code if the decoder wasn't properly configured; else
19381933
* returns 0.
19391934
*/
1940-
int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map)
1935+
int cxl_decoder_add_locked(struct cxl_decoder *cxld)
19411936
{
19421937
struct cxl_port *port;
19431938
struct device *dev;
@@ -1958,7 +1953,7 @@ int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map)
19581953
if (!is_endpoint_decoder(dev)) {
19591954
struct cxl_switch_decoder *cxlsd = to_cxl_switch_decoder(dev);
19601955

1961-
rc = decoder_populate_targets(cxlsd, port, target_map);
1956+
rc = decoder_populate_targets(cxlsd, port);
19621957
if (rc && (cxld->flags & CXL_DECODER_F_ENABLE)) {
19631958
dev_err(&port->dev,
19641959
"Failed to populate active decoder targets\n");
@@ -1977,17 +1972,14 @@ EXPORT_SYMBOL_NS_GPL(cxl_decoder_add_locked, "CXL");
19771972
/**
19781973
* cxl_decoder_add - Add a decoder with targets
19791974
* @cxld: The cxl decoder allocated by cxl_<type>_decoder_alloc()
1980-
* @target_map: A list of downstream ports that this decoder can direct memory
1981-
* traffic to. These numbers should correspond with the port number
1982-
* in the PCIe Link Capabilities structure.
19831975
*
19841976
* This is the unlocked variant of cxl_decoder_add_locked().
19851977
* See cxl_decoder_add_locked().
19861978
*
19871979
* Context: Process context. Takes and releases the device lock of the port that
19881980
* owns the @cxld.
19891981
*/
1990-
int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map)
1982+
int cxl_decoder_add(struct cxl_decoder *cxld)
19911983
{
19921984
struct cxl_port *port;
19931985

@@ -2000,7 +1992,7 @@ int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map)
20001992
port = to_cxl_port(cxld->dev.parent);
20011993

20021994
guard(device)(&port->dev);
2003-
return cxl_decoder_add_locked(cxld, target_map);
1995+
return cxl_decoder_add_locked(cxld);
20041996
}
20051997
EXPORT_SYMBOL_NS_GPL(cxl_decoder_add, "CXL");
20061998

drivers/cxl/core/region.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1510,8 +1510,10 @@ static int cxl_port_setup_targets(struct cxl_port *port,
15101510
cxl_rr->nr_targets_set);
15111511
return -ENXIO;
15121512
}
1513-
} else
1513+
} else {
15141514
cxlsd->target[cxl_rr->nr_targets_set] = ep->dport;
1515+
cxlsd->cxld.target_map[cxl_rr->nr_targets_set] = ep->dport->port_id;
1516+
}
15151517
inc = 1;
15161518
out_target_set:
15171519
cxl_rr->nr_targets_set += inc;

drivers/cxl/cxl.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,9 @@ enum cxl_decoder_type {
357357
* @target_type: accelerator vs expander (type2 vs type3) selector
358358
* @region: currently assigned region for this decoder
359359
* @flags: memory type capabilities and locking
360+
* @target_map: cached copy of hardware port-id list, available at init
361+
* before all @dport objects have been instantiated. While
362+
* dport id is 8bit, CFMWS interleave targets are 32bits.
360363
* @commit: device/decoder-type specific callback to commit settings to hw
361364
* @reset: device/decoder-type specific callback to reset hw settings
362365
*/
@@ -369,6 +372,7 @@ struct cxl_decoder {
369372
enum cxl_decoder_type target_type;
370373
struct cxl_region *region;
371374
unsigned long flags;
375+
u32 target_map[CXL_DECODER_MAX_INTERLEAVE];
372376
int (*commit)(struct cxl_decoder *cxld);
373377
void (*reset)(struct cxl_decoder *cxld);
374378
};
@@ -781,9 +785,9 @@ struct cxl_root_decoder *cxl_root_decoder_alloc(struct cxl_port *port,
781785
unsigned int nr_targets);
782786
struct cxl_switch_decoder *cxl_switch_decoder_alloc(struct cxl_port *port,
783787
unsigned int nr_targets);
784-
int cxl_decoder_add(struct cxl_decoder *cxld, int *target_map);
788+
int cxl_decoder_add(struct cxl_decoder *cxld);
785789
struct cxl_endpoint_decoder *cxl_endpoint_decoder_alloc(struct cxl_port *port);
786-
int cxl_decoder_add_locked(struct cxl_decoder *cxld, int *target_map);
790+
int cxl_decoder_add_locked(struct cxl_decoder *cxld);
787791
int cxl_decoder_autoremove(struct device *host, struct cxl_decoder *cxld);
788792
static inline int cxl_root_decoder_autoremove(struct device *host,
789793
struct cxl_root_decoder *cxlrd)

tools/testing/cxl/test/cxl.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ static int mock_cxl_add_passthrough_decoder(struct cxl_port *port)
651651

652652

653653
struct target_map_ctx {
654-
int *target_map;
654+
u32 *target_map;
655655
int index;
656656
int target_count;
657657
};
@@ -863,9 +863,7 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
863863
target_count = NR_CXL_SWITCH_PORTS;
864864

865865
for (i = 0; i < NR_CXL_PORT_DECODERS; i++) {
866-
int target_map[CXL_DECODER_MAX_INTERLEAVE] = { 0 };
867866
struct target_map_ctx ctx = {
868-
.target_map = target_map,
869867
.target_count = target_count,
870868
};
871869
struct cxl_decoder *cxld;
@@ -894,6 +892,8 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
894892
cxld = &cxled->cxld;
895893
}
896894

895+
ctx.target_map = cxld->target_map;
896+
897897
mock_init_hdm_decoder(cxld);
898898

899899
if (target_count) {
@@ -905,7 +905,7 @@ static int mock_cxl_enumerate_decoders(struct cxl_hdm *cxlhdm,
905905
}
906906
}
907907

908-
rc = cxl_decoder_add_locked(cxld, target_map);
908+
rc = cxl_decoder_add_locked(cxld);
909909
if (rc) {
910910
put_device(&cxld->dev);
911911
dev_err(&port->dev, "Failed to add decoder\n");

0 commit comments

Comments
 (0)