Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
a59de68
SDL330: Add O_NOFOLLOW symlink protection to pcm-msr.cpp, client.cpp,…
markovamaria Jan 23, 2026
c1cc5d0
Implement Windows MCFG ACPI table reading using GetSystemFirmwareTabl…
Copilot Jan 27, 2026
5360074
Address code review feedback: improve comments and fix alignment issue
Copilot Jan 27, 2026
dc8f74e
Add security validation for MCFG header length to prevent integer und…
Copilot Jan 27, 2026
56b6291
fix compilation on Windows
rdementi Jan 27, 2026
afdebfc
convert PCM_DEBUG ifdef into DBG messages
rdementi Jan 27, 2026
7aab6aa
Add getNUMANode() API to PciHandle and PciHandleMM classes
Copilot Jan 27, 2026
e88e116
Refactor getNUMANode to use shared helper function
Copilot Jan 27, 2026
7ae883b
Address code review feedback: improve comments and formatting
Copilot Jan 27, 2026
9e32b3d
Add implementation summary document
Copilot Jan 27, 2026
400eca6
Implement Windows NUMA node retrieval using ACPI SRAT table
Copilot Jan 27, 2026
79f564b
Improve Windows NUMA implementation: add thread safety and fix alignment
Copilot Jan 27, 2026
124697e
Implement FreeBSD NUMA node retrieval using sysctl
Copilot Jan 27, 2026
dac100c
Improve FreeBSD implementation: add buffer overflow protection
Copilot Jan 27, 2026
0f34ec7
Add -n option to pcm-pcicfg to print NUMA node of PCI device
Copilot Jan 27, 2026
98bf5e5
Add tests for pcm-pcicfg -n option to test.sh for CI
Copilot Jan 27, 2026
436760f
fix compilation issues
rdementi Jan 27, 2026
48daab8
improve formatting
rdementi Jan 27, 2026
7e052ed
address cppcheck false-positive
rdementi Jan 28, 2026
e8103c8
remove a too detailed implementation summary
rdementi Jan 28, 2026
1d702ce
DBG: print NUMA node in PCICFG register scan
rdementi Jan 28, 2026
19e4b2e
pcm-power: more error checking anf DBG logging for PERF_LIMIT_REASON_…
rdementi Jan 28, 2026
c96f16f
DBG output for tpmi
rdementi Jan 28, 2026
2d4dea8
Add API to map NUMA node ID to CPU socket ID
Copilot Jan 28, 2026
51de67a
Fix code review issues: update copyright years and improve Windows im…
Copilot Jan 28, 2026
d05ea64
Add FreeBSD implementation for mapNUMANodeToSocket API
Copilot Jan 28, 2026
66d3652
remove FreeBSD fallback implementation which assumes NUMA domain == s…
rdementi Jan 28, 2026
b9d42da
pass NUMANode to uncore discovery and TPMI detection function
rdementi Jan 28, 2026
f5486cf
don't assume 1 discovery table per socket, instead use NUMA topology …
rdementi Jan 28, 2026
9b92681
document socket 0 as default
rdementi Jan 28, 2026
e1eb043
SDL505: Add fuzz report to CI artifacts
markovamaria Jan 28, 2026
bae6fda
add getNUMANode API to TPMIHandle
rdementi Jan 29, 2026
1b02838
Fix Linux linker error for getNUMANodeLinux function
Copilot Jan 29, 2026
21ded08
Add socket ID and NUMA node output to pcm-tpmi utility
Copilot Jan 29, 2026
3f0e23b
Fix stream format state handling and reduce code duplication
Copilot Jan 29, 2026
6cf4cf4
Remove unnecessary null check for PCM instance
Copilot Jan 29, 2026
54f6190
compute NUMA node in constructor of PciHandle/PciHandleMM to eliminat…
Copilot Jan 29, 2026
530ebd2
Implement thread-safe cache for PCM::mapNUMANodeToSocket() (#895)
Copilot Jan 29, 2026
a2ba3d6
rely on NUMA node / socket for UFS
rdementi Jan 30, 2026
30cae6e
Add quiet mode infrastructure with environment variable support
Copilot Jan 30, 2026
d6403c5
Document PCM_QUIET environment variable
Copilot Jan 30, 2026
8cdfe3e
Address code review feedback: use atomic for quietMode and fix string…
Copilot Jan 30, 2026
893a992
implement quietMode for more prints
rdementi Jan 30, 2026
8bb2a37
set Quiet Mode for pcm-tpmi
rdementi Jan 30, 2026
dcc29c3
implement quietMode for more prints (II)
rdementi Jan 30, 2026
af66310
Fix socket information parsing in bhs-die-stat.sh and bhs-power-mode.sh
Copilot Feb 2, 2026
78b8768
Add NUMA node information to script output
Copilot Feb 2, 2026
0123410
Fix whitespace issue in bhs-die-stat.sh
Copilot Feb 2, 2026
82783ee
Print NUMA node ID after Socket ID
Copilot Feb 2, 2026
0da826a
Add instance ID to output after NUMA node ID
Copilot Feb 2, 2026
c7a7fbb
assume NUMA node 0 if not available on Linux
rdementi Feb 2, 2026
29ac335
rename scripts/bhs-die-stat.sh to scripts/ufs-die-stat.sh
rdementi Feb 2, 2026
d897cd7
Fix bhs-power-mode scripts to handle multiple TPMI instances per socket
Copilot Feb 2, 2026
2c41734
implement forAllDevices
rdementi Feb 3, 2026
b1c3787
Add -l option for listing PCI devices with verbosity levels
Copilot Feb 3, 2026
69d82ae
Fix formatting issues from code review
Copilot Feb 3, 2026
c26b506
fix device check and device id retrieval
rdementi Feb 3, 2026
030d4b8
Add NUMA node printing to device listing
Copilot Feb 3, 2026
e2da2b7
enhance output
rdementi Feb 3, 2026
ea6317b
rework verbosity levels
rdementi Feb 5, 2026
83cb106
Update Intel-PMT to latest (8e57e18)
markovamaria Feb 12, 2026
2c8f336
Removed details from error message (SDL423 compliance)
markovamaria Feb 17, 2026
3c29ebe
Add SDL441 compliance workflow with CAS integration
markovamaria Feb 11, 2026
209bb48
Update Dockerfile to meet security compliance
markovamaria Feb 14, 2026
9b55b8a
Add SDL419 compliance workflow with CAS integration
markovamaria Feb 18, 2026
41faa0b
Enabled automatic evidence submission for SDL441
markovamaria Feb 19, 2026
6936bfd
Harden DLL loading, enable SSL for pcm-sensor-server on Windows CI
markovamaria Feb 19, 2026
28d60a9
fix FreeBSD build
rdementi Feb 21, 2026
7b7ff20
Revert "fix FreeBSD build"
rdementi Feb 21, 2026
7f67bdb
add a missing include file
rdementi Feb 21, 2026
11cc76c
Fix FreeBSD compilation error: use cpuset_getaffinity instead of cpus…
Copilot Feb 21, 2026
f322751
Fix macOS build: add MacMSRDriver include path for numa_to_socket_exa…
Copilot Feb 21, 2026
0eb084b
don't compile NUMA example on OSX
rdementi Feb 21, 2026
db8416f
try to fix compile error
rdementi Feb 21, 2026
8d0e56e
fix cppcheck warning
rdementi Feb 21, 2026
609a6e8
fix compilation error
rdementi Feb 21, 2026
1f1418a
alternative BitScanForward64 implementation
rdementi Feb 21, 2026
cf1898e
no numa test on OSX
rdementi Feb 21, 2026
677543d
address cppcheck false-positive
rdementi Feb 21, 2026
8256278
fix cmake file
rdementi Feb 21, 2026
786225b
do not build numa cache test on OSX
rdementi Feb 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/ci-cas-security-dockerfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Security Scanning (dockerfile)

on:
schedule:
# Every 2 months on 1st at midnight UTC
- cron: '0 0 1 */2 *'
# Manual trigger for testing
workflow_dispatch:

jobs:
security:
runs-on: ["innersource.prod.amr.dind"]
if: ${{ github.repository != 'intel/pcm' }}

permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: false

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: CAS Security Orchestrator (Source Only)
uses: intel-innersource/applications.security.monitoring.cas@v2
with:
sdl-api-key: ${{ secrets.SDL_API_KEY }}
sdl-project-id: ${{ secrets.SDL_PROJECT_ID }}
sdl-idsid-value: ${{ secrets.SDL_IDSID_VALUE }}
# Scan for SDL419 only (workaround), SDL441 has separate scan
sdl-tasks: "SDL419"
# Set branch type to 'release' for scheduled runs and manual trigger on main branch.
# Required for automatic evidence submit. Excludes push events.
branch-type: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule') && 'release' || 'dev' }}
43 changes: 43 additions & 0 deletions .github/workflows/ci-cas-security.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Security Scanning (Source Code)

on:
schedule:
# Every 2 months on 1st at midnight UTC
- cron: '0 0 1 */2 *'
# Manual trigger for testing
workflow_dispatch:

jobs:
security:
runs-on: ["innersource.prod.amr.dind"]
if: ${{ github.repository != 'intel/pcm' }}

permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install Python dependencies for SCA scanning
run: |
pip install -r perfmon/requirements.txt || true
pip install -r perfmon/scripts/ci/verify_mapfile/requirements.txt || true
pip install -r Intel-PMT/tools/docker/requirements.txt || true

- name: CAS Security Orchestrator (Source Only)
uses: intel-innersource/applications.security.monitoring.cas@v2
with:
sdl-api-key: ${{ secrets.SDL_API_KEY }}
sdl-project-id: ${{ secrets.SDL_PROJECT_ID }}
sdl-idsid-value: ${{ secrets.SDL_IDSID_VALUE }}
sdl-tasks: "SDL441" # scan for SDL441 only, SDL419 has separate scan (workaround)
# Set branch type to 'release' for scheduled runs and manual trigger on main branch.
# Required for automatic evidence submit. Excludes push events.
branch-type: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule') && 'release' || 'dev' }}
6 changes: 4 additions & 2 deletions .github/workflows/ci-fuzz-micro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ jobs:
- name: upload-artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: fuzz-log-${{ github.sha }}
path: "build/fuzz-log.txt"
name: fuzz-evidence-${{ github.sha }}
path: |
build/fuzz-log.txt
build/report.txt


6 changes: 4 additions & 2 deletions .github/workflows/ci-fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ jobs:
- name: upload-artifact
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0
with:
name: fuzz-log-${{ github.sha }}
path: "build/fuzz-log.txt"
name: fuzz-evidence-${{ github.sha }}
path: |
build/fuzz-log.txt
build/report.txt


7 changes: 6 additions & 1 deletion .github/workflows/ci-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ on:

env:
BUILD_TYPE: Release
OPENSSL_ROOT_DIR: "C:\\Program Files\\OpenSSL-Win64"

permissions:
contents: read
Expand All @@ -30,7 +31,11 @@ jobs:
- name: Configure CMake
run: |
if (Test-Path ${{github.workspace}}\build){ Remove-Item ${{github.workspace}}\build -Recurse }
cmake -B ${{github.workspace}}\build
$cryptoLib = "$env:OPENSSL_ROOT_DIR\lib\VC\x64\MT\libcrypto_static.lib"
$sslLib = "$env:OPENSSL_ROOT_DIR\lib\VC\x64\MT\libssl_static.lib"
cmake -B ${{github.workspace}}\build `
-DLIB_EAY_RELEASE:FILEPATH="$cryptoLib" `
-DSSL_EAY_RELEASE:FILEPATH="$sslLib"
- name: Build
run: |
cmake --build ${{github.workspace}}\build --config ${{env.BUILD_TYPE}} --parallel
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,4 @@ build
src/simdjson
.vscode/
_codeql_build_dir/
tests/numa_test
17 changes: 15 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,26 @@ FROM fedora:43@sha256:6cd815d862109208adf6040ea13391fe6aeb87a9dc80735c2ab07083fd
# Copyright (c) 2020-2024 Intel Corporation

RUN dnf -y install gcc-c++ git findutils make cmake openssl openssl-devel libasan libasan-static hwdata

COPY . /tmp/pcm
RUN cd /tmp/pcm && mkdir build && cd build && cmake -DPCM_NO_STATIC_LIBASAN=OFF .. && make -j
WORKDIR /tmp/pcm/build
RUN cmake -DPCM_NO_STATIC_LIBASAN=OFF .. && make -j

FROM fedora:43@sha256:6cd815d862109208adf6040ea13391fe6aeb87a9dc80735c2ab07083fdf5e03a

COPY --from=builder /tmp/pcm/build/bin/* /usr/local/bin/
COPY --from=builder /tmp/pcm/build/bin/opCode*.txt /usr/local/share/pcm/
COPY --from=builder /usr/share/hwdata/pci.ids /usr/share/hwdata/pci.ids
ENV PCM_NO_PERF=1

ENTRYPOINT [ "/usr/local/bin/pcm-sensor-server", "-p", "9738", "-r" ]
RUN useradd -m pcm-user

# Allow pcm-user to run the server via sudo without a password
RUN echo "pcm-user ALL=(root) NOPASSWD: /usr/local/bin/pcm-sensor-server" >> /etc/sudoers

USER pcm-user

HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD sudo /usr/local/bin/pcm-sensor-server --help > /dev/null 2>&1 || exit 1

ENTRYPOINT [ "sudo", "/usr/local/bin/pcm-sensor-server", "-p", "9738", "-r" ]
2 changes: 1 addition & 1 deletion Intel-PMT
Submodule Intel-PMT updated 36 files
+45 −0 .github/ISSUE_TEMPLATE/bug_report.yml
+24 −0 .github/ISSUE_TEMPLATE/feature_request.yml
+25 −0 .github/ISSUE_TEMPLATE/question.yml
+4 −4 .github/workflows/codeql.yml
+5 −5 .github/workflows/scorecards.yml
+15 −0 MAINTAINERS.md
+41 −2 Readme.md
+1 −1 Security.md
+69 −0 docs/FAQ.md
+35 −0 docs/getting-started.md
+19 −0 docs/use-cases.md
+0 −21 tools/collectd-agent/LICENSE
+32 −0 tools/collectd-agent/Readme.md
+165 −20 tools/collectd-agent/pmt.py
+3 −3 tools/docker/Dockerfile
+144 −120 tools/docker/requirements.txt
+26 −26 tools/inventory-converter/README.md
+2 −2 tools/inventory-converter/inventory_converter.py
+1 −1 tools/inventory-converter/setup.py
+1 −1 tools/inventory-converter/yaml_metadata_from_avro.py
+2 −0 tools/otel/.gitignore
+105 −0 tools/otel/Readme.md
+237 −0 tools/otel/build-config.yaml
+23 −0 tools/otel/configs/config-example-pmt-local.yaml
+30 −0 tools/otel/configs/config-example-pmt-redfish.yaml
+31 −0 tools/otel/intelpmtreceiver/aggregator.go
+120 −0 tools/otel/intelpmtreceiver/common_processor.go
+55 −0 tools/otel/intelpmtreceiver/config.go
+37 −0 tools/otel/intelpmtreceiver/constants.go
+64 −0 tools/otel/intelpmtreceiver/factory.go
+50 −0 tools/otel/intelpmtreceiver/go.mod
+149 −0 tools/otel/intelpmtreceiver/go.sum
+58 −0 tools/otel/intelpmtreceiver/local_aggregator.go
+647 −0 tools/otel/intelpmtreceiver/receiver.go
+86 −0 tools/otel/intelpmtreceiver/redfish_aggregator.go
+361 −0 tools/otel/intelpmtreceiver/xml-parser.go
2 changes: 2 additions & 0 deletions doc/ENVVAR_README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,6 @@

`PCM_ENFORCE_MBM=1` : force-enable Memory Bandwidth Monitoring (MBM) metrics (LocalMemoryBW = LMB) and (RemoteMemoryBW = RMB) on processors with RDT/MBM errata

`PCM_QUIET=1` : enable quiet mode for PCM initialization. In quiet mode, only error messages are output during PCM initialization, suppressing informational output such as processor information and topology details

`PCM_DEBUG_LEVEL=x` : x is an integer defining debug output level. level = 0 (default): minimal or no debug info, > 0 increases verbosity
119 changes: 119 additions & 0 deletions doc/NUMA_NODE_API.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# NUMA Node Location API for PCI Devices

## Overview

The `getNUMANode()` API allows you to retrieve the NUMA (Non-Uniform Memory Access) node location of a PCI device identified by its segment:bus:device:function coordinates.

## Background

- **PciHandle** and **PciHandleMM** classes are abstractions of PCI configuration space registers
- Each PCI device has a unique location: `segment:bus:device:function`
- **segment** is also known as **group number** or **domain** (synonyms: groupnr, groupnr_)

## API Usage

### Method Signature

```cpp
int32 PciHandle::getNUMANode() const;
int32 PciHandleMM::getNUMANode() const;
```

### Return Value

- **>= 0**: The NUMA node ID where the PCI device is located
- **-1**: NUMA information not available or not applicable

### Example

```cpp
#include "pci.h"

using namespace pcm;

// Open a PCI device at segment 0, bus 0, device 0, function 0
PciHandleType handle(0, 0, 0, 0);

// Get the NUMA node
int32 numa_node = handle.getNUMANode();

if (numa_node >= 0) {
std::cout << "Device is on NUMA node: " << numa_node << "\n";
} else {
std::cout << "NUMA information not available\n";
}
```

## Platform-Specific Implementation

### Linux

- **Method**: Reads from `/sys/bus/pci/devices/<domain>:<bus>:<device>.<function>/numa_node`
- **Fallback**: Also tries `/pcm/sys/bus/pci/devices/...` path
- **Return**:
- NUMA node ID (typically 0, 1, 2, ...) if available
- -1 if the file doesn't exist or can't be read

### Windows

- **Method**: Reads SRAT (System Resource Affinity Table) from ACPI firmware using `GetSystemFirmwareTable` API
- **Implementation**:
- Parses SRAT table to extract PCI Device Affinity structures (type 2)
- Builds a mapping from PCI device location (segment:bus:device:function) to NUMA node (proximity domain)
- Caches the mapping on first call for performance
- **Return**:
- NUMA node ID (proximity domain) if device is found in SRAT table
- -1 if SRAT table is not available or device is not listed
- **Requirements**: Windows Vista or later (for `GetSystemFirmwareTable` API)

### FreeBSD / DragonFly

- **Method**: Queries system via `sysctlbyname()` for NUMA domain information
- **Implementation**:
- First checks if NUMA is enabled via `vm.ndomains` sysctl
- Attempts to query PCI device-specific NUMA domain using multiple sysctl path formats
- Tries: `hw.pci.X.Y.Z.W.numa_domain` and `hw.pci.X:Y:Z.W.numa_domain`
- **Return**:
- NUMA node ID if available and system has NUMA enabled
- -1 if NUMA is disabled, not supported, or device affinity information unavailable
- **Note**: FreeBSD doesn't have a standardized sysctl path for PCI device NUMA affinity across all versions

### macOS

- **Method**: Returns -1 (macOS typically doesn't expose NUMA for PCI devices)
- **Return**: -1 (not applicable)

## Use Cases

1. **Performance Optimization**: Place processing threads on the same NUMA node as the device
2. **Memory Allocation**: Allocate buffers on the same NUMA node for optimal DMA performance
3. **System Topology Discovery**: Map out the relationship between PCI devices and NUMA nodes
4. **Monitoring and Analytics**: Identify cross-NUMA traffic patterns

## Building the Example

```bash
cd examples
g++ -std=c++11 -I../src numa_node_example.cpp -o numa_node_example -L../build/lib -lpcm -lpthread
LD_LIBRARY_PATH=../build/lib ./numa_node_example
```

## Notes

- Requires appropriate permissions to access PCI configuration space
- On Linux, run with `sudo` or ensure `/sys/bus/pci` is accessible
- The NUMA node value is read at runtime and not cached
- A return value of -1 doesn't indicate an error; it means NUMA information is not available

## Related APIs

- `PciHandle::read32()` - Read 32-bit value from PCI configuration space
- `PciHandle::write32()` - Write 32-bit value to PCI configuration space
- `PciHandle::read64()` - Read 64-bit value from PCI configuration space
- `PciHandle::exists()` - Check if a PCI device exists

## See Also

- Linux kernel documentation: `Documentation/ABI/testing/sysfs-bus-pci`
- ACPI SRAT (System Resource Affinity Table) specification
- PCI Express Base Specification
2 changes: 1 addition & 1 deletion doc/WINDOWS_HOWTO.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ Starting from this release, **pcm-sensor-server** is now supported on Windows. T

### Running pcm-sensor-server on Windows

1. Choose or create a directory for PCM (e.g., `C:\Program Files\PCM\` or `C:\Program Files (x86)\PCM\`). Copy `msr.sys` and `pcm-sensor-server.exe` to this directory.
1. Create a directory for PCM in a protected location (e.g., `C:\Program Files\PCM\` or `C:\Program Files (x86)\PCM\`). Copy `msr.sys` and `pcm-sensor-server.exe` to this directory. **Important:** Do not place PCM binaries in user-writable directories (e.g., Downloads, Desktop, `C:\Users\Public\`) to prevent DLL planting attacks.

2. Run as Administrator (required for MSR access):
```
Expand Down
8 changes: 7 additions & 1 deletion examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,10 @@ if(UNIX)
# create shared lib example
add_executable(c_example_shlib ${EXAMPLE_FILE})
target_link_libraries(c_example_shlib PUBLIC PCM_SHARED PRIVATE Threads::Threads)
endif(UNIX)

# numa_to_socket_example
if(NOT APPLE)
add_executable(numa_to_socket_example numa_to_socket_example.cpp)
target_link_libraries(numa_to_socket_example PUBLIC PCM_SHARED PRIVATE Threads::Threads)
endif()
endif(UNIX)
75 changes: 75 additions & 0 deletions examples/numa_node_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 2024, Intel Corporation
// Example: How to retrieve NUMA node location for PCI devices

#include <iostream>
#include <iomanip>
#include "pci.h"

using namespace pcm;

int main()
{
std::cout << "Example: Retrieving NUMA node location for PCI devices\n";
std::cout << "========================================================\n\n";

// Example 1: Get NUMA node for a specific PCI device
// Format: segment (or group):bus:device.function
uint32 segment = 0; // Also known as "domain" or "group"
uint32 bus = 0;
uint32 device = 0;
uint32 function = 0;

try
{
// Create a handle to the PCI device
// On Linux: uses /proc/bus/pci/ or PciHandleMM for memory-mapped access
// On Windows: uses Windows driver
// On FreeBSD: uses /dev/pci
// On macOS: uses PCIDriver
PciHandleType handle(segment, bus, device, function);

std::cout << "Successfully opened PCI device "
<< segment << ":" << bus << ":" << device << "." << function << "\n";

// Get the NUMA node location
int32 numa_node = handle.getNUMANode();

std::cout << "NUMA node: ";
if (numa_node >= 0)
{
std::cout << numa_node << "\n";
}
else
{
std::cout << "Not available (return value: " << numa_node << ")\n";
std::cout << "Note: -1 means NUMA information is not available on this platform\n";
std::cout << " or the PCI device does not have NUMA node association.\n";
}

// You can also read PCI configuration space as usual
uint32 vendor_device_id = 0;
if (handle.read32(0, &vendor_device_id) == sizeof(uint32))
{
uint32 vendor_id = vendor_device_id & 0xFFFF;
uint32 device_id = (vendor_device_id >> 16) & 0xFFFF;
std::cout << "\nPCI Device Info:\n";
std::cout << " Vendor ID: 0x" << std::hex << std::setw(4) << std::setfill('0')
<< vendor_id << "\n";
std::cout << " Device ID: 0x" << std::setw(4) << std::setfill('0')
<< device_id << std::dec << "\n";
}
}
catch (const std::exception& e)
{
std::cerr << "Error: " << e.what() << "\n";
std::cerr << "\nPossible reasons:\n";
std::cerr << " - PCI device does not exist\n";
std::cerr << " - Insufficient permissions (try running as root/administrator)\n";
std::cerr << " - PCI subsystem not available on this platform\n";
return 1;
}

std::cout << "\n=== Example completed successfully ===\n";
return 0;
}
Loading
Loading