mirror of
https://github.com/intel/compute-runtime.git
synced 2026-01-03 14:55:24 +08:00
Update zesDeviceReset to 1.0 Spec.
Change-Id: Idc55e9c06c4cd7cd366c4a1dd9af77e518c0bec3 Signed-off-by: Bill Jordan <bill.jordan@intel.com>
This commit is contained in:
@@ -147,30 +147,32 @@ ze_result_t LinuxGlobalOperationsImp::reset(ze_bool_t force) {
|
||||
std::vector<int> myPidFds;
|
||||
std::vector<::pid_t> processes;
|
||||
|
||||
// For all processes in the system, see if the process
|
||||
// has this device open.
|
||||
result = pProcfsAccess->listProcesses(processes);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
for (auto &&pid : processes) {
|
||||
std::vector<int> fds;
|
||||
getPidFdsForOpenDevice(pProcfsAccess, pSysfsAccess, pid, fds);
|
||||
if (pid == myPid) {
|
||||
// L0 is expected to have this file open.
|
||||
// Keep list of fds. Close before unbind.
|
||||
myPidFds = fds;
|
||||
} else if (!fds.empty()) {
|
||||
// Device is in use by another process.
|
||||
// Don't reset while in use.
|
||||
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
|
||||
if (!force) {
|
||||
// If not force, don't reset if any process
|
||||
// has this device open.
|
||||
result = pProcfsAccess->listProcesses(processes);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
}
|
||||
for (auto &&pid : processes) {
|
||||
std::vector<int> fds;
|
||||
getPidFdsForOpenDevice(pProcfsAccess, pSysfsAccess, pid, fds);
|
||||
if (pid == myPid) {
|
||||
// L0 is expected to have this file open.
|
||||
// Keep list of fds. Close before unbind.
|
||||
myPidFds = fds;
|
||||
} else if (!fds.empty()) {
|
||||
// Device is in use by another process.
|
||||
// Don't reset while in use.
|
||||
return ZE_RESULT_ERROR_HANDLE_OBJECT_IN_USE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &&fd : myPidFds) {
|
||||
// Close open filedescriptors to the device
|
||||
// before unbinding device.
|
||||
// From this point forward, there is
|
||||
// From this point forward, there is no
|
||||
// graceful way to fail the reset call.
|
||||
// All future ze calls by this process for this
|
||||
// device will fail.
|
||||
@@ -183,9 +185,9 @@ ze_result_t LinuxGlobalOperationsImp::reset(ze_bool_t force) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Verify no other process has the device open.
|
||||
// This addresses the window between checking
|
||||
// file handles above, and unbinding the device.
|
||||
// If force is set (or someone opened the device
|
||||
// after we checkd) there could be processes
|
||||
// that have the device open. Kill them here.
|
||||
result = pProcfsAccess->listProcesses(processes);
|
||||
if (ZE_RESULT_SUCCESS != result) {
|
||||
return result;
|
||||
@@ -194,9 +196,7 @@ ze_result_t LinuxGlobalOperationsImp::reset(ze_bool_t force) {
|
||||
std::vector<int> fds;
|
||||
getPidFdsForOpenDevice(pProcfsAccess, pSysfsAccess, pid, fds);
|
||||
if (!fds.empty()) {
|
||||
// Process is using this device after we unbound it.
|
||||
// Send a sigkill to the process to force it to close
|
||||
// the device. Otherwise, the device cannot be rebound.
|
||||
// Kill all processes that have the device open.
|
||||
::kill(pid, SIGKILL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,11 +39,21 @@ const std::string engine2("2");
|
||||
const std::string engine3("3");
|
||||
std::string driverVersion("5.0.0-37-generic SMP mod_unload");
|
||||
std::string srcVersion("5.0.0-37");
|
||||
const std::string fullFunctionResetPath("/reset");
|
||||
|
||||
class GlobalOperationsSysfsAccess : public SysfsAccess {};
|
||||
|
||||
template <>
|
||||
struct Mock<GlobalOperationsSysfsAccess> : public GlobalOperationsSysfsAccess {
|
||||
ze_result_t getRealPathVal(const std::string file, std::string &val) {
|
||||
if (file.compare(functionLevelReset) == 0) {
|
||||
val = fullFunctionResetPath;
|
||||
} else {
|
||||
return ZE_RESULT_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t getValString(const std::string file, std::string &val) {
|
||||
if (file.compare(subsystemVendorFile) == 0) {
|
||||
val = "0x8086";
|
||||
@@ -131,6 +141,7 @@ struct Mock<GlobalOperationsSysfsAccess> : public GlobalOperationsSysfsAccess {
|
||||
MOCK_METHOD(ze_result_t, read, (const std::string file, std::string &val), (override));
|
||||
MOCK_METHOD(ze_result_t, read, (const std::string file, uint64_t &val), (override));
|
||||
MOCK_METHOD(ze_result_t, scanDirEntries, (const std::string path, std::vector<std::string> &list), (override));
|
||||
MOCK_METHOD(ze_result_t, getRealPath, (const std::string path, std::string &val), (override));
|
||||
};
|
||||
|
||||
class GlobalOperationsFsAccess : public FsAccess {};
|
||||
@@ -168,9 +179,14 @@ struct Mock<GlobalOperationsFsAccess> : public GlobalOperationsFsAccess {
|
||||
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
|
||||
}
|
||||
|
||||
ze_result_t getPermissionDenied(const std::string file) {
|
||||
return ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS;
|
||||
}
|
||||
|
||||
Mock<GlobalOperationsFsAccess>() = default;
|
||||
|
||||
MOCK_METHOD(ze_result_t, read, (const std::string file, std::string &val), (override));
|
||||
MOCK_METHOD(ze_result_t, canWrite, (const std::string file), (override));
|
||||
};
|
||||
|
||||
class PublicLinuxGlobalOperationsImp : public L0::LinuxGlobalOperationsImp {
|
||||
|
||||
@@ -178,5 +178,15 @@ TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhileReadingNonExist
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_NOT_AVAILABLE, pSysfsAccess->scanDirEntries("clients/7/busy", engineEntries));
|
||||
}
|
||||
|
||||
TEST_F(SysmanGlobalOperationsFixture, GivenValidDeviceHandleWhenCallingResetVerifyPermissionDenied) {
|
||||
ON_CALL(*pSysfsAccess.get(), getRealPath(_, Matcher<std::string &>(_)))
|
||||
.WillByDefault(::testing::Invoke(pSysfsAccess.get(), &Mock<GlobalOperationsSysfsAccess>::getRealPathVal));
|
||||
ON_CALL(*pFsAccess.get(), canWrite(Matcher<std::string>(fullFunctionResetPath)))
|
||||
.WillByDefault(::testing::Invoke(pFsAccess.get(), &Mock<GlobalOperationsFsAccess>::getPermissionDenied));
|
||||
pGlobalOperationsImp->init();
|
||||
ze_result_t result = zesDeviceReset(device, true);
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_INSUFFICIENT_PERMISSIONS, result);
|
||||
}
|
||||
|
||||
} // namespace ult
|
||||
} // namespace L0
|
||||
|
||||
Reference in New Issue
Block a user