Skip to content

Commit abfd613

Browse files
xiongzubiaobgoglin
authored andcommitted
linux: add more MemoryModule info attributes
FormFactor=DIMM, Type=DDR4, Size=<KiB> (with support for more than 32GB DIMMs), Rank=2 Uses SMBIOS 2.6 when available. Signed-off-by: Zubiao Xiong <[email protected]> Signed-off-by: Brice Goglin <[email protected]>
1 parent ec50746 commit abfd613

File tree

3 files changed

+156
-1
lines changed

3 files changed

+156
-1
lines changed

doc/hwloc.doxy

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2291,9 +2291,10 @@ The Solaris kstat processor group name that was used to build this Group object.
22912291
the attribute may be attached to the highest bridge
22922292
(i.e. the first object that actually appears below the physical slot).
22932293
</dd>
2294-
<dt>Vendor, AssetTag, PartNumber, DeviceLocation, BankLocation (MemoryModule Misc objects)</dt>
2294+
<dt>Vendor, AssetTag, PartNumber, DeviceLocation, BankLocation, FormFactor, Type, Size, Rank (MemoryModule Misc objects)</dt>
22952295
<dd>
22962296
Information about memory modules (DIMMs) extracted from SMBIOS.
2297+
Size is in KiB.
22972298
</dd>
22982299
</dl>
22992300

hwloc/topology-linux.c

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6904,6 +6904,8 @@ struct hwloc_firmware_dmi_mem_device_header {
69046904
* Anything below (SMBIOS 2.6+) is optional for hwloc,
69056905
* we must to check header->length before reading them.
69066906
*/
6907+
unsigned char attributes;
6908+
unsigned char extended_size[4];
69076909
};
69086910

69096911
static int check_dmi_entry(const char *buffer)
@@ -6917,13 +6919,122 @@ static int check_dmi_entry(const char *buffer)
69176919
return 1;
69186920
}
69196921

6922+
static const char *dmi_memory_device_form_factor(uint8_t code)
6923+
{
6924+
static const char *form_factor[] = {
6925+
"Other", /* 0x01 */
6926+
"Unknown",
6927+
"SIMM",
6928+
"SIP",
6929+
"Chip",
6930+
"DIP",
6931+
"ZIP",
6932+
"Proprietary Card",
6933+
"DIMM",
6934+
"TSOP",
6935+
"Row Of Chips",
6936+
"RIMM",
6937+
"SODIMM",
6938+
"SRIMM",
6939+
"FB-DIMM",
6940+
"Die", /* 0x10 */
6941+
/* updated for SMBIOS 3.7.0 20230721 */
6942+
};
6943+
6944+
if (code >= 1 && code <= sizeof(form_factor)/sizeof(form_factor[0]))
6945+
return form_factor[code - 1];
6946+
return NULL; /* return NULL to distinguish unsupported values from the official "Unknown" value above */
6947+
}
6948+
6949+
static const char *dmi_memory_device_type(uint8_t code)
6950+
{
6951+
static const char *type[] = {
6952+
"Other", /* 0x01 */
6953+
"Unknown",
6954+
"DRAM",
6955+
"EDRAM",
6956+
"VRAM",
6957+
"SRAM",
6958+
"RAM",
6959+
"ROM",
6960+
"Flash",
6961+
"EEPROM",
6962+
"FEPROM",
6963+
"EPROM",
6964+
"CDRAM",
6965+
"3DRAM",
6966+
"SDRAM",
6967+
"SGRAM",
6968+
"RDRAM",
6969+
"DDR",
6970+
"DDR2",
6971+
"DDR2 FB-DIMM",
6972+
"Reserved",
6973+
"Reserved",
6974+
"Reserved",
6975+
"DDR3",
6976+
"FBD2",
6977+
"DDR4",
6978+
"LPDDR",
6979+
"LPDDR2",
6980+
"LPDDR3",
6981+
"LPDDR4",
6982+
"Logical non-volatile device",
6983+
"HBM",
6984+
"HBM2",
6985+
"DDR5",
6986+
"LPDDR5",
6987+
"HBM3" /* 0x24 */
6988+
/* updated for SMBIOS 3.7.0 20230721 */
6989+
};
6990+
6991+
if (code >= 1 && code <= sizeof(type)/sizeof(type[0]))
6992+
return type[code - 1];
6993+
return NULL; /* return NULL to distinguish unsupported values from the official "Unknown" value above */
6994+
}
6995+
6996+
static int dmi_memory_device_size(char *buffer, size_t len,
6997+
const struct hwloc_firmware_dmi_mem_device_header *header)
6998+
{
6999+
uint64_t memory_size = 0;
7000+
uint16_t code = *(uint16_t *)(header->size);
7001+
7002+
if (code == 0xFFFF)
7003+
return -1;
7004+
7005+
if (header->length >= offsetof(struct hwloc_firmware_dmi_mem_device_header, extended_size) + sizeof(header->extended_size) && code == 0x7FFF) {
7006+
memory_size = *(uint32_t *)(header->extended_size) & 0x7FFFFFFF; /* MiB */
7007+
memory_size <<= 10;
7008+
} else {
7009+
memory_size = code & 0x7FFF;
7010+
if (!(code & 0x8000)) /* MiB (otherwise KiB) */
7011+
memory_size <<= 10;
7012+
}
7013+
snprintf(buffer, len, "%llu", (unsigned long long) memory_size);
7014+
return 0;
7015+
}
7016+
7017+
static int dmi_memory_device_rank(char *buffer, size_t len,
7018+
const struct hwloc_firmware_dmi_mem_device_header *header)
7019+
{
7020+
uint8_t code;
7021+
if (header->length < offsetof(struct hwloc_firmware_dmi_mem_device_header, attributes) + sizeof(header->attributes))
7022+
return -1;
7023+
code = header->attributes;
7024+
if (!code)
7025+
return -1;
7026+
snprintf(buffer, len, "%u", code & 0x0F);
7027+
return 0;
7028+
}
7029+
69207030
static int
69217031
hwloc__get_firmware_dmi_memory_info_one(struct hwloc_topology *topology,
69227032
unsigned idx, const char *path, FILE *fd,
69237033
struct hwloc_firmware_dmi_mem_device_header *header)
69247034
{
69257035
unsigned slen;
69267036
char buffer[256]; /* enough for memory device strings, or at least for each of them */
7037+
const char *retbuf;
69277038
unsigned foff; /* offset in raw file */
69287039
unsigned boff; /* offset in buffer read from raw file */
69297040
unsigned i;
@@ -7009,6 +7120,17 @@ hwloc__get_firmware_dmi_memory_info_one(struct hwloc_topology *topology,
70097120
goto out_with_infos;
70107121
}
70117122

7123+
retbuf = dmi_memory_device_form_factor(header->ff);
7124+
if (retbuf)
7125+
hwloc__add_info(&infos, "FormFactor", retbuf);
7126+
retbuf = dmi_memory_device_type(header->mem_type);
7127+
if (retbuf)
7128+
hwloc__add_info(&infos, "Type", retbuf);
7129+
if (!dmi_memory_device_size(buffer, sizeof(buffer), header))
7130+
hwloc__add_info(&infos, "Size", buffer);
7131+
if (!dmi_memory_device_rank(buffer, sizeof(buffer), header))
7132+
hwloc__add_info(&infos, "Rank", buffer);
7133+
70127134
misc = hwloc_alloc_setup_object(topology, HWLOC_OBJ_MISC, idx);
70137135
if (!misc)
70147136
goto out_with_infos;

tests/hwloc/linux/32em64t-2n8c+dax+nvme+mic+dimms.xml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,55 +446,87 @@
446446
<info name="SerialNumber" value="48AAE639"/>
447447
<info name="AssetTag" value="01115021"/>
448448
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
449+
<info name="FormFactor" value="DIMM"/>
450+
<info name="Type" value="DDR3"/>
451+
<info name="Size" value="4194304"/>
452+
<info name="Rank" value="2"/>
449453
</object>
450454
<object type="Misc" os_index="1" subtype="MemoryModule">
451455
<info name="DeviceLocation" value="DIMM_A2 "/>
452456
<info name="Vendor" value="00AD04B300AD"/>
453457
<info name="SerialNumber" value="486AE620"/>
454458
<info name="AssetTag" value="01115021"/>
455459
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
460+
<info name="FormFactor" value="DIMM"/>
461+
<info name="Type" value="DDR3"/>
462+
<info name="Size" value="4194304"/>
463+
<info name="Rank" value="2"/>
456464
</object>
457465
<object type="Misc" os_index="2" subtype="MemoryModule">
458466
<info name="DeviceLocation" value="DIMM_A3 "/>
459467
<info name="Vendor" value="00AD04B300AD"/>
460468
<info name="SerialNumber" value="3667956F"/>
461469
<info name="AssetTag" value="01115021"/>
462470
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
471+
<info name="FormFactor" value="DIMM"/>
472+
<info name="Type" value="DDR3"/>
473+
<info name="Size" value="4194304"/>
474+
<info name="Rank" value="2"/>
463475
</object>
464476
<object type="Misc" os_index="3" subtype="MemoryModule">
465477
<info name="DeviceLocation" value="DIMM_A4 "/>
466478
<info name="Vendor" value="00AD04B300AD"/>
467479
<info name="SerialNumber" value="36679587"/>
468480
<info name="AssetTag" value="01115021"/>
469481
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
482+
<info name="FormFactor" value="DIMM"/>
483+
<info name="Type" value="DDR3"/>
484+
<info name="Size" value="4194304"/>
485+
<info name="Rank" value="2"/>
470486
</object>
471487
<object type="Misc" os_index="12" subtype="MemoryModule">
472488
<info name="DeviceLocation" value="DIMM_B1 "/>
473489
<info name="Vendor" value="00AD04B300AD"/>
474490
<info name="SerialNumber" value="484AE61F"/>
475491
<info name="AssetTag" value="01115021"/>
476492
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
493+
<info name="FormFactor" value="DIMM"/>
494+
<info name="Type" value="DDR3"/>
495+
<info name="Size" value="4194304"/>
496+
<info name="Rank" value="2"/>
477497
</object>
478498
<object type="Misc" os_index="13" subtype="MemoryModule">
479499
<info name="DeviceLocation" value="DIMM_B2 "/>
480500
<info name="Vendor" value="00AD04B300AD"/>
481501
<info name="SerialNumber" value="482AE655"/>
482502
<info name="AssetTag" value="01115021"/>
483503
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
504+
<info name="FormFactor" value="DIMM"/>
505+
<info name="Type" value="DDR3"/>
506+
<info name="Size" value="4194304"/>
507+
<info name="Rank" value="2"/>
484508
</object>
485509
<object type="Misc" os_index="14" subtype="MemoryModule">
486510
<info name="DeviceLocation" value="DIMM_B3 "/>
487511
<info name="Vendor" value="00AD04B300AD"/>
488512
<info name="SerialNumber" value="488AE635"/>
489513
<info name="AssetTag" value="01115021"/>
490514
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
515+
<info name="FormFactor" value="DIMM"/>
516+
<info name="Type" value="DDR3"/>
517+
<info name="Size" value="4194304"/>
518+
<info name="Rank" value="2"/>
491519
</object>
492520
<object type="Misc" os_index="15" subtype="MemoryModule">
493521
<info name="DeviceLocation" value="DIMM_B4 "/>
494522
<info name="Vendor" value="00AD04B300AD"/>
495523
<info name="SerialNumber" value="48AAE621"/>
496524
<info name="AssetTag" value="01115021"/>
497525
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
526+
<info name="FormFactor" value="DIMM"/>
527+
<info name="Type" value="DDR3"/>
528+
<info name="Size" value="4194304"/>
529+
<info name="Rank" value="2"/>
498530
</object>
499531
</object>
500532
<distances2 type="NUMANode" nbobjs="2" kind="5" name="NUMALatency" indexing="os">

0 commit comments

Comments
 (0)