Skip to content

Commit

Permalink
linux: add more MemoryModule info attributes
Browse files Browse the repository at this point in the history
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 <zubiao.xiong@memverge.com>
Signed-off-by: Brice Goglin <Brice.Goglin@inria.fr>
  • Loading branch information
xiongzubiao authored and bgoglin committed Aug 3, 2023
1 parent ec50746 commit abfd613
Show file tree
Hide file tree
Showing 3 changed files with 156 additions and 1 deletion.
3 changes: 2 additions & 1 deletion doc/hwloc.doxy
Expand Up @@ -2291,9 +2291,10 @@ The Solaris kstat processor group name that was used to build this Group object.
the attribute may be attached to the highest bridge
(i.e. the first object that actually appears below the physical slot).
</dd>
<dt>Vendor, AssetTag, PartNumber, DeviceLocation, BankLocation (MemoryModule Misc objects)</dt>
<dt>Vendor, AssetTag, PartNumber, DeviceLocation, BankLocation, FormFactor, Type, Size, Rank (MemoryModule Misc objects)</dt>
<dd>
Information about memory modules (DIMMs) extracted from SMBIOS.
Size is in KiB.
</dd>
</dl>

Expand Down
122 changes: 122 additions & 0 deletions hwloc/topology-linux.c
Expand Up @@ -6904,6 +6904,8 @@ struct hwloc_firmware_dmi_mem_device_header {
* Anything below (SMBIOS 2.6+) is optional for hwloc,
* we must to check header->length before reading them.
*/
unsigned char attributes;
unsigned char extended_size[4];
};

static int check_dmi_entry(const char *buffer)
Expand All @@ -6917,13 +6919,122 @@ static int check_dmi_entry(const char *buffer)
return 1;
}

static const char *dmi_memory_device_form_factor(uint8_t code)
{
static const char *form_factor[] = {
"Other", /* 0x01 */
"Unknown",
"SIMM",
"SIP",
"Chip",
"DIP",
"ZIP",
"Proprietary Card",
"DIMM",
"TSOP",
"Row Of Chips",
"RIMM",
"SODIMM",
"SRIMM",
"FB-DIMM",
"Die", /* 0x10 */
/* updated for SMBIOS 3.7.0 20230721 */
};

if (code >= 1 && code <= sizeof(form_factor)/sizeof(form_factor[0]))
return form_factor[code - 1];
return NULL; /* return NULL to distinguish unsupported values from the official "Unknown" value above */
}

static const char *dmi_memory_device_type(uint8_t code)
{
static const char *type[] = {
"Other", /* 0x01 */
"Unknown",
"DRAM",
"EDRAM",
"VRAM",
"SRAM",
"RAM",
"ROM",
"Flash",
"EEPROM",
"FEPROM",
"EPROM",
"CDRAM",
"3DRAM",
"SDRAM",
"SGRAM",
"RDRAM",
"DDR",
"DDR2",
"DDR2 FB-DIMM",
"Reserved",
"Reserved",
"Reserved",
"DDR3",
"FBD2",
"DDR4",
"LPDDR",
"LPDDR2",
"LPDDR3",
"LPDDR4",
"Logical non-volatile device",
"HBM",
"HBM2",
"DDR5",
"LPDDR5",
"HBM3" /* 0x24 */
/* updated for SMBIOS 3.7.0 20230721 */
};

if (code >= 1 && code <= sizeof(type)/sizeof(type[0]))
return type[code - 1];
return NULL; /* return NULL to distinguish unsupported values from the official "Unknown" value above */
}

static int dmi_memory_device_size(char *buffer, size_t len,
const struct hwloc_firmware_dmi_mem_device_header *header)
{
uint64_t memory_size = 0;
uint16_t code = *(uint16_t *)(header->size);

if (code == 0xFFFF)
return -1;

if (header->length >= offsetof(struct hwloc_firmware_dmi_mem_device_header, extended_size) + sizeof(header->extended_size) && code == 0x7FFF) {
memory_size = *(uint32_t *)(header->extended_size) & 0x7FFFFFFF; /* MiB */
memory_size <<= 10;
} else {
memory_size = code & 0x7FFF;
if (!(code & 0x8000)) /* MiB (otherwise KiB) */
memory_size <<= 10;
}
snprintf(buffer, len, "%llu", (unsigned long long) memory_size);
return 0;
}

static int dmi_memory_device_rank(char *buffer, size_t len,
const struct hwloc_firmware_dmi_mem_device_header *header)
{
uint8_t code;
if (header->length < offsetof(struct hwloc_firmware_dmi_mem_device_header, attributes) + sizeof(header->attributes))
return -1;
code = header->attributes;
if (!code)
return -1;
snprintf(buffer, len, "%u", code & 0x0F);
return 0;
}

static int
hwloc__get_firmware_dmi_memory_info_one(struct hwloc_topology *topology,
unsigned idx, const char *path, FILE *fd,
struct hwloc_firmware_dmi_mem_device_header *header)
{
unsigned slen;
char buffer[256]; /* enough for memory device strings, or at least for each of them */
const char *retbuf;
unsigned foff; /* offset in raw file */
unsigned boff; /* offset in buffer read from raw file */
unsigned i;
Expand Down Expand Up @@ -7009,6 +7120,17 @@ hwloc__get_firmware_dmi_memory_info_one(struct hwloc_topology *topology,
goto out_with_infos;
}

retbuf = dmi_memory_device_form_factor(header->ff);
if (retbuf)
hwloc__add_info(&infos, "FormFactor", retbuf);
retbuf = dmi_memory_device_type(header->mem_type);
if (retbuf)
hwloc__add_info(&infos, "Type", retbuf);
if (!dmi_memory_device_size(buffer, sizeof(buffer), header))
hwloc__add_info(&infos, "Size", buffer);
if (!dmi_memory_device_rank(buffer, sizeof(buffer), header))
hwloc__add_info(&infos, "Rank", buffer);

misc = hwloc_alloc_setup_object(topology, HWLOC_OBJ_MISC, idx);
if (!misc)
goto out_with_infos;
Expand Down
32 changes: 32 additions & 0 deletions tests/hwloc/linux/32em64t-2n8c+dax+nvme+mic+dimms.xml
Expand Up @@ -446,55 +446,87 @@
<info name="SerialNumber" value="48AAE639"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
<object type="Misc" os_index="1" subtype="MemoryModule">
<info name="DeviceLocation" value="DIMM_A2 "/>
<info name="Vendor" value="00AD04B300AD"/>
<info name="SerialNumber" value="486AE620"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
<object type="Misc" os_index="2" subtype="MemoryModule">
<info name="DeviceLocation" value="DIMM_A3 "/>
<info name="Vendor" value="00AD04B300AD"/>
<info name="SerialNumber" value="3667956F"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
<object type="Misc" os_index="3" subtype="MemoryModule">
<info name="DeviceLocation" value="DIMM_A4 "/>
<info name="Vendor" value="00AD04B300AD"/>
<info name="SerialNumber" value="36679587"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
<object type="Misc" os_index="12" subtype="MemoryModule">
<info name="DeviceLocation" value="DIMM_B1 "/>
<info name="Vendor" value="00AD04B300AD"/>
<info name="SerialNumber" value="484AE61F"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
<object type="Misc" os_index="13" subtype="MemoryModule">
<info name="DeviceLocation" value="DIMM_B2 "/>
<info name="Vendor" value="00AD04B300AD"/>
<info name="SerialNumber" value="482AE655"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
<object type="Misc" os_index="14" subtype="MemoryModule">
<info name="DeviceLocation" value="DIMM_B3 "/>
<info name="Vendor" value="00AD04B300AD"/>
<info name="SerialNumber" value="488AE635"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
<object type="Misc" os_index="15" subtype="MemoryModule">
<info name="DeviceLocation" value="DIMM_B4 "/>
<info name="Vendor" value="00AD04B300AD"/>
<info name="SerialNumber" value="48AAE621"/>
<info name="AssetTag" value="01115021"/>
<info name="PartNumber" value="HMT351R7CFR8C-PB "/>
<info name="FormFactor" value="DIMM"/>
<info name="Type" value="DDR3"/>
<info name="Size" value="4194304"/>
<info name="Rank" value="2"/>
</object>
</object>
<distances2 type="NUMANode" nbobjs="2" kind="5" name="NUMALatency" indexing="os">
Expand Down

0 comments on commit abfd613

Please sign in to comment.