Skip to content

Commit 00413c1

Browse files
davejiangdjbw
authored andcommitted
cxl: Change 'struct cxl_memdev_state' *_perf_list to single 'struct cxl_dpa_perf'
In order to address the issue with being able to expose qos_class sysfs attributes under 'ram' and 'pmem' sub-directories, the attributes must be defined as static attributes rather than under driver->dev_groups. To avoid implementing locking for accessing the 'struct cxl_dpa_perf` lists, convert the list to a single 'struct cxl_dpa_perf' entry in preparation to move the attributes to statically defined. While theoretically a partition may have multiple qos_class via CDAT, this has not been encountered with testing on available hardware. The code is simplified for now to not support the complex case until a use case is needed to support that. Link: https://lore.kernel.org/linux-cxl/65b200ba228f_2d43c29468@dwillia2-mobl3.amr.corp.intel.com.notmuch/ Suggested-by: Dan Williams <[email protected]> Signed-off-by: Dave Jiang <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Jonathan Cameron <[email protected]> Signed-off-by: Dan Williams <[email protected]>
1 parent cb66b1d commit 00413c1

File tree

4 files changed

+34
-90
lines changed

4 files changed

+34
-90
lines changed

drivers/cxl/core/cdat.c

Lines changed: 24 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -210,40 +210,19 @@ static int cxl_port_perf_data_calculate(struct cxl_port *port,
210210
return 0;
211211
}
212212

213-
static void add_perf_entry(struct device *dev, struct dsmas_entry *dent,
214-
struct list_head *list)
213+
static void update_perf_entry(struct device *dev, struct dsmas_entry *dent,
214+
struct cxl_dpa_perf *dpa_perf)
215215
{
216-
struct cxl_dpa_perf *dpa_perf;
217-
218-
dpa_perf = kzalloc(sizeof(*dpa_perf), GFP_KERNEL);
219-
if (!dpa_perf)
220-
return;
221-
222216
dpa_perf->dpa_range = dent->dpa_range;
223217
dpa_perf->coord = dent->coord;
224218
dpa_perf->qos_class = dent->qos_class;
225-
list_add_tail(&dpa_perf->list, list);
226219
dev_dbg(dev,
227220
"DSMAS: dpa: %#llx qos: %d read_bw: %d write_bw %d read_lat: %d write_lat: %d\n",
228221
dent->dpa_range.start, dpa_perf->qos_class,
229222
dent->coord.read_bandwidth, dent->coord.write_bandwidth,
230223
dent->coord.read_latency, dent->coord.write_latency);
231224
}
232225

233-
static void free_perf_ents(void *data)
234-
{
235-
struct cxl_memdev_state *mds = data;
236-
struct cxl_dpa_perf *dpa_perf, *n;
237-
LIST_HEAD(discard);
238-
239-
list_splice_tail_init(&mds->ram_perf_list, &discard);
240-
list_splice_tail_init(&mds->pmem_perf_list, &discard);
241-
list_for_each_entry_safe(dpa_perf, n, &discard, list) {
242-
list_del(&dpa_perf->list);
243-
kfree(dpa_perf);
244-
}
245-
}
246-
247226
static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
248227
struct xarray *dsmas_xa)
249228
{
@@ -263,16 +242,14 @@ static void cxl_memdev_set_qos_class(struct cxl_dev_state *cxlds,
263242
xa_for_each(dsmas_xa, index, dent) {
264243
if (resource_size(&cxlds->ram_res) &&
265244
range_contains(&ram_range, &dent->dpa_range))
266-
add_perf_entry(dev, dent, &mds->ram_perf_list);
245+
update_perf_entry(dev, dent, &mds->ram_perf);
267246
else if (resource_size(&cxlds->pmem_res) &&
268247
range_contains(&pmem_range, &dent->dpa_range))
269-
add_perf_entry(dev, dent, &mds->pmem_perf_list);
248+
update_perf_entry(dev, dent, &mds->pmem_perf);
270249
else
271250
dev_dbg(dev, "no partition for dsmas dpa: %#llx\n",
272251
dent->dpa_range.start);
273252
}
274-
275-
devm_add_action_or_reset(&cxlds->cxlmd->dev, free_perf_ents, mds);
276253
}
277254

278255
static int match_cxlrd_qos_class(struct device *dev, void *data)
@@ -293,24 +270,24 @@ static int match_cxlrd_qos_class(struct device *dev, void *data)
293270
return 0;
294271
}
295272

296-
static void cxl_qos_match(struct cxl_port *root_port,
297-
struct list_head *work_list,
298-
struct list_head *discard_list)
273+
static void reset_dpa_perf(struct cxl_dpa_perf *dpa_perf)
299274
{
300-
struct cxl_dpa_perf *dpa_perf, *n;
275+
*dpa_perf = (struct cxl_dpa_perf) {
276+
.qos_class = CXL_QOS_CLASS_INVALID,
277+
};
278+
}
301279

302-
list_for_each_entry_safe(dpa_perf, n, work_list, list) {
303-
int rc;
280+
static bool cxl_qos_match(struct cxl_port *root_port,
281+
struct cxl_dpa_perf *dpa_perf)
282+
{
283+
if (dpa_perf->qos_class == CXL_QOS_CLASS_INVALID)
284+
return false;
304285

305-
if (dpa_perf->qos_class == CXL_QOS_CLASS_INVALID)
306-
return;
286+
if (!device_for_each_child(&root_port->dev, &dpa_perf->qos_class,
287+
match_cxlrd_qos_class))
288+
return false;
307289

308-
rc = device_for_each_child(&root_port->dev,
309-
(void *)&dpa_perf->qos_class,
310-
match_cxlrd_qos_class);
311-
if (!rc)
312-
list_move_tail(&dpa_perf->list, discard_list);
313-
}
290+
return true;
314291
}
315292

316293
static int match_cxlrd_hb(struct device *dev, void *data)
@@ -334,23 +311,10 @@ static int match_cxlrd_hb(struct device *dev, void *data)
334311
return 0;
335312
}
336313

337-
static void discard_dpa_perf(struct list_head *list)
338-
{
339-
struct cxl_dpa_perf *dpa_perf, *n;
340-
341-
list_for_each_entry_safe(dpa_perf, n, list, list) {
342-
list_del(&dpa_perf->list);
343-
kfree(dpa_perf);
344-
}
345-
}
346-
DEFINE_FREE(dpa_perf, struct list_head *, if (!list_empty(_T)) discard_dpa_perf(_T))
347-
348314
static int cxl_qos_class_verify(struct cxl_memdev *cxlmd)
349315
{
350316
struct cxl_dev_state *cxlds = cxlmd->cxlds;
351317
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
352-
LIST_HEAD(__discard);
353-
struct list_head *discard __free(dpa_perf) = &__discard;
354318
struct cxl_port *root_port;
355319
int rc;
356320

@@ -363,16 +327,18 @@ static int cxl_qos_class_verify(struct cxl_memdev *cxlmd)
363327
root_port = &cxl_root->port;
364328

365329
/* Check that the QTG IDs are all sane between end device and root decoders */
366-
cxl_qos_match(root_port, &mds->ram_perf_list, discard);
367-
cxl_qos_match(root_port, &mds->pmem_perf_list, discard);
330+
if (!cxl_qos_match(root_port, &mds->ram_perf))
331+
reset_dpa_perf(&mds->ram_perf);
332+
if (!cxl_qos_match(root_port, &mds->pmem_perf))
333+
reset_dpa_perf(&mds->pmem_perf);
368334

369335
/* Check to make sure that the device's host bridge is under a root decoder */
370336
rc = device_for_each_child(&root_port->dev,
371337
(void *)cxlmd->endpoint->host_bridge,
372338
match_cxlrd_hb);
373339
if (!rc) {
374-
list_splice_tail_init(&mds->ram_perf_list, discard);
375-
list_splice_tail_init(&mds->pmem_perf_list, discard);
340+
reset_dpa_perf(&mds->ram_perf);
341+
reset_dpa_perf(&mds->pmem_perf);
376342
}
377343

378344
return rc;

drivers/cxl/core/mbox.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,8 +1391,8 @@ struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev)
13911391
mds->cxlds.reg_map.host = dev;
13921392
mds->cxlds.reg_map.resource = CXL_RESOURCE_NONE;
13931393
mds->cxlds.type = CXL_DEVTYPE_CLASSMEM;
1394-
INIT_LIST_HEAD(&mds->ram_perf_list);
1395-
INIT_LIST_HEAD(&mds->pmem_perf_list);
1394+
mds->ram_perf.qos_class = CXL_QOS_CLASS_INVALID;
1395+
mds->pmem_perf.qos_class = CXL_QOS_CLASS_INVALID;
13961396

13971397
return mds;
13981398
}

drivers/cxl/cxlmem.h

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -395,13 +395,11 @@ enum cxl_devtype {
395395

396396
/**
397397
* struct cxl_dpa_perf - DPA performance property entry
398-
* @list - list entry
399398
* @dpa_range - range for DPA address
400399
* @coord - QoS performance data (i.e. latency, bandwidth)
401400
* @qos_class - QoS Class cookies
402401
*/
403402
struct cxl_dpa_perf {
404-
struct list_head list;
405403
struct range dpa_range;
406404
struct access_coordinate coord;
407405
int qos_class;
@@ -471,8 +469,8 @@ struct cxl_dev_state {
471469
* @security: security driver state info
472470
* @fw: firmware upload / activation state
473471
* @mbox_send: @dev specific transport for transmitting mailbox commands
474-
* @ram_perf_list: performance data entries matched to RAM
475-
* @pmem_perf_list: performance data entries matched to PMEM
472+
* @ram_perf: performance data entry matched to RAM partition
473+
* @pmem_perf: performance data entry matched to PMEM partition
476474
*
477475
* See CXL 3.0 8.2.9.8.2 Capacity Configuration and Label Storage for
478476
* details on capacity parameters.
@@ -494,8 +492,8 @@ struct cxl_memdev_state {
494492
u64 next_volatile_bytes;
495493
u64 next_persistent_bytes;
496494

497-
struct list_head ram_perf_list;
498-
struct list_head pmem_perf_list;
495+
struct cxl_dpa_perf ram_perf;
496+
struct cxl_dpa_perf pmem_perf;
499497

500498
struct cxl_event_state event;
501499
struct cxl_poison_state poison;

drivers/cxl/mem.c

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -221,18 +221,8 @@ static ssize_t ram_qos_class_show(struct device *dev,
221221
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
222222
struct cxl_dev_state *cxlds = cxlmd->cxlds;
223223
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
224-
struct cxl_dpa_perf *dpa_perf;
225224

226-
if (!dev->driver)
227-
return -ENOENT;
228-
229-
if (list_empty(&mds->ram_perf_list))
230-
return -ENOENT;
231-
232-
dpa_perf = list_first_entry(&mds->ram_perf_list, struct cxl_dpa_perf,
233-
list);
234-
235-
return sysfs_emit(buf, "%d\n", dpa_perf->qos_class);
225+
return sysfs_emit(buf, "%d\n", mds->ram_perf.qos_class);
236226
}
237227

238228
static struct device_attribute dev_attr_ram_qos_class =
@@ -244,18 +234,8 @@ static ssize_t pmem_qos_class_show(struct device *dev,
244234
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
245235
struct cxl_dev_state *cxlds = cxlmd->cxlds;
246236
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
247-
struct cxl_dpa_perf *dpa_perf;
248-
249-
if (!dev->driver)
250-
return -ENOENT;
251-
252-
if (list_empty(&mds->pmem_perf_list))
253-
return -ENOENT;
254-
255-
dpa_perf = list_first_entry(&mds->pmem_perf_list, struct cxl_dpa_perf,
256-
list);
257237

258-
return sysfs_emit(buf, "%d\n", dpa_perf->qos_class);
238+
return sysfs_emit(buf, "%d\n", mds->pmem_perf.qos_class);
259239
}
260240

261241
static struct device_attribute dev_attr_pmem_qos_class =
@@ -273,11 +253,11 @@ static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
273253
return 0;
274254

275255
if (a == &dev_attr_pmem_qos_class.attr)
276-
if (list_empty(&mds->pmem_perf_list))
256+
if (mds->pmem_perf.qos_class == CXL_QOS_CLASS_INVALID)
277257
return 0;
278258

279259
if (a == &dev_attr_ram_qos_class.attr)
280-
if (list_empty(&mds->ram_perf_list))
260+
if (mds->ram_perf.qos_class == CXL_QOS_CLASS_INVALID)
281261
return 0;
282262

283263
return a->mode;

0 commit comments

Comments
 (0)