Return proper clDevice for given media adapter

Signed-off-by: Kamil Diedrich <kamil.diedrich@intel.com>
This commit is contained in:
Kamil Diedrich 2021-02-17 22:17:01 +01:00 committed by Compute-Runtime-Automation
parent 64d772d366
commit edf066a54b
10 changed files with 328 additions and 41 deletions

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2017-2020 Intel Corporation
# Copyright (C) 2017-2021 Intel Corporation
#
# SPDX-License-Identifier: MIT
#
@ -8,6 +8,7 @@ set(RUNTIME_SRCS_SHARINGS_VA
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/${BRANCH_DIR_SUFFIX}/va_device.cpp
${CMAKE_CURRENT_SOURCE_DIR}/va_device.h
${CMAKE_CURRENT_SOURCE_DIR}/va_device_shared.cpp
${CMAKE_CURRENT_SOURCE_DIR}/${BRANCH_DIR_SUFFIX}/va_extension.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_va_api.cpp
${CMAKE_CURRENT_SOURCE_DIR}/cl_va_api.h

View File

@ -75,7 +75,12 @@ clGetDeviceIDsFromVA_APIMediaAdapterINTEL(cl_platform_id platform, cl_va_api_dev
VADevice vaDevice{};
cl_device_id device = vaDevice.getDeviceFromVA(pPlatform, mediaAdapter);
GetInfoHelper::set(devices, device);
GetInfoHelper::set(numDevices, 1u);
if (device == nullptr) {
GetInfoHelper::set(numDevices, 0u);
status = CL_DEVICE_NOT_FOUND;
} else {
GetInfoHelper::set(numDevices, 1u);
}
}
return status;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -16,7 +16,7 @@ VADevice::VADevice() {
}
ClDevice *VADevice::getDeviceFromVA(Platform *pPlatform, VADisplay vaDisplay) {
return pPlatform->getClDevice(0);
return getRootDeviceFromVaDisplay(pPlatform, vaDisplay);
}
VADevice::~VADevice() {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -20,6 +20,7 @@ class VADevice {
VADevice();
virtual ~VADevice();
ClDevice *getRootDeviceFromVaDisplay(Platform *pPlatform, VADisplay vaDisplay);
ClDevice *getDeviceFromVA(Platform *pPlatform, VADisplay vaDisplay);
static std::function<void *(const char *, int)> fdlopen;

View File

@ -0,0 +1,67 @@
/*
* Copyright (C) 2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/device/device.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/os_interface.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include "opencl/source/cl_device/cl_device.h"
#include "opencl/source/platform/platform.h"
#include "opencl/source/sharings/va/va_device.h"
#include <sys/stat.h>
#include <system_error>
#include <unistd.h>
#include <va/va_backend.h>
namespace NEO {
ClDevice *VADevice::getRootDeviceFromVaDisplay(Platform *pPlatform, VADisplay vaDisplay) {
VADisplayContextP pDisplayContext_test = reinterpret_cast<VADisplayContextP>(vaDisplay);
UNRECOVERABLE_IF(pDisplayContext_test->vadpy_magic != 0x56414430);
VADriverContextP pDriverContext_test = pDisplayContext_test->pDriverContext;
int deviceFd = *(int *)pDriverContext_test->drm_state;
UNRECOVERABLE_IF(deviceFd < 0);
char path[256] = {0};
size_t pathlen = 256;
if (SysCalls::getDevicePath(deviceFd, path, pathlen)) {
return nullptr;
}
if (SysCalls::access(path, F_OK)) {
return nullptr;
}
int readLinkSize = 0;
char devicePath[256] = {0};
readLinkSize = SysCalls::readlink(path, devicePath, pathlen);
if (readLinkSize == -1) {
return nullptr;
}
std::string_view prefixView = "../../devices/pci0000:00/0000:";
std::string_view devicePathView(devicePath, static_cast<size_t>(readLinkSize));
devicePathView.remove_prefix(prefixView.size());
devicePathView = devicePathView.substr(0, 7);
for (size_t i = 0; i < pPlatform->getNumDevices(); ++i) {
auto device = pPlatform->getClDevice(i);
NEO::Device *neoDevice = &device->getDevice();
auto *drm = neoDevice->getRootDeviceEnvironment().osInterface->get()->getDrm();
auto pciPath = drm->getPciPath();
if (devicePathView == pciPath) {
return device;
}
}
return nullptr;
}
} // namespace NEO

View File

@ -1,10 +1,11 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "shared/source/helpers/string.h"
#include "shared/source/os_interface/linux/sys_calls.h"
#include "drm/i915_drm.h"
@ -12,7 +13,11 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <system_error>
namespace NEO {
namespace SysCalls {
@ -20,6 +25,8 @@ uint32_t closeFuncCalled = 0u;
int closeFuncArgPassed = 0;
constexpr int fakeFileDescriptor = 123;
uint32_t vmId = 0;
bool makeFakeDevicePath = false;
bool allowFakeDevicePath = false;
int close(int fileDescriptor) {
closeFuncCalled++;
@ -55,5 +62,35 @@ int ioctl(int fileDescriptor, unsigned long int request, void *arg) {
}
return 0;
}
int access(const char *pathName, int mode) {
if (allowFakeDevicePath || strcmp(pathName, "/sys/dev/char/226:128") == 0) {
return 0;
}
return -1;
}
int readlink(const char *path, char *buf, size_t bufsize) {
if (strcmp(path, "/sys/dev/char/226:128") != 0) {
return -1;
}
constexpr size_t sizeofPath = sizeof("../../devices/pci0000:00/0000:00:02.0/drm/renderD128");
strcpy_s(buf, sizeofPath, "../../devices/pci0000:00/0000:00:02.0/drm/renderD128");
return sizeofPath;
}
int getDevicePath(int deviceFd, char *buf, size_t &bufSize) {
if (deviceFd <= 0) {
return -1;
}
constexpr size_t sizeofPath = sizeof("/sys/dev/char/226:128");
makeFakeDevicePath ? strcpy_s(buf, sizeofPath, "/sys/dev/char/xyzwerq") : strcpy_s(buf, sizeofPath, "/sys/dev/char/226:128");
bufSize = sizeofPath;
return 0;
}
} // namespace SysCalls
} // namespace NEO

View File

@ -1,25 +1,6 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "opencl/source/cl_device/cl_device.h"
#include "opencl/source/platform/platform.h"
#include "opencl/source/sharings/va/va_device.h"
#include "opencl/test/unit_test/fixtures/platform_fixture.h"
#include "test.h"
using namespace NEO;
using VaDeviceTests = Test<PlatformFixture>;
TEST_F(VaDeviceTests, givenVADeviceWhenGetDeviceFromVAIsCalledThenRootDeviceIsReturned) {
VADisplay vaDisplay = nullptr;
VADevice vaDevice{};
ClDevice *device = vaDevice.getDeviceFromVA(pPlatform, vaDisplay);
EXPECT_EQ(pPlatform->getClDevice(0), device);
}

View File

@ -5,15 +5,21 @@
*
*/
#include "shared/source/device/device.h"
#include "shared/source/gmm_helper/gmm.h"
#include "shared/source/helpers/array_count.h"
#include "shared/source/memory_manager/graphics_allocation.h"
#include "shared/source/os_interface/linux/drm_neo.h"
#include "shared/source/os_interface/linux/os_interface.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/ult_hw_config.h"
#include "shared/test/common/helpers/variable_backup.h"
#include "opencl/source/api/api.h"
#include "opencl/source/cl_device/cl_device.h"
#include "opencl/source/platform/platform.h"
#include "opencl/source/sharings/va/cl_va_api.h"
#include "opencl/source/sharings/va/va_device.h"
#include "opencl/source/sharings/va/va_sharing.h"
#include "opencl/source/sharings/va/va_surface.h"
#include "opencl/test/unit_test/fixtures/platform_fixture.h"
@ -22,10 +28,14 @@
#include "opencl/test/unit_test/mocks/mock_command_queue.h"
#include "opencl/test/unit_test/mocks/mock_context.h"
#include "opencl/test/unit_test/mocks/mock_platform.h"
#include "opencl/test/unit_test/os_interface/linux/drm_mock.h"
#include "opencl/test/unit_test/sharings/va/mock_va_sharing.h"
#include "test.h"
#include "gtest/gtest.h"
#include <va/va_backend.h>
using namespace NEO;
class VaSharingTests : public ::testing::Test, public PlatformFixture {
@ -556,19 +566,6 @@ TEST_F(VaSharingTests, givenContextWhenSharingTableEmptyThenReturnsNullptr) {
EXPECT_EQ(sharingF, nullptr);
}
TEST_F(VaSharingTests, givenValidPlatformWhenGetDeviceIdsFromVaApiMediaAdapterCalledThenReturnFirstDevice) {
cl_device_id devices = 0;
cl_uint numDevices = 0;
cl_platform_id platformId = this->pPlatform;
auto errCode = clGetDeviceIDsFromVA_APIMediaAdapterINTEL(platformId, 0u, nullptr, 0u, 1, &devices, &numDevices);
EXPECT_EQ(CL_SUCCESS, errCode);
EXPECT_EQ(1u, numDevices);
EXPECT_NE(nullptr, platform()->getClDevice(0));
EXPECT_EQ(platform()->getClDevice(0), devices);
}
TEST_F(VaSharingTests, givenInValidPlatformWhenGetDeviceIdsFromVaApiMediaAdapterCalledThenReturnFirstDevice) {
cl_device_id devices = 0;
cl_uint numDevices = 0;
@ -1227,3 +1224,172 @@ TEST_F(VaSharingTests, givenPlaneArgumentEquals2WithoutNoProperFormatsThenReturn
EXPECT_EQ(result, CL_SUCCESS);
}
class VaDeviceTests : public Test<PlatformFixture> {
public:
VaDeviceTests() {
ultHwConfig.useMockedPrepareDeviceEnvironmentsFunc = false;
}
VariableBackup<UltHwConfig> backup{&ultHwConfig};
};
TEST_F(VaDeviceTests, givenVADeviceWhenGetDeviceFromVAIsCalledThenRootDeviceIsReturned) {
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = 1;
auto device = pPlatform->getClDevice(0);
NEO::Device *neoDevice = &device->getDevice();
auto mockDrm = static_cast<DrmMock *>(neoDevice->getRootDeviceEnvironment().osInterface->get()->getDrm());
mockDrm->setPciPath("00:02.0");
VADevice vaDevice{};
auto clDevice = vaDevice.getDeviceFromVA(pPlatform, vaDisplay.get());
EXPECT_NE(clDevice, nullptr);
}
TEST_F(VaDeviceTests, givenVADeviceAndInvalidPciPathOfClDeviceWhenGetDeviceFromVAIsCalledThenNullptrIsReturned) {
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = 1;
auto device = pPlatform->getClDevice(0);
NEO::Device *neoDevice = &device->getDevice();
auto mockDrm = static_cast<DrmMock *>(neoDevice->getRootDeviceEnvironment().osInterface->get()->getDrm());
mockDrm->setPciPath("00:00.0");
VADevice vaDevice{};
auto clDevice = vaDevice.getDeviceFromVA(pPlatform, vaDisplay.get());
EXPECT_EQ(clDevice, nullptr);
}
TEST_F(VaDeviceTests, givenVADeviceAndInvalidFDWhenGetDeviceFromVAIsCalledThenNullptrIsReturned) {
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = 0;
VADevice vaDevice{};
auto clDevice = vaDevice.getDeviceFromVA(pPlatform, vaDisplay.get());
EXPECT_EQ(clDevice, nullptr);
}
TEST_F(VaDeviceTests, givenVADeviceAndInvalidMagicNumberWhenGetDeviceFromVAIsCalledThenUnrecoverableIsCalled) {
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x0;
VADevice vaDevice{};
EXPECT_ANY_THROW(vaDevice.getDeviceFromVA(pPlatform, vaDisplay.get()));
}
TEST_F(VaDeviceTests, givenVADeviceAndNegativeFdWhenGetDeviceFromVAIsCalledThenUnrecoverableIsCalled) {
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = -1;
VADevice vaDevice{};
EXPECT_ANY_THROW(vaDevice.getDeviceFromVA(pPlatform, vaDisplay.get()));
}
namespace NEO {
namespace SysCalls {
extern bool makeFakeDevicePath;
extern bool allowFakeDevicePath;
} // namespace SysCalls
} // namespace NEO
TEST_F(VaDeviceTests, givenVADeviceAndFakeDevicePathWhenGetDeviceFromVAIsCalledThenNullptrIsReturned) {
VariableBackup<bool> makeFakePathBackup(&SysCalls::makeFakeDevicePath, true);
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = 1;
VADevice vaDevice{};
auto clDevice = vaDevice.getDeviceFromVA(pPlatform, vaDisplay.get());
EXPECT_EQ(clDevice, nullptr);
}
TEST_F(VaDeviceTests, givenVADeviceAndAbsolutePathWhenGetDeviceFromVAIsCalledThenNullptrIsReturned) {
VariableBackup<bool> makeFakePathBackup(&SysCalls::makeFakeDevicePath, true);
VariableBackup<bool> allowFakeDevicePathBackup(&SysCalls::allowFakeDevicePath, true);
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = 1;
VADevice vaDevice{};
auto clDevice = vaDevice.getDeviceFromVA(pPlatform, vaDisplay.get());
EXPECT_EQ(clDevice, nullptr);
}
TEST_F(VaDeviceTests, givenValidPlatformWithInvalidVaDisplayWhenGetDeviceIdsFromVaApiMediaAdapterCalledThenReturnNullptrAndZeroDevices) {
cl_device_id devices = 0;
cl_uint numDevices = 0;
cl_platform_id platformId = pPlatform;
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = 1;
auto device = pPlatform->getClDevice(0);
NEO::Device *neoDevice = &device->getDevice();
auto mockDrm = static_cast<DrmMock *>(neoDevice->getRootDeviceEnvironment().osInterface->get()->getDrm());
mockDrm->setPciPath("00:00.0");
auto errCode = clGetDeviceIDsFromVA_APIMediaAdapterINTEL(platformId, 0u, vaDisplay.get(), 0u, 1, &devices, &numDevices);
EXPECT_EQ(CL_DEVICE_NOT_FOUND, errCode);
EXPECT_EQ(0u, numDevices);
EXPECT_EQ(nullptr, devices);
}
TEST_F(VaDeviceTests, givenValidPlatformWhenGetDeviceIdsFromVaApiMediaAdapterCalledThenReturnFirstDevice) {
cl_device_id devices = 0;
cl_uint numDevices = 0;
cl_platform_id platformId = pPlatform;
auto vaDisplay = std::make_unique<VADisplayContext>();
vaDisplay->vadpy_magic = 0x56414430;
auto contextPtr = std::make_unique<VADriverContext>();
auto drmState = std::make_unique<int>();
vaDisplay->pDriverContext = contextPtr.get();
contextPtr->drm_state = drmState.get();
*(int *)contextPtr->drm_state = 1;
auto device = pPlatform->getClDevice(0);
NEO::Device *neoDevice = &device->getDevice();
auto mockDrm = static_cast<DrmMock *>(neoDevice->getRootDeviceEnvironment().osInterface->get()->getDrm());
mockDrm->setPciPath("00:02.0");
auto errCode = clGetDeviceIDsFromVA_APIMediaAdapterINTEL(platformId, 0u, vaDisplay.get(), 0u, 1, &devices, &numDevices);
EXPECT_EQ(CL_SUCCESS, errCode);
EXPECT_EQ(1u, numDevices);
EXPECT_EQ(pPlatform->getClDevice(0), devices);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -7,10 +7,15 @@
#pragma once
#include <iostream>
namespace NEO {
namespace SysCalls {
int close(int fileDescriptor);
int open(const char *file, int flags);
int ioctl(int fileDescriptor, unsigned long int request, void *arg);
int getDevicePath(int deviceFd, char *buf, size_t &bufSize);
int access(const char *pathname, int mode);
int readlink(const char *path, char *buf, size_t bufsize);
} // namespace SysCalls
} // namespace NEO

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Intel Corporation
* Copyright (C) 2020-2021 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -8,7 +8,11 @@
#include "shared/source/os_interface/linux/sys_calls.h"
#include <fcntl.h>
#include <iostream>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/sysmacros.h>
#include <unistd.h>
namespace NEO {
@ -22,5 +26,25 @@ int open(const char *file, int flags) {
int ioctl(int fileDescriptor, unsigned long int request, void *arg) {
return ::ioctl(fileDescriptor, request, arg);
}
int access(const char *pathName, int mode) {
return ::access(pathName, mode);
}
int readlink(const char *path, char *buf, size_t bufsize) {
return static_cast<int>(::readlink(path, buf, bufsize));
}
int getDevicePath(int deviceFd, char *buf, size_t &bufSize) {
struct stat st;
if (fstat(deviceFd, &st)) {
return -1;
}
snprintf(buf, bufSize, "/sys/dev/char/%d:%d",
major(st.st_rdev), minor(st.st_rdev));
return 0;
}
} // namespace SysCalls
} // namespace NEO