1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380
|
/*
* Copyright (C) 2018-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#pragma once
#include "shared/source/gmm_helper/gmm_lib.h"
#include "shared/source/helpers/driver_model_type.h"
#include "shared/source/memory_manager/definitions/engine_limits.h"
#include "shared/source/os_interface/linux/drm_debug.h"
#include "shared/source/os_interface/linux/drm_wrappers.h"
#include "shared/source/os_interface/linux/hw_device_id.h"
#include "shared/source/os_interface/os_interface.h"
#include <array>
#include <atomic>
#include <cstdint>
#include <limits>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>
struct GT_SYSTEM_INFO;
namespace aub_stream {
enum EngineType : uint32_t;
}
namespace NEO {
constexpr uint32_t contextPrivateParamBoost = 0x80000000;
constexpr uint32_t chunkingModeShared = 1;
constexpr uint32_t chunkingModeDevice = 2;
enum class AllocationType;
enum class CachePolicy : uint32_t;
enum class CacheRegion : uint16_t;
enum class SubmissionStatus : uint32_t;
class BufferObject;
class ReleaseHelper;
class DeviceFactory;
class MemoryInfo;
class OsContext;
class OsContextLinux;
class Gmm;
class GraphicsAllocation;
struct CacheInfo;
struct EngineInfo;
struct HardwareInfo;
struct RootDeviceEnvironment;
struct SystemInfo;
struct DeviceDescriptor {
unsigned short deviceId;
const HardwareInfo *pHwInfo;
void (*setupHardwareInfo)(HardwareInfo *, bool, const ReleaseHelper *);
const char *devName;
};
extern const DeviceDescriptor deviceDescriptorTable[];
class Drm : public DriverModel {
friend DeviceFactory;
public:
static constexpr DriverModelType driverModelType = DriverModelType::drm;
static SubmissionStatus getSubmissionStatusFromReturnCode(int32_t retCode);
~Drm() override;
virtual int ioctl(DrmIoctl request, void *arg);
unsigned int getDeviceHandle() const override {
return 0;
}
PhysicalDevicePciSpeedInfo getPciSpeedInfo() const override;
int enableTurboBoost();
int getEuTotal(int &euTotal);
int getSubsliceTotal(int &subsliceTotal);
int getMaxGpuFrequency(HardwareInfo &hwInfo, int &maxGpuFrequency);
int getEnabledPooledEu(int &enabled);
int getMinEuInPool(int &minEUinPool);
int getTimestampFrequency(int &frequency);
int getOaTimestampFrequency(int &frequency);
MOCKABLE_VIRTUAL int queryGttSize(uint64_t >tSizeOutput, bool alignUpToFullRange);
bool isPreemptionSupported() const { return preemptionSupported; }
MOCKABLE_VIRTUAL void checkPreemptionSupport();
inline int getFileDescriptor() const { return hwDeviceId->getFileDescriptor(); }
int queryAdapterBDF();
MOCKABLE_VIRTUAL int createDrmVirtualMemory(uint32_t &drmVmId);
void destroyDrmVirtualMemory(uint32_t drmVmId);
MOCKABLE_VIRTUAL int createDrmContext(uint32_t drmVmId, bool isDirectSubmissionRequested, bool isCooperativeContextRequested);
void destroyDrmContext(uint32_t drmContextId);
int queryVmId(uint32_t drmContextId, uint32_t &vmId);
void setLowPriorityContextParam(uint32_t drmContextId);
MOCKABLE_VIRTUAL unsigned int bindDrmContext(uint32_t drmContextId, uint32_t deviceIndex, aub_stream::EngineType engineType);
MOCKABLE_VIRTUAL int getErrno();
bool setQueueSliceCount(uint64_t sliceCount);
void checkQueueSliceSupport();
uint64_t getSliceMask(uint64_t sliceCount);
MOCKABLE_VIRTUAL bool querySystemInfo();
MOCKABLE_VIRTUAL bool queryEngineInfo();
MOCKABLE_VIRTUAL bool sysmanQueryEngineInfo();
MOCKABLE_VIRTUAL bool queryEngineInfo(bool isSysmanEnabled);
MOCKABLE_VIRTUAL bool queryMemoryInfo();
bool queryTopology(HardwareInfo &hwInfo, DrmQueryTopologyData &topologyData);
bool createVirtualMemoryAddressSpace(uint32_t vmCount);
void destroyVirtualMemoryAddressSpace();
uint32_t getVirtualMemoryAddressSpace(uint32_t vmId) const;
MOCKABLE_VIRTUAL int bindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo, const bool forcePagingFence);
MOCKABLE_VIRTUAL int unbindBufferObject(OsContext *osContext, uint32_t vmHandleId, BufferObject *bo);
int setupHardwareInfo(const DeviceDescriptor *, bool);
void setupSystemInfo(HardwareInfo *hwInfo, SystemInfo *sysInfo);
void setupCacheInfo(const HardwareInfo &hwInfo);
MOCKABLE_VIRTUAL void getPrelimVersion(std::string &prelimVersion);
MOCKABLE_VIRTUAL int getEuDebugSysFsEnable();
PhysicalDevicePciBusInfo getPciBusInfo() const override;
bool isGpuHangDetected(OsContext &osContext) override;
MOCKABLE_VIRTUAL bool checkResetStatus(OsContext &osContext);
bool areNonPersistentContextsSupported() const { return nonPersistentContextsSupported; }
void checkNonPersistentContextsSupport();
void setNonPersistentContext(uint32_t drmContextId);
bool isPerContextVMRequired() const {
return requirePerContextVM;
}
void setPerContextVMRequired(bool required) {
requirePerContextVM = required;
}
void checkContextDebugSupport();
bool isContextDebugSupported() { return contextDebugSupported; }
MOCKABLE_VIRTUAL void setContextDebugFlag(uint32_t drmContextId);
void setUnrecoverableContext(uint32_t drmContextId);
void setDirectSubmissionActive(bool value) { this->directSubmissionActive = value; }
bool isDirectSubmissionActive() const { return this->directSubmissionActive; }
MOCKABLE_VIRTUAL void setSharedSystemAllocEnable(bool value) { this->sharedSystemAllocEnable = value; }
MOCKABLE_VIRTUAL bool isSharedSystemAllocEnabled() const { return this->sharedSystemAllocEnable; }
void adjustSharedSystemMemCapabilities();
uint64_t getSharedSystemBindFlags();
MOCKABLE_VIRTUAL bool isSetPairAvailable();
MOCKABLE_VIRTUAL bool getSetPairAvailable() { return setPairAvailable; }
MOCKABLE_VIRTUAL bool isChunkingAvailable();
MOCKABLE_VIRTUAL bool getChunkingAvailable() { return chunkingAvailable; }
MOCKABLE_VIRTUAL uint32_t getChunkingMode() { return chunkingMode; }
uint32_t getMinimalSizeForChunking() { return minimalChunkingSize; }
MOCKABLE_VIRTUAL bool useVMBindImmediate() const;
MOCKABLE_VIRTUAL bool isVmBindAvailable();
MOCKABLE_VIRTUAL bool registerResourceClasses();
MOCKABLE_VIRTUAL void setPageFaultSupported(bool value) { this->pageFaultSupported = value; }
MOCKABLE_VIRTUAL void queryPageFaultSupport();
bool hasPageFaultSupport() const;
bool hasKmdMigrationSupport() const;
bool checkToDisableScratchPage() { return disableScratch; }
unsigned int getGpuFaultCheckThreshold() const { return gpuFaultCheckThreshold; }
void configureScratchPagePolicy();
void configureGpuFaultCheckThreshold();
bool checkGpuPageFaultRequired() {
return (checkToDisableScratchPage() && getGpuFaultCheckThreshold() != 0);
}
MOCKABLE_VIRTUAL bool resourceRegistrationEnabled();
MOCKABLE_VIRTUAL uint32_t registerResource(DrmResourceClass classType, const void *data, size_t size);
MOCKABLE_VIRTUAL void unregisterResource(uint32_t handle);
MOCKABLE_VIRTUAL uint32_t registerIsaCookie(uint32_t isaHandle);
MOCKABLE_VIRTUAL bool isDebugAttachAvailable();
void setGmmInputArgs(void *args) override;
SystemInfo *getSystemInfo() const {
return systemInfo.get();
}
CacheInfo *getCacheInfo() const {
return cacheInfo.get();
}
MemoryInfo *getMemoryInfo() const {
return memoryInfo.get();
}
EngineInfo *getEngineInfo() const {
return engineInfo.get();
}
IoctlHelper *getIoctlHelper() const {
return ioctlHelper.get();
}
const RootDeviceEnvironment &getRootDeviceEnvironment() const {
return rootDeviceEnvironment;
}
const HardwareInfo *getHardwareInfo() const override;
static bool isDrmSupported(int fileDescriptor);
static Drm *create(std::unique_ptr<HwDeviceIdDrm> &&hwDeviceId, RootDeviceEnvironment &rootDeviceEnvironment);
static void overrideBindSupport(bool &useVmBind);
std::string getPciPath() { return hwDeviceId->getPciPath(); }
std::string getDeviceNode() { return hwDeviceId->getDeviceNode(); }
std::pair<uint64_t, uint64_t> getFenceAddressAndValToWait(uint32_t vmHandleId, bool isLocked);
void waitForBind(uint32_t vmHandleId);
uint64_t getNextFenceVal(uint32_t vmHandleId) { return fenceVal[vmHandleId] + 1; }
void incFenceVal(uint32_t vmHandleId) { fenceVal[vmHandleId]++; }
uint64_t *getFenceAddr(uint32_t vmHandleId) { return &pagingFence[vmHandleId]; }
int waitHandle(uint32_t waitHandle, int64_t timeout);
enum class ValueWidth : uint32_t {
u8,
u16,
u32,
u64
};
MOCKABLE_VIRTUAL int waitUserFence(uint32_t ctxId, uint64_t address, uint64_t value, ValueWidth dataWidth, int64_t timeout, uint16_t flags, bool userInterrupt,
uint32_t externalInterruptId, GraphicsAllocation *allocForInterruptWait);
int waitOnUserFences(OsContextLinux &osContext, uint64_t address, uint64_t value, uint32_t numActiveTiles, int64_t timeout, uint32_t postSyncOffset, bool userInterrupt,
uint32_t externalInterruptId, GraphicsAllocation *allocForInterruptWait);
void setNewResourceBoundToVM(BufferObject *bo, uint32_t vmHandleId);
const std::vector<int> &getSliceMappings(uint32_t deviceIndex);
static std::vector<std::unique_ptr<HwDeviceId>> discoverDevices(ExecutionEnvironment &executionEnvironment);
static std::vector<std::unique_ptr<HwDeviceId>> discoverDevice(ExecutionEnvironment &executionEnvironment, std::string &osPciPath);
static std::vector<std::unique_ptr<HwDeviceId>> discoverDevices(ExecutionEnvironment &executionEnvironment, std::string &osPciPath);
[[nodiscard]] std::unique_lock<std::mutex> lockBindFenceMutex();
void setPciDomain(uint32_t domain) {
pciDomain = domain;
}
MOCKABLE_VIRTUAL std::vector<uint64_t> getMemoryRegions();
MOCKABLE_VIRTUAL bool completionFenceSupport();
MOCKABLE_VIRTUAL uint32_t notifyFirstCommandQueueCreated(const void *data, size_t size);
MOCKABLE_VIRTUAL void notifyLastCommandQueueDestroyed(uint32_t handle);
uint64_t getPatIndex(Gmm *gmm, AllocationType allocationType, CacheRegion cacheRegion, CachePolicy cachePolicy, bool closEnabled, bool isSystemMemory) const;
bool isVmBindPatIndexProgrammingSupported() const { return vmBindPatIndexProgrammingSupported; }
MOCKABLE_VIRTUAL bool getDeviceMemoryMaxClockRateInMhz(uint32_t tileId, uint32_t &clkRate);
MOCKABLE_VIRTUAL bool getDeviceMemoryPhysicalSizeInBytes(uint32_t tileId, uint64_t &physicalSize);
void cleanup() override;
bool readSysFsAsString(const std::string &relativeFilePath, std::string &readString);
MOCKABLE_VIRTUAL std::string getSysFsPciPath();
MOCKABLE_VIRTUAL std::string getSysFsPciPathBaseName();
std::unique_ptr<HwDeviceIdDrm> &getHwDeviceId() { return hwDeviceId; }
template <typename DataType>
std::vector<DataType> query(uint32_t queryId, uint32_t queryItemFlags);
static std::string getDrmVersion(int fileDescriptor);
MOCKABLE_VIRTUAL uint32_t getAggregatedProcessCount() const;
uint32_t getVmIdForContext(OsContext &osContext, uint32_t vmHandleId) const;
MOCKABLE_VIRTUAL void setSharedSystemAllocAddressRange(uint64_t value) { this->sharedSystemAllocAddressRange = value; }
MOCKABLE_VIRTUAL uint64_t getSharedSystemAllocAddressRange() const { return this->sharedSystemAllocAddressRange; }
protected:
Drm() = delete;
Drm(std::unique_ptr<HwDeviceIdDrm> &&hwDeviceIdIn, RootDeviceEnvironment &rootDeviceEnvironment);
int waitOnUserFencesImpl(const OsContextLinux &osContext, uint64_t address, uint64_t value, uint32_t numActiveTiles, int64_t timeout, uint32_t postSyncOffset, bool userInterrupt,
uint32_t externalInterruptId, GraphicsAllocation *allocForInterruptWait);
int getQueueSliceCount(GemContextParamSseu *sseu);
std::string generateUUID();
std::string generateElfUUID(const void *data);
void printIoctlStatistics();
void setupIoctlHelper(const PRODUCT_FAMILY productFamily);
void queryAndSetVmBindPatIndexProgrammingSupport();
bool queryDeviceIdAndRevision();
static uint64_t alignUpGttSize(uint64_t inputGttSize);
#pragma pack(1)
struct PCIConfig {
uint16_t vendorID;
uint16_t deviceID;
uint16_t command;
uint16_t status;
uint8_t revision;
uint8_t progIF;
uint8_t subclass;
uint8_t classCode;
uint8_t cacheLineSize;
uint8_t latencyTimer;
uint8_t headerType;
uint8_t bist;
uint32_t bar0[6];
uint32_t cardbusCISPointer;
uint16_t subsystemVendorID;
uint16_t subsystemDeviceID;
uint32_t rom;
uint8_t capabilities;
uint8_t reserved[7];
uint8_t interruptLine;
uint8_t interruptPIN;
uint8_t minGrant;
uint8_t maxLatency;
};
#pragma pack()
GemContextParamSseu sseu{};
ADAPTER_BDF adapterBDF{};
uint32_t pciDomain = 0;
struct IoctlStatisticsEntry {
long long totalTime = 0;
uint64_t count = 0;
long long minTime = std::numeric_limits<long long>::max();
long long maxTime = 0;
};
std::unordered_map<DrmIoctl, IoctlStatisticsEntry> ioctlStatistics;
std::mutex bindFenceMutex;
std::array<uint64_t, EngineLimits::maxHandleCount> pagingFence;
std::array<uint64_t, EngineLimits::maxHandleCount> fenceVal;
std::vector<uint32_t> virtualMemoryIds;
std::unique_ptr<HwDeviceIdDrm> hwDeviceId;
std::unique_ptr<IoctlHelper> ioctlHelper;
std::unique_ptr<SystemInfo> systemInfo;
std::unique_ptr<CacheInfo> cacheInfo;
std::unique_ptr<EngineInfo> engineInfo;
std::unique_ptr<MemoryInfo> memoryInfo;
std::once_flag checkBindOnce;
std::once_flag checkSetPairOnce;
std::once_flag checkChunkingOnce;
std::once_flag checkCompletionFenceOnce;
RootDeviceEnvironment &rootDeviceEnvironment;
bool sliceCountChangeSupported = false;
bool preemptionSupported = false;
bool nonPersistentContextsSupported = false;
bool requirePerContextVM = false;
bool bindAvailable = false;
bool directSubmissionActive = false;
bool sharedSystemAllocEnable = false;
uint64_t sharedSystemAllocAddressRange = 0lu;
bool setPairAvailable = false;
bool chunkingAvailable = false;
uint32_t chunkingMode = 0;
uint32_t minimalChunkingSize;
bool contextDebugSupported = false;
bool pageFaultSupported = false;
bool completionFenceSupported = false;
bool vmBindPatIndexProgrammingSupported = false;
bool disableScratch = false;
uint32_t gpuFaultCheckThreshold = 10u;
std::atomic<uint32_t> gpuFaultCheckCounter{0u};
bool memoryInfoQueried = false;
bool engineInfoQueried = false;
bool systemInfoQueried = false;
bool topologyQueried = false;
private:
int getParamIoctl(DrmParam param, int *dstValue);
};
} // namespace NEO
|