Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add new IOCTL call to set max ring size #261

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion core/os_interface/linux/drm_neo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include "core/debug_settings/debug_settings_manager.h"
#include "core/helpers/debug_helpers.h"
#include "core/helpers/hw_info.h"
#include "core/memory_manager/memory_constants.h"
#include "core/os_interface/linux/hw_device_id.h"
#include "core/os_interface/linux/os_inc.h"
#include "core/os_interface/linux/sys_calls.h"
Expand Down Expand Up @@ -236,6 +235,27 @@ void Drm::setNonPersistentContext(uint32_t drmContextId) {
ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
}

void Drm::checkRingSizeChangeSupport() {
drm_i915_gem_context_param contextParam = {};
contextParam.param = I915_CONTEXT_PARAM_RINGSIZE;
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM, &contextParam);

ringSizeChangeSupported = (retVal == 0);
}

void Drm::setMaxRingSize(uint32_t drmContextId) {
drm_i915_gem_context_param contextParam = {};
contextParam.ctx_id = drmContextId;
contextParam.param = I915_CONTEXT_PARAM_RINGSIZE;
contextParam.value = maxRingSize;
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_SETPARAM, &contextParam);
if (retVal == ENODEV) {
ringSizeChangeSupported = false;
} else {
UNRECOVERABLE_IF(retVal != 0);
}
}

uint32_t Drm::createDrmContext() {
drm_i915_gem_context_create gcc = {};
auto retVal = ioctl(DRM_IOCTL_I915_GEM_CONTEXT_CREATE, &gcc);
Expand Down
12 changes: 10 additions & 2 deletions core/os_interface/linux/drm_neo.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once
#include "core/helpers/basic_math.h"
#include "core/memory_manager/memory_constants.h"
#include "core/os_interface/linux/engine_info.h"
#include "core/os_interface/linux/hw_device_id.h"
#include "core/os_interface/linux/memory_info.h"
Expand Down Expand Up @@ -85,6 +86,10 @@ class Drm {
void checkNonPersistentContextsSupport();
void setNonPersistentContext(uint32_t drmContextId);

bool isRingSizeChangeSupported() const { return ringSizeChangeSupported; }
void checkRingSizeChangeSupport();
void setMaxRingSize(uint32_t drmContextId);

MemoryInfo *getMemoryInfo() const {
return memoryInfo.get();
}
Expand All @@ -94,11 +99,14 @@ class Drm {

protected:
int getQueueSliceCount(drm_i915_gem_context_param_sseu *sseu);
bool sliceCountChangeSupported = false;
drm_i915_gem_context_param_sseu sseu{};

bool preemptionSupported = false;
bool sliceCountChangeSupported = false;
bool ringSizeChangeSupported = false;
bool nonPersistentContextsSupported = false;
drm_i915_gem_context_param_sseu sseu{};
std::unique_ptr<HwDeviceId> hwDeviceId;
const uint64_t maxRingSize = 512u * MemoryConstants::kiloByte;
int deviceId = 0;
int revisionId = 0;
GTTYPE eGtType = GTTYPE_UNDEFINED;
Expand Down
1 change: 1 addition & 0 deletions core/os_interface/linux/hw_info_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ int HwInfoConfig::configureHwInfo(const HardwareInfo *inHwInfo, HardwareInfo *ou
outHwInfo->capabilityTable.ftrRenderCompressedImages = false;
drm->checkQueueSliceSupport();
drm->checkNonPersistentContextsSupport();
drm->checkRingSizeChangeSupport();
drm->checkPreemptionSupport();
bool preemption = drm->isPreemptionSupported();
PreemptionHelper::adjustDefaultPreemptionMode(outHwInfo->capabilityTable,
Expand Down
3 changes: 3 additions & 0 deletions core/os_interface/linux/os_context_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ OsContextLinux::OsContextLinux(Drm &drm, uint32_t contextId, DeviceBitfield devi
if (drm.areNonPersistentContextsSupported()) {
drm.setNonPersistentContext(drmContextId);
}
if (drm.isRingSizeChangeSupported()) {
drm.setMaxRingSize(drmContextId);
}
if (drm.isPreemptionSupported() && lowPriority) {
drm.setLowPriorityContextParam(drmContextId);
}
Expand Down
12 changes: 12 additions & 0 deletions third_party/uapi/drm/i915_drm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1582,6 +1582,18 @@ struct drm_i915_gem_context_param {
* By default, new contexts allow persistence.
*/
#define I915_CONTEXT_PARAM_PERSISTENCE 0xb

/*
*
* I915_CONTEXT_PARAM_RINGSIZE:
*
* Sets the size of the ringbuffer to use for logical ring contexts.
* Only possible to be set prior to first use, i.e. during construction.
* Only applies to the current set of engine and lost for those engines
* are replaced by a new mapping.
* Must be between 4 - 512 KiB.
*/
#define I915_CONTEXT_PARAM_RINGSIZE 0xc
/* Must be kept compact -- no holes and well documented */

__u64 value;
Expand Down
7 changes: 7 additions & 0 deletions unit_tests/os_interface/linux/drm_mock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,10 @@ int DrmMock::ioctl(unsigned long request, void *arg) {
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_PERSISTENCE) {
return this->StoredRetValForPersistant;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_RINGSIZE) {
receivedContextParamRequest.value = storedMaxRingSize;
return this->StoredRetValForRingSizeChange;
}
}

if ((request == DRM_IOCTL_I915_GEM_CONTEXT_GETPARAM) && (arg != nullptr)) {
Expand All @@ -109,6 +113,9 @@ int DrmMock::ioctl(unsigned long request, void *arg) {
static_cast<drm_i915_gem_context_param *>(arg)->value = this->StoredPersistentContextsSupport;
return this->StoredRetValForPersistant;
}
if (receivedContextParamRequest.param == I915_CONTEXT_PARAM_RINGSIZE) {
return this->StoredRetValForRingSizeChange;
}
}

if (request == DRM_IOCTL_I915_GEM_EXECBUFFER2) {
Expand Down
3 changes: 3 additions & 0 deletions unit_tests/os_interface/linux/drm_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class DrmMock : public Drm {
using Drm::nonPersistentContextsSupported;
using Drm::preemptionSupported;
using Drm::query;
using Drm::ringSizeChangeSupported;
using Drm::sliceCountChangeSupported;

DrmMock(RootDeviceEnvironment &rootDeviceEnvironment) : Drm(std::make_unique<HwDeviceId>(mockFd), rootDeviceEnvironment) {
Expand Down Expand Up @@ -102,6 +103,7 @@ class DrmMock : public Drm {
int StoredRetValForPooledEU = 0;
int StoredRetValForMinEUinPool = 0;
int StoredRetValForPersistant = 0;
int StoredRetValForRingSizeChange = 0;
int StoredPreemptionSupport =
I915_SCHEDULER_CAP_ENABLED |
I915_SCHEDULER_CAP_PRIORITY |
Expand Down Expand Up @@ -135,6 +137,7 @@ class DrmMock : public Drm {

uint64_t storedGTTSize = 1ull << 47;
uint64_t storedParamSseu = ULONG_MAX;
uint64_t storedMaxRingSize = 512u * MemoryConstants::kiloByte;

virtual int handleRemainingRequests(unsigned long request, void *arg) { return -1; }

Expand Down
35 changes: 35 additions & 0 deletions unit_tests/os_interface/linux/drm_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/

#include "core/helpers/file_io.h"
#include "core/memory_manager/memory_constants.h"
#include "core/os_interface/device_factory.h"
#include "core/os_interface/linux/os_context_linux.h"
#include "core/os_interface/linux/os_interface.h"
Expand Down Expand Up @@ -221,6 +222,40 @@ TEST(DrmTest, givenDrmAndNegativeCheckNonPersistentContextsSupportWhenOsContextI
}
}

TEST(DrmTest, givenDrmMockAndPositiveCheckSetRingSizeSupportWhenOsContextIsCreatedThenCorrectRingSizeIsReturned) {

DrmMock drmMock;
uint32_t drmContextId1 = 123;
auto expectedCount = 0u;
drmMock.StoredCtxId = drmContextId1;
drmMock.StoredRetValForRingSizeChange = 0;
drmMock.checkRingSizeChangeSupport();
++expectedCount;

OsContextLinux osContext(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
++expectedCount;
EXPECT_EQ(expectedCount, drmMock.receivedContextParamRequestCount);

uint64_t maxRingSize = 512u * MemoryConstants::kiloByte;
EXPECT_EQ(maxRingSize, drmMock.receivedContextParamRequest.value);
}

TEST(DrmTest, givenDrmMockAndUnsupportedPlatformErrorWhenOsContextIsCreatedThenIsRingSizeChangeSupportedReturnsFalse) {

DrmMock drmMock;
uint32_t drmContextId1 = 123;
drmMock.StoredCtxId = drmContextId1;
auto unsupportedPlatformErrorCode = ENODEV;
drmMock.StoredRetValForRingSizeChange = 0;

drmMock.checkRingSizeChangeSupport();
EXPECT_TRUE(drmMock.isRingSizeChangeSupported());
drmMock.StoredRetValForRingSizeChange = unsupportedPlatformErrorCode;

OsContextLinux osContext(drmMock, 0u, 1, aub_stream::ENGINE_RCS, PreemptionMode::Disabled, false);
EXPECT_FALSE(drmMock.isRingSizeChangeSupported());
}

TEST(DrmTest, givenDrmPreemptionEnabledAndLowPriorityEngineWhenCreatingOsContextThenCallSetContextPriorityIoctl) {
DrmMock drmMock;
drmMock.StoredCtxId = 123;
Expand Down
13 changes: 13 additions & 0 deletions unit_tests/os_interface/linux/hw_info_config_linux_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,19 @@ TEST_F(HwInfoConfigTestLinuxDummy, whenConfigureHwInfoIsCalledAndPersitentContex
EXPECT_FALSE(drm->areNonPersistentContextsSupported());
}

TEST_F(HwInfoConfigTestLinuxDummy, whenConfigureHwInfoIsCalledThenIsRingSizeChangeSupportedReturnsTrue) {
int ret = hwConfig.configureHwInfo(&pInHwInfo, &outHwInfo, osInterface);
EXPECT_EQ(0, ret);
EXPECT_TRUE(drm->isRingSizeChangeSupported());
}

TEST_F(HwInfoConfigTestLinuxDummy, whenConfigureHwInfoIsCalledAndRingSizeChangeIsUnsupportedThenIsRingSizeChangeSupportedReturnsFalse) {
drm->StoredRetValForRingSizeChange = -1;
int ret = hwConfig.configureHwInfo(&pInHwInfo, &outHwInfo, osInterface);
EXPECT_EQ(0, ret);
EXPECT_FALSE(drm->isRingSizeChangeSupported());
}

TEST_F(HwInfoConfigTestLinuxDummy, dummyConfigPreemptionDrmEnabledMidThreadOn) {
pInHwInfo.capabilityTable.defaultPreemptionMode = PreemptionMode::MidThread;
drm->StoredPreemptionSupport =
Expand Down