Skip to content

Commit 59f8d15

Browse files
committed
cxl/mbox: Move mailbox related driver state to its own data structure
'struct cxl_dev_state' makes too many assumptions about the capabilities of a CXL device. In particular it assumes a CXL device has a mailbox and all of the infrastructure and state that comes along with that. In preparation for supporting accelerator / Type-2 devices that may not have a mailbox and in general maintain a minimal core context structure, make mailbox functionality a super-set of 'struct cxl_dev_state' with 'struct cxl_memdev_state'. With this reorganization it allows for CXL devices that support HDM decoder mapping, but not other general-expander / Type-3 capabilities, to only enable that subset without the rest of the mailbox infrastructure coming along for the ride. Reviewed-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Reviewed-by: Dave Jiang <dave.jiang@intel.com> Link: https://lore.kernel.org/r/168679260240.3436160.15520641540463704524.stgit@dwillia2-xfh.jf.intel.com Signed-off-by: Dan Williams <dan.j.williams@intel.com>
1 parent 3fe7feb commit 59f8d15

8 files changed

Lines changed: 336 additions & 290 deletions

File tree

drivers/cxl/core/mbox.c

Lines changed: 141 additions & 134 deletions
Large diffs are not rendered by default.

drivers/cxl/core/memdev.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,9 @@ static ssize_t firmware_version_show(struct device *dev,
3939
{
4040
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
4141
struct cxl_dev_state *cxlds = cxlmd->cxlds;
42+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
4243

43-
return sysfs_emit(buf, "%.16s\n", cxlds->firmware_version);
44+
return sysfs_emit(buf, "%.16s\n", mds->firmware_version);
4445
}
4546
static DEVICE_ATTR_RO(firmware_version);
4647

@@ -49,8 +50,9 @@ static ssize_t payload_max_show(struct device *dev,
4950
{
5051
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
5152
struct cxl_dev_state *cxlds = cxlmd->cxlds;
53+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
5254

53-
return sysfs_emit(buf, "%zu\n", cxlds->payload_size);
55+
return sysfs_emit(buf, "%zu\n", mds->payload_size);
5456
}
5557
static DEVICE_ATTR_RO(payload_max);
5658

@@ -59,8 +61,9 @@ static ssize_t label_storage_size_show(struct device *dev,
5961
{
6062
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
6163
struct cxl_dev_state *cxlds = cxlmd->cxlds;
64+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlds);
6265

63-
return sysfs_emit(buf, "%zu\n", cxlds->lsa_size);
66+
return sysfs_emit(buf, "%zu\n", mds->lsa_size);
6467
}
6568
static DEVICE_ATTR_RO(label_storage_size);
6669

@@ -231,7 +234,7 @@ static int cxl_validate_poison_dpa(struct cxl_memdev *cxlmd, u64 dpa)
231234

232235
int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
233236
{
234-
struct cxl_dev_state *cxlds = cxlmd->cxlds;
237+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
235238
struct cxl_mbox_inject_poison inject;
236239
struct cxl_poison_record record;
237240
struct cxl_mbox_cmd mbox_cmd;
@@ -255,13 +258,13 @@ int cxl_inject_poison(struct cxl_memdev *cxlmd, u64 dpa)
255258
.size_in = sizeof(inject),
256259
.payload_in = &inject,
257260
};
258-
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
261+
rc = cxl_internal_send_cmd(mds, &mbox_cmd);
259262
if (rc)
260263
goto out;
261264

262265
cxlr = cxl_dpa_to_region(cxlmd, dpa);
263266
if (cxlr)
264-
dev_warn_once(cxlds->dev,
267+
dev_warn_once(mds->cxlds.dev,
265268
"poison inject dpa:%#llx region: %s\n", dpa,
266269
dev_name(&cxlr->dev));
267270

@@ -279,7 +282,7 @@ EXPORT_SYMBOL_NS_GPL(cxl_inject_poison, CXL);
279282

280283
int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
281284
{
282-
struct cxl_dev_state *cxlds = cxlmd->cxlds;
285+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
283286
struct cxl_mbox_clear_poison clear;
284287
struct cxl_poison_record record;
285288
struct cxl_mbox_cmd mbox_cmd;
@@ -312,14 +315,15 @@ int cxl_clear_poison(struct cxl_memdev *cxlmd, u64 dpa)
312315
.payload_in = &clear,
313316
};
314317

315-
rc = cxl_internal_send_cmd(cxlds, &mbox_cmd);
318+
rc = cxl_internal_send_cmd(mds, &mbox_cmd);
316319
if (rc)
317320
goto out;
318321

319322
cxlr = cxl_dpa_to_region(cxlmd, dpa);
320323
if (cxlr)
321-
dev_warn_once(cxlds->dev, "poison clear dpa:%#llx region: %s\n",
322-
dpa, dev_name(&cxlr->dev));
324+
dev_warn_once(mds->cxlds.dev,
325+
"poison clear dpa:%#llx region: %s\n", dpa,
326+
dev_name(&cxlr->dev));
323327

324328
record = (struct cxl_poison_record) {
325329
.address = cpu_to_le64(dpa),
@@ -397,31 +401,33 @@ EXPORT_SYMBOL_NS_GPL(is_cxl_memdev, CXL);
397401

398402
/**
399403
* set_exclusive_cxl_commands() - atomically disable user cxl commands
400-
* @cxlds: The device state to operate on
404+
* @mds: The device state to operate on
401405
* @cmds: bitmap of commands to mark exclusive
402406
*
403407
* Grab the cxl_memdev_rwsem in write mode to flush in-flight
404408
* invocations of the ioctl path and then disable future execution of
405409
* commands with the command ids set in @cmds.
406410
*/
407-
void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds)
411+
void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,
412+
unsigned long *cmds)
408413
{
409414
down_write(&cxl_memdev_rwsem);
410-
bitmap_or(cxlds->exclusive_cmds, cxlds->exclusive_cmds, cmds,
415+
bitmap_or(mds->exclusive_cmds, mds->exclusive_cmds, cmds,
411416
CXL_MEM_COMMAND_ID_MAX);
412417
up_write(&cxl_memdev_rwsem);
413418
}
414419
EXPORT_SYMBOL_NS_GPL(set_exclusive_cxl_commands, CXL);
415420

416421
/**
417422
* clear_exclusive_cxl_commands() - atomically enable user cxl commands
418-
* @cxlds: The device state to modify
423+
* @mds: The device state to modify
419424
* @cmds: bitmap of commands to mark available for userspace
420425
*/
421-
void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds)
426+
void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,
427+
unsigned long *cmds)
422428
{
423429
down_write(&cxl_memdev_rwsem);
424-
bitmap_andnot(cxlds->exclusive_cmds, cxlds->exclusive_cmds, cmds,
430+
bitmap_andnot(mds->exclusive_cmds, mds->exclusive_cmds, cmds,
425431
CXL_MEM_COMMAND_ID_MAX);
426432
up_write(&cxl_memdev_rwsem);
427433
}

drivers/cxl/cxlmem.h

Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,34 @@ struct cxl_poison_state {
267267
* @cxl_dvsec: Offset to the PCIe device DVSEC
268268
* @rcd: operating in RCD mode (CXL 3.0 9.11.8 CXL Devices Attached to an RCH)
269269
* @media_ready: Indicate whether the device media is usable
270+
* @dpa_res: Overall DPA resource tree for the device
271+
* @pmem_res: Active Persistent memory capacity configuration
272+
* @ram_res: Active Volatile memory capacity configuration
273+
* @component_reg_phys: register base of component registers
274+
* @serial: PCIe Device Serial Number
275+
*/
276+
struct cxl_dev_state {
277+
struct device *dev;
278+
struct cxl_memdev *cxlmd;
279+
struct cxl_regs regs;
280+
int cxl_dvsec;
281+
bool rcd;
282+
bool media_ready;
283+
struct resource dpa_res;
284+
struct resource pmem_res;
285+
struct resource ram_res;
286+
resource_size_t component_reg_phys;
287+
u64 serial;
288+
};
289+
290+
/**
291+
* struct cxl_memdev_state - Generic Type-3 Memory Device Class driver data
292+
*
293+
* CXL 8.1.12.1 PCI Header - Class Code Register Memory Device defines
294+
* common memory device functionality like the presence of a mailbox and
295+
* the functionality related to that like Identify Memory Device and Get
296+
* Partition Info
297+
* @cxlds: Core driver state common across Type-2 and Type-3 devices
270298
* @payload_size: Size of space for payload
271299
* (CXL 2.0 8.2.8.4.3 Mailbox Capabilities Register)
272300
* @lsa_size: Size of Label Storage Area
@@ -275,9 +303,6 @@ struct cxl_poison_state {
275303
* @firmware_version: Firmware version for the memory device.
276304
* @enabled_cmds: Hardware commands found enabled in CEL.
277305
* @exclusive_cmds: Commands that are kernel-internal only
278-
* @dpa_res: Overall DPA resource tree for the device
279-
* @pmem_res: Active Persistent memory capacity configuration
280-
* @ram_res: Active Volatile memory capacity configuration
281306
* @total_bytes: sum of all possible capacities
282307
* @volatile_only_bytes: hard volatile capacity
283308
* @persistent_only_bytes: hard persistent capacity
@@ -286,53 +311,41 @@ struct cxl_poison_state {
286311
* @active_persistent_bytes: sum of hard + soft persistent
287312
* @next_volatile_bytes: volatile capacity change pending device reset
288313
* @next_persistent_bytes: persistent capacity change pending device reset
289-
* @component_reg_phys: register base of component registers
290-
* @serial: PCIe Device Serial Number
291314
* @event: event log driver state
292315
* @poison: poison driver state info
293316
* @mbox_send: @dev specific transport for transmitting mailbox commands
294317
*
295-
* See section 8.2.9.5.2 Capacity Configuration and Label Storage for
318+
* See CXL 3.0 8.2.9.8.2 Capacity Configuration and Label Storage for
296319
* details on capacity parameters.
297320
*/
298-
struct cxl_dev_state {
299-
struct device *dev;
300-
struct cxl_memdev *cxlmd;
301-
302-
struct cxl_regs regs;
303-
int cxl_dvsec;
304-
305-
bool rcd;
306-
bool media_ready;
321+
struct cxl_memdev_state {
322+
struct cxl_dev_state cxlds;
307323
size_t payload_size;
308324
size_t lsa_size;
309325
struct mutex mbox_mutex; /* Protects device mailbox and firmware */
310326
char firmware_version[0x10];
311327
DECLARE_BITMAP(enabled_cmds, CXL_MEM_COMMAND_ID_MAX);
312328
DECLARE_BITMAP(exclusive_cmds, CXL_MEM_COMMAND_ID_MAX);
313-
314-
struct resource dpa_res;
315-
struct resource pmem_res;
316-
struct resource ram_res;
317329
u64 total_bytes;
318330
u64 volatile_only_bytes;
319331
u64 persistent_only_bytes;
320332
u64 partition_align_bytes;
321-
322333
u64 active_volatile_bytes;
323334
u64 active_persistent_bytes;
324335
u64 next_volatile_bytes;
325336
u64 next_persistent_bytes;
326-
327-
resource_size_t component_reg_phys;
328-
u64 serial;
329-
330337
struct cxl_event_state event;
331338
struct cxl_poison_state poison;
332-
333-
int (*mbox_send)(struct cxl_dev_state *cxlds, struct cxl_mbox_cmd *cmd);
339+
int (*mbox_send)(struct cxl_memdev_state *mds,
340+
struct cxl_mbox_cmd *cmd);
334341
};
335342

343+
static inline struct cxl_memdev_state *
344+
to_cxl_memdev_state(struct cxl_dev_state *cxlds)
345+
{
346+
return container_of(cxlds, struct cxl_memdev_state, cxlds);
347+
}
348+
336349
enum cxl_opcode {
337350
CXL_MBOX_OP_INVALID = 0x0000,
338351
CXL_MBOX_OP_RAW = CXL_MBOX_OP_INVALID,
@@ -691,18 +704,20 @@ enum {
691704
CXL_PMEM_SEC_PASS_USER,
692705
};
693706

694-
int cxl_internal_send_cmd(struct cxl_dev_state *cxlds,
707+
int cxl_internal_send_cmd(struct cxl_memdev_state *mds,
695708
struct cxl_mbox_cmd *cmd);
696-
int cxl_dev_state_identify(struct cxl_dev_state *cxlds);
709+
int cxl_dev_state_identify(struct cxl_memdev_state *mds);
697710
int cxl_await_media_ready(struct cxl_dev_state *cxlds);
698-
int cxl_enumerate_cmds(struct cxl_dev_state *cxlds);
699-
int cxl_mem_create_range_info(struct cxl_dev_state *cxlds);
700-
struct cxl_dev_state *cxl_dev_state_create(struct device *dev);
701-
void set_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds);
702-
void clear_exclusive_cxl_commands(struct cxl_dev_state *cxlds, unsigned long *cmds);
703-
void cxl_mem_get_event_records(struct cxl_dev_state *cxlds, u32 status);
704-
int cxl_set_timestamp(struct cxl_dev_state *cxlds);
705-
int cxl_poison_state_init(struct cxl_dev_state *cxlds);
711+
int cxl_enumerate_cmds(struct cxl_memdev_state *mds);
712+
int cxl_mem_create_range_info(struct cxl_memdev_state *mds);
713+
struct cxl_memdev_state *cxl_memdev_state_create(struct device *dev);
714+
void set_exclusive_cxl_commands(struct cxl_memdev_state *mds,
715+
unsigned long *cmds);
716+
void clear_exclusive_cxl_commands(struct cxl_memdev_state *mds,
717+
unsigned long *cmds);
718+
void cxl_mem_get_event_records(struct cxl_memdev_state *mds, u32 status);
719+
int cxl_set_timestamp(struct cxl_memdev_state *mds);
720+
int cxl_poison_state_init(struct cxl_memdev_state *mds);
706721
int cxl_mem_get_poison(struct cxl_memdev *cxlmd, u64 offset, u64 len,
707722
struct cxl_region *cxlr);
708723
int cxl_trigger_poison_list(struct cxl_memdev *cxlmd);

drivers/cxl/mem.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(cxl_poison_clear_fops, NULL,
117117
static int cxl_mem_probe(struct device *dev)
118118
{
119119
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
120+
struct cxl_memdev_state *mds = to_cxl_memdev_state(cxlmd->cxlds);
120121
struct cxl_dev_state *cxlds = cxlmd->cxlds;
121122
struct device *endpoint_parent;
122123
struct cxl_port *parent_port;
@@ -141,10 +142,10 @@ static int cxl_mem_probe(struct device *dev)
141142
dentry = cxl_debugfs_create_dir(dev_name(dev));
142143
debugfs_create_devm_seqfile(dev, "dpamem", dentry, cxl_mem_dpa_show);
143144

144-
if (test_bit(CXL_POISON_ENABLED_INJECT, cxlds->poison.enabled_cmds))
145+
if (test_bit(CXL_POISON_ENABLED_INJECT, mds->poison.enabled_cmds))
145146
debugfs_create_file("inject_poison", 0200, dentry, cxlmd,
146147
&cxl_poison_inject_fops);
147-
if (test_bit(CXL_POISON_ENABLED_CLEAR, cxlds->poison.enabled_cmds))
148+
if (test_bit(CXL_POISON_ENABLED_CLEAR, mds->poison.enabled_cmds))
148149
debugfs_create_file("clear_poison", 0200, dentry, cxlmd,
149150
&cxl_poison_clear_fops);
150151

@@ -227,9 +228,12 @@ static umode_t cxl_mem_visible(struct kobject *kobj, struct attribute *a, int n)
227228
{
228229
if (a == &dev_attr_trigger_poison_list.attr) {
229230
struct device *dev = kobj_to_dev(kobj);
231+
struct cxl_memdev *cxlmd = to_cxl_memdev(dev);
232+
struct cxl_memdev_state *mds =
233+
to_cxl_memdev_state(cxlmd->cxlds);
230234

231235
if (!test_bit(CXL_POISON_ENABLED_LIST,
232-
to_cxl_memdev(dev)->cxlds->poison.enabled_cmds))
236+
mds->poison.enabled_cmds))
233237
return 0;
234238
}
235239
return a->mode;

0 commit comments

Comments
 (0)