Files
compute-runtime/shared/source/os_interface/linux/pci_path.cpp
Elaine, Wang 28fa434541 feature: support pci path contains card0
Some OpenCL application need to render libva surface
with drm display and use the same libva surface as
OpenCL kernel output. Such applicatoins need to
use /dev/dri/card0 instead of /dev/dri/renderD128
for getting the display fd.

Related-To: NEO-11714

Signed-off-by: Elaine, Wang <elaine.wang@intel.com>
2024-07-22 11:28:18 +02:00

90 lines
2.2 KiB
C++

/*
* Copyright (C) 2021-2024 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/os_interface/linux/pci_path.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include <cstdint>
#include <string_view>
#include <unistd.h>
namespace NEO {
std::optional<std::string> getPciLinkPath(int deviceFd) {
char path[256] = {0};
size_t pathlen = 256;
if (SysCalls::getDevicePath(deviceFd, path, pathlen)) {
return std::nullopt;
}
if (SysCalls::access(path, F_OK)) {
return std::nullopt;
}
int readLinkSize = 0;
char devicePath[256] = {0};
size_t devicePathLength = 256;
readLinkSize = SysCalls::readlink(path, devicePath, devicePathLength);
if (readLinkSize == -1) {
return std::nullopt;
}
return std::string(devicePath, static_cast<size_t>(readLinkSize));
}
std::optional<std::string> getPciPath(int deviceFd) {
auto deviceLinkPath = NEO::getPciLinkPath(deviceFd);
if (deviceLinkPath == std::nullopt) {
return std::nullopt;
}
auto pciPathPos = deviceLinkPath->find("/drm/render");
if (pciPathPos == std::string::npos) {
pciPathPos = deviceLinkPath->find("/drm/card");
}
if (pciPathPos == std::string::npos || pciPathPos < 12) {
return std::nullopt;
}
return deviceLinkPath->substr(pciPathPos - 12u, 12u);
}
std::optional<std::string> getPciRootPath(int deviceFd) {
auto pciLinkPath = NEO::getPciLinkPath(deviceFd);
// pciLinkPath = "../../devices/pci0000:37/0000:37:01.0/0000:38:00.0/0000:39:01.0/0000:3a:00.0/drm/renderD128/",
// Then root path = "/pci0000:37/0000:37:01.0/0000:38:00.0/"
if (pciLinkPath == std::nullopt) {
return std::nullopt;
}
auto startPos = pciLinkPath->find("/pci");
if (startPos == std::string::npos) {
return std::nullopt;
}
// Root PCI path is at 2 levels up from drm/renderD128
uint32_t rootPciDepth = 4;
auto endPos = std::string::npos;
while (rootPciDepth--) {
endPos = pciLinkPath->rfind('/', endPos - 1);
if (endPos == std::string::npos) {
return std::nullopt;
}
}
return pciLinkPath->substr(startPos, endPos - startPos);
}
} // namespace NEO