kern: use slab allocated KSessionRequest dynamic mappings

This commit is contained in:
Michael Scire 2022-10-12 00:36:32 -07:00 committed by SciresM
parent e7a1e0fee2
commit 13238fc4fd
4 changed files with 91 additions and 72 deletions

View file

@ -36,6 +36,7 @@ namespace ams::kern::init {
size_t num_KDebug;
size_t num_KIoPool;
size_t num_KIoRegion;
size_t num_KSessionRequestMappings;
};
NOINLINE void InitializeSlabResourceCounts();

View file

@ -29,7 +29,10 @@ namespace ams::kern {
public:
class SessionMappings {
private:
static constexpr size_t NumStaticMappings = 8;
/* At most 15 buffers of each type (4-bit descriptor counts), for 45 total. */
static constexpr size_t NumMappings = ((1ul << 4) - 1) * 3;
static constexpr size_t NumStaticMappings = 8;
static constexpr size_t NumDynamicMappings = NumMappings - NumStaticMappings;
class Mapping {
private:
@ -50,16 +53,27 @@ namespace ams::kern {
constexpr ALWAYS_INLINE size_t GetSize() const { return m_size; }
constexpr ALWAYS_INLINE KMemoryState GetMemoryState() const { return m_state; }
};
public:
class DynamicMappings : public KSlabAllocated<DynamicMappings, true> {
private:
Mapping m_mappings[NumDynamicMappings];
public:
constexpr explicit DynamicMappings() : m_mappings() { /* ... */ }
constexpr ALWAYS_INLINE Mapping &Get(size_t idx) { return m_mappings[idx]; }
constexpr ALWAYS_INLINE const Mapping &Get(size_t idx) const { return m_mappings[idx]; }
};
static_assert(sizeof(DynamicMappings) == sizeof(Mapping) * NumDynamicMappings);
private:
Mapping m_static_mappings[NumStaticMappings];
Mapping *m_mappings;
DynamicMappings *m_dynamic_mappings;
u8 m_num_send;
u8 m_num_recv;
u8 m_num_exch;
public:
constexpr explicit SessionMappings(util::ConstantInitializeTag) : m_static_mappings(), m_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ }
constexpr explicit SessionMappings(util::ConstantInitializeTag) : m_static_mappings(), m_dynamic_mappings(), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ }
explicit SessionMappings() : m_mappings(nullptr), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ }
explicit SessionMappings() : m_dynamic_mappings(nullptr), m_num_send(), m_num_recv(), m_num_exch() { /* ... */ }
void Initialize() { /* ... */ }
void Finalize();
@ -96,7 +110,7 @@ namespace ams::kern {
if (index < NumStaticMappings) {
return m_static_mappings[index];
} else {
return m_mappings[index - NumStaticMappings];
return m_dynamic_mappings->Get(index - NumStaticMappings);
}
}
@ -107,7 +121,7 @@ namespace ams::kern {
if (index < NumStaticMappings) {
return m_static_mappings[index];
} else {
return m_mappings[index - NumStaticMappings];
return m_dynamic_mappings->Get(index - NumStaticMappings);
}
}
@ -118,7 +132,7 @@ namespace ams::kern {
if (index < NumStaticMappings) {
return m_static_mappings[index];
} else {
return m_mappings[index - NumStaticMappings];
return m_dynamic_mappings->Get(index - NumStaticMappings);
}
}
};

View file

@ -17,30 +17,34 @@
namespace ams::kern::init {
/* For macro convenience. */
using KSessionRequestMappings = KSessionRequest::SessionMappings::DynamicMappings;
#define SLAB_COUNT(CLASS) g_slab_resource_counts.num_##CLASS
#define FOREACH_SLAB_TYPE(HANDLER, ...) \
HANDLER(KProcess, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) \
HANDLER(KThread, (SLAB_COUNT(KThread)), ## __VA_ARGS__) \
HANDLER(KEvent, (SLAB_COUNT(KEvent)), ## __VA_ARGS__) \
HANDLER(KInterruptEvent, (SLAB_COUNT(KInterruptEvent)), ## __VA_ARGS__) \
HANDLER(KPort, (SLAB_COUNT(KPort)), ## __VA_ARGS__) \
HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ## __VA_ARGS__) \
HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ## __VA_ARGS__) \
HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ## __VA_ARGS__) \
HANDLER(KCodeMemory, (SLAB_COUNT(KCodeMemory)), ## __VA_ARGS__) \
HANDLER(KDeviceAddressSpace, (SLAB_COUNT(KDeviceAddressSpace)), ## __VA_ARGS__) \
HANDLER(KSession, (SLAB_COUNT(KSession)), ## __VA_ARGS__) \
HANDLER(KSessionRequest, (SLAB_COUNT(KSession) * 2), ## __VA_ARGS__) \
HANDLER(KLightSession, (SLAB_COUNT(KLightSession)), ## __VA_ARGS__) \
HANDLER(KThreadLocalPage, (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), ## __VA_ARGS__) \
HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ## __VA_ARGS__) \
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ## __VA_ARGS__) \
HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ## __VA_ARGS__) \
HANDLER(KDebug, (SLAB_COUNT(KDebug)), ## __VA_ARGS__) \
HANDLER(KIoPool, (SLAB_COUNT(KIoPool)), ## __VA_ARGS__) \
HANDLER(KIoRegion, (SLAB_COUNT(KIoRegion)), ## __VA_ARGS__) \
HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ## __VA_ARGS__)
HANDLER(KProcess, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) \
HANDLER(KThread, (SLAB_COUNT(KThread)), ## __VA_ARGS__) \
HANDLER(KEvent, (SLAB_COUNT(KEvent)), ## __VA_ARGS__) \
HANDLER(KInterruptEvent, (SLAB_COUNT(KInterruptEvent)), ## __VA_ARGS__) \
HANDLER(KPort, (SLAB_COUNT(KPort)), ## __VA_ARGS__) \
HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ## __VA_ARGS__) \
HANDLER(KSharedMemoryInfo, (SLAB_COUNT(KSharedMemory) * 8), ## __VA_ARGS__) \
HANDLER(KTransferMemory, (SLAB_COUNT(KTransferMemory)), ## __VA_ARGS__) \
HANDLER(KCodeMemory, (SLAB_COUNT(KCodeMemory)), ## __VA_ARGS__) \
HANDLER(KDeviceAddressSpace, (SLAB_COUNT(KDeviceAddressSpace)), ## __VA_ARGS__) \
HANDLER(KSession, (SLAB_COUNT(KSession)), ## __VA_ARGS__) \
HANDLER(KSessionRequest, (SLAB_COUNT(KSession) * 2), ## __VA_ARGS__) \
HANDLER(KLightSession, (SLAB_COUNT(KLightSession)), ## __VA_ARGS__) \
HANDLER(KThreadLocalPage, (SLAB_COUNT(KProcess) + (SLAB_COUNT(KProcess) + SLAB_COUNT(KThread)) / 8), ## __VA_ARGS__) \
HANDLER(KObjectName, (SLAB_COUNT(KObjectName)), ## __VA_ARGS__) \
HANDLER(KResourceLimit, (SLAB_COUNT(KResourceLimit)), ## __VA_ARGS__) \
HANDLER(KEventInfo, (SLAB_COUNT(KThread) + SLAB_COUNT(KDebug)), ## __VA_ARGS__) \
HANDLER(KDebug, (SLAB_COUNT(KDebug)), ## __VA_ARGS__) \
HANDLER(KIoPool, (SLAB_COUNT(KIoPool)), ## __VA_ARGS__) \
HANDLER(KIoRegion, (SLAB_COUNT(KIoRegion)), ## __VA_ARGS__) \
HANDLER(KSecureSystemResource, (SLAB_COUNT(KProcess)), ## __VA_ARGS__) \
HANDLER(KSessionRequestMappings, (SLAB_COUNT(KSessionRequestMappings)), ## __VA_ARGS__)
namespace {
@ -55,24 +59,25 @@ namespace ams::kern::init {
#undef DEFINE_SLAB_TYPE_ENUM_MEMBER
/* Constexpr counts. */
constexpr size_t SlabCountKProcess = 80;
constexpr size_t SlabCountKThread = 800;
constexpr size_t SlabCountKEvent = 900;
constexpr size_t SlabCountKInterruptEvent = 100;
constexpr size_t SlabCountKPort = 384;
constexpr size_t SlabCountKSharedMemory = 80;
constexpr size_t SlabCountKTransferMemory = 200;
constexpr size_t SlabCountKCodeMemory = 10;
constexpr size_t SlabCountKDeviceAddressSpace = 300;
constexpr size_t SlabCountKSession = 1133;
constexpr size_t SlabCountKLightSession = 100;
constexpr size_t SlabCountKObjectName = 7;
constexpr size_t SlabCountKResourceLimit = 5;
constexpr size_t SlabCountKDebug = cpu::NumCores;
constexpr size_t SlabCountKIoPool = 1;
constexpr size_t SlabCountKIoRegion = 6;
constexpr size_t SlabCountKProcess = 80;
constexpr size_t SlabCountKThread = 800;
constexpr size_t SlabCountKEvent = 900;
constexpr size_t SlabCountKInterruptEvent = 100;
constexpr size_t SlabCountKPort = 384;
constexpr size_t SlabCountKSharedMemory = 80;
constexpr size_t SlabCountKTransferMemory = 200;
constexpr size_t SlabCountKCodeMemory = 10;
constexpr size_t SlabCountKDeviceAddressSpace = 300;
constexpr size_t SlabCountKSession = 1133;
constexpr size_t SlabCountKLightSession = 100;
constexpr size_t SlabCountKObjectName = 7;
constexpr size_t SlabCountKResourceLimit = 5;
constexpr size_t SlabCountKDebug = cpu::NumCores;
constexpr size_t SlabCountKIoPool = 1;
constexpr size_t SlabCountKIoRegion = 6;
constexpr size_t SlabcountKSessionRequestMappings = 40;
constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread;
constexpr size_t SlabCountExtraKThread = (1024 + 256 + 256) - SlabCountKThread;
namespace test {
@ -86,22 +91,23 @@ namespace ams::kern::init {
/* Global to hold our resource counts. */
constinit KSlabResourceCounts g_slab_resource_counts = {
.num_KProcess = SlabCountKProcess,
.num_KThread = SlabCountKThread,
.num_KEvent = SlabCountKEvent,
.num_KInterruptEvent = SlabCountKInterruptEvent,
.num_KPort = SlabCountKPort,
.num_KSharedMemory = SlabCountKSharedMemory,
.num_KTransferMemory = SlabCountKTransferMemory,
.num_KCodeMemory = SlabCountKCodeMemory,
.num_KDeviceAddressSpace = SlabCountKDeviceAddressSpace,
.num_KSession = SlabCountKSession,
.num_KLightSession = SlabCountKLightSession,
.num_KObjectName = SlabCountKObjectName,
.num_KResourceLimit = SlabCountKResourceLimit,
.num_KDebug = SlabCountKDebug,
.num_KIoPool = SlabCountKIoPool,
.num_KIoRegion = SlabCountKIoRegion,
.num_KProcess = SlabCountKProcess,
.num_KThread = SlabCountKThread,
.num_KEvent = SlabCountKEvent,
.num_KInterruptEvent = SlabCountKInterruptEvent,
.num_KPort = SlabCountKPort,
.num_KSharedMemory = SlabCountKSharedMemory,
.num_KTransferMemory = SlabCountKTransferMemory,
.num_KCodeMemory = SlabCountKCodeMemory,
.num_KDeviceAddressSpace = SlabCountKDeviceAddressSpace,
.num_KSession = SlabCountKSession,
.num_KLightSession = SlabCountKLightSession,
.num_KObjectName = SlabCountKObjectName,
.num_KResourceLimit = SlabCountKResourceLimit,
.num_KDebug = SlabCountKDebug,
.num_KIoPool = SlabCountKIoPool,
.num_KIoRegion = SlabCountKIoRegion,
.num_KSessionRequestMappings = SlabcountKSessionRequestMappings,
};
template<typename T>

View file

@ -19,22 +19,20 @@ namespace ams::kern {
Result KSessionRequest::SessionMappings::PushMap(KProcessAddress client, KProcessAddress server, size_t size, KMemoryState state, size_t index) {
/* At most 15 buffers of each type (4-bit descriptor counts). */
MESOSPHERE_ASSERT(index < ((1ul << 4) - 1) * 3);
MESOSPHERE_ASSERT(index < NumMappings);
/* Get the mapping. */
Mapping *mapping;
if (index < NumStaticMappings) {
mapping = std::addressof(m_static_mappings[index]);
} else {
/* Allocate a page for the extra mappings. */
if (m_mappings == nullptr) {
KPageBuffer *page_buffer = KPageBuffer::Allocate();
R_UNLESS(page_buffer != nullptr, svc::ResultOutOfMemory());
m_mappings = reinterpret_cast<Mapping *>(page_buffer);
/* Allocate dynamic mappings as necessary. */
if (m_dynamic_mappings == nullptr) {
m_dynamic_mappings = DynamicMappings::Allocate();
R_UNLESS(m_dynamic_mappings != nullptr, svc::ResultOutOfMemory());
}
mapping = std::addressof(m_mappings[index - NumStaticMappings]);
mapping = std::addressof(m_dynamic_mappings->Get(index - NumStaticMappings));
}
/* Set the mapping. */
@ -59,9 +57,9 @@ namespace ams::kern {
}
void KSessionRequest::SessionMappings::Finalize() {
if (m_mappings) {
KPageBuffer::Free(reinterpret_cast<KPageBuffer *>(m_mappings));
m_mappings = nullptr;
if (m_dynamic_mappings) {
DynamicMappings::Free(m_dynamic_mappings);
m_dynamic_mappings = nullptr;
}
}