[PATCH 1/3] lib/amdgpu: Extract PCI device address from file descriptor
vitaly.prosyak at amd.com
vitaly.prosyak at amd.com
Sun Jan 5 07:15:49 UTC 2025
From: "Jesse.zhang at amd.com" <Jesse.zhang at amd.com>
Extract the PCI domain, device, and function numbers from
the file descriptor associated with the amdgpu device.
Cc: Vitaly Prosyak <vitaly.prosyak at amd.com>
Cc: Christian Koenig <christian.koenig at amd.com>
Cc: Alexander Deucher <alexander.deucher at amd.com>
v2 : improve commit message, formatting and some coding (Vitaly)
Suggest-by: Vitaly Prosyak <vitaly.prosyak at amd.com>
Signed-off-by: Jesse Zhang <jesse.zhang at amd.com>
Reviewed-by: Vitaly Prosyak <vitaly.prosyak at amd.com>
---
lib/amdgpu/amd_ip_blocks.c | 143 ++++++++++++++++++++++++++-----------
lib/amdgpu/amd_ip_blocks.h | 17 +++++
2 files changed, 118 insertions(+), 42 deletions(-)
diff --git a/lib/amdgpu/amd_ip_blocks.c b/lib/amdgpu/amd_ip_blocks.c
index cc4163bfc..9749e2072 100644
--- a/lib/amdgpu/amd_ip_blocks.c
+++ b/lib/amdgpu/amd_ip_blocks.c
@@ -810,10 +810,9 @@ int setup_amdgpu_ip_blocks(uint32_t major, uint32_t minor, struct amdgpu_gpu_inf
igt_info("amdgpu: unknown (family_id, chip_external_rev): (%u, %u)\n",
amdinfo->family_id, amdinfo->chip_external_rev);
return -1;
- } else {
- igt_info("amdgpu: %s (family_id, chip_external_rev): (%u, %u)\n",
- info->name, amdinfo->family_id, amdinfo->chip_external_rev);
}
+ igt_info("amdgpu: %s (family_id, chip_external_rev): (%u, %u)\n",
+ info->name, amdinfo->family_id, amdinfo->chip_external_rev);
if (info->family >= CHIP_GFX1100) {
info->chip_class = GFX11;
@@ -1007,43 +1006,103 @@ asic_rings_readness(amdgpu_device_handle device_handle, uint32_t mask,
bool
is_reset_enable(enum amd_ip_block_type ip_type, uint32_t reset_type)
{
- char cmd[256];
- FILE *fp, *fp2;
- char buffer[100];
- bool enable = false;
- char reset_mask[100];
-
- if(ip_type == AMD_IP_GFX)
- snprintf(reset_mask, sizeof(reset_mask) - 1, "gfx_reset_mask");
- else if (ip_type == AMD_IP_COMPUTE)
- snprintf(reset_mask, sizeof(reset_mask) - 1, "compute_reset_mask");
- else
- snprintf(reset_mask, sizeof(reset_mask) - 1, "sdma_reset_mask");
-
- snprintf(cmd, sizeof(cmd) - 1, "sudo cat /sys/kernel/debug/dri/0/name |grep -oP '(?<=dev=)[0-9:.]+'");
- fp = popen(cmd, "r");
- if (fp == NULL)
- return false;
-
- if (fgets(buffer, 13, fp) != NULL) {
- snprintf(cmd,sizeof(cmd) - 1,"sudo cat /sys/bus/pci/devices/%s/%s | grep -oP '%s'",
- buffer,reset_mask,
- reset_type & AMDGPU_RESET_TYPE_FULL ? "full":
- reset_type & AMDGPU_RESET_TYPE_SOFT_RESET ? "soft":
- reset_type & AMDGPU_RESET_TYPE_PER_QUEUE ? "queue": "pipe");
-
- fp2 = popen(cmd, "r");
- if (fp2 == NULL) {
- pclose(fp);
- return false;
- }
-
- if (fgets(buffer, 13, fp2) != NULL) {
- enable = true;
- }
- pclose(fp2);
- }
- pclose(fp);
-
- return enable;
+ char cmd[256];
+ FILE *fp, *fp2;
+ char buffer[100];
+ bool enable = false;
+ char reset_mask[100];
+
+ if (ip_type == AMD_IP_GFX)
+ snprintf(reset_mask, sizeof(reset_mask) - 1, "gfx_reset_mask");
+ else if (ip_type == AMD_IP_COMPUTE)
+ snprintf(reset_mask, sizeof(reset_mask) - 1, "compute_reset_mask");
+ else
+ snprintf(reset_mask, sizeof(reset_mask) - 1, "sdma_reset_mask");
+
+ snprintf(cmd, sizeof(cmd) - 1, "sudo cat /sys/kernel/debug/dri/0/name |grep -oP '(?<=dev=)[0-9:.]+'");
+ fp = popen(cmd, "r");
+ if (fp == NULL)
+ return false;
+
+ if (fgets(buffer, 13, fp) != NULL) {
+ snprintf(cmd, sizeof(cmd) - 1, "sudo cat /sys/bus/pci/devices/%s/%s | grep -oP '%s'",
+ buffer, reset_mask,
+ reset_type & AMDGPU_RESET_TYPE_FULL ? "full" :
+ reset_type & AMDGPU_RESET_TYPE_SOFT_RESET ? "soft" :
+ reset_type & AMDGPU_RESET_TYPE_PER_QUEUE ? "queue" : "pipe");
+
+ fp2 = popen(cmd, "r");
+ if (fp2 == NULL) {
+ pclose(fp);
+ return false;
+ }
+
+ if (fgets(buffer, 13, fp2) != NULL)
+ enable = true;
+ pclose(fp2);
+ }
+ pclose(fp);
+
+ return enable;
+}
+
+/**
+ * get_pci_addr_from_fd - Extracts the PCI device address from a file descriptor.
+ * @fd: The file descriptor to extract the address from.
+ * @pci: Pointer to a pci_addr struct to store the extracted address.
+ *
+ * Returns 0 on success, or a negative error code on failure.
+ */
+int get_pci_addr_from_fd(int fd, struct pci_addr *pci)
+{
+ char path[80];
+ struct stat st;
+ char link[20], pci_path[256];
+ char *buf;
+ int len, sysfs;
+ int ret;
+
+ // Check if the file descriptor is a character device and can be accessed
+ if (fstat(fd, &st) < 0 || !S_ISCHR(st.st_mode))
+ return -1;
+
+ snprintf(path, sizeof(path), "/sys/dev/char/%d:%d",
+ major(st.st_rdev), minor(st.st_rdev));
+
+ // Check if the sysfs path exists
+ if (access(path, F_OK) < 0)
+ return -1;
+
+ // Open the sysfs directory
+ sysfs = open(path, O_RDONLY);
+ if (sysfs < 0)
+ return -1;
+
+ // Read the "device" link from the sysfs directory
+ snprintf(link, sizeof(link), "device");
+ len = readlinkat(sysfs, link, pci_path, sizeof(pci_path) - 1);
+ if (len == -1) {
+ close(sysfs);
+ return -ENOENT;
+ }
+ close(sysfs);
+ // Null-terminate the extracted path
+ pci_path[len] = '\0';
+
+ // Find the last occurrence of '/' in the extracted path
+ buf = strrchr(pci_path, '/');
+ if (!buf)
+ return -ENOENT;
+
+ // Extract the PCI device address from the path using sscanf
+ ret = sscanf(buf, "/%4x:%2x:%2x.%2x", &pci->domain, &pci->bus,
+ &pci->device, &pci->function);
+
+ if (ret != 4) {
+ igt_info("error %s Unable to extract PCI device address from '%s\n",
+ __FUNCTION__, buf);
+ return -ENOENT;
+ }
+
+ return 0;
}
diff --git a/lib/amdgpu/amd_ip_blocks.h b/lib/amdgpu/amd_ip_blocks.h
index 337ef3c25..dc4d87151 100644
--- a/lib/amdgpu/amd_ip_blocks.h
+++ b/lib/amdgpu/amd_ip_blocks.h
@@ -8,6 +8,13 @@
#define AMD_IP_BLOCKS_H
#include <amdgpu_drm.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/sysmacros.h>
#include "amd_registers.h"
#include "amd_family.h"
@@ -183,6 +190,13 @@ struct chip_info {
amdgpu_device_handle dev;
};
+struct pci_addr {
+ unsigned int domain;
+ unsigned int bus;
+ unsigned int device;
+ unsigned int function;
+};
+
extern struct amdgpu_ip_blocks_device amdgpu_ips;
extern const struct chip_info *g_pChip;
int
@@ -220,4 +234,7 @@ asic_rings_readness(amdgpu_device_handle device_handle, uint32_t mask, bool arr[
bool
is_reset_enable(enum amd_ip_block_type ip_type, uint32_t reset_type);
+
+int
+get_pci_addr_from_fd(int fd, struct pci_addr *pci);
#endif
--
2.34.1
More information about the igt-dev
mailing list