mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 14:08:37 +00:00
vm: memory locking rewritten
Added vm::lock_sudo method (wrapper for utils::memory_lock). Put locking outside of vm::g_mutex scope. Prelock sudo memory for RSX, vm::stack, vm::main. Prelock sudo memory for shared memory objects. Don't check for TSX path.
This commit is contained in:
parent
eaf0bbc108
commit
ea5f5aea5f
6 changed files with 52 additions and 35 deletions
|
|
@ -763,18 +763,6 @@ namespace vm
|
|||
|
||||
// Unlock
|
||||
g_range_lock.release(0);
|
||||
|
||||
perf_meter<"PAGE_LCK"_u64> perf1;
|
||||
|
||||
if (!g_use_rtm)
|
||||
{
|
||||
perf1.reset();
|
||||
}
|
||||
else if (!utils::memory_lock(g_sudo_addr + addr, size))
|
||||
{
|
||||
vm_log.error("Failed to lock memory. Consider increasing your system limits.\n"
|
||||
"addr=0x%x, size=0x%x, shm=%d, shm:[f=%d,l=%u]", addr, size, +!!shm, shm ? shm->flags() : 0, shm ? shm->info : 0);
|
||||
}
|
||||
}
|
||||
|
||||
bool page_protect(u32 addr, u32 size, u8 flags_test, u8 flags_set, u8 flags_clear)
|
||||
|
|
@ -1009,7 +997,7 @@ namespace vm
|
|||
fmt::throw_exception("Invalid memory location (%u)" HERE, +location);
|
||||
}
|
||||
|
||||
return block->alloc(size, align);
|
||||
return block->alloc(size, nullptr, align);
|
||||
}
|
||||
|
||||
u32 falloc(u32 addr, u32 size, memory_location_t location)
|
||||
|
|
@ -1053,6 +1041,19 @@ namespace vm
|
|||
}
|
||||
}
|
||||
|
||||
void lock_sudo(u32 addr, u32 size)
|
||||
{
|
||||
perf_meter<"PAGE_LCK"_u64> perf;
|
||||
|
||||
verify("lock_sudo" HERE), addr % 4096 == 0;
|
||||
verify("lock_sudo" HERE), size % 4096 == 0;
|
||||
|
||||
if (!utils::memory_lock(g_sudo_addr + addr, size))
|
||||
{
|
||||
vm_log.error("Failed to lock sudo memory (addr=0x%x, size=0x%x). Consider increasing your system limits.", addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
bool block_t::try_alloc(u32 addr, u8 flags, u32 size, std::shared_ptr<utils::shm>&& shm)
|
||||
{
|
||||
// Check if memory area is already mapped
|
||||
|
|
@ -1108,12 +1109,13 @@ namespace vm
|
|||
, size(size)
|
||||
, flags(flags)
|
||||
{
|
||||
if (flags & 0x100)
|
||||
if (flags & 0x100 || flags & 0x20)
|
||||
{
|
||||
// Special path for 4k-aligned pages
|
||||
// Special path for whole-allocated areas allowing 4k granularity
|
||||
m_common = std::make_shared<utils::shm>(size);
|
||||
verify(HERE), m_common->map_critical(vm::base(addr), utils::protection::no) == vm::base(addr);
|
||||
verify(HERE), m_common->map_critical(vm::get_super_ptr(addr)) == vm::get_super_ptr(addr);
|
||||
m_common->map_critical(vm::base(addr), utils::protection::no);
|
||||
m_common->map_critical(vm::get_super_ptr(addr));
|
||||
lock_sudo(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1131,7 +1133,6 @@ namespace vm
|
|||
it = next;
|
||||
}
|
||||
|
||||
// Special path for 4k-aligned pages
|
||||
if (m_common)
|
||||
{
|
||||
m_common->unmap_critical(vm::base(addr));
|
||||
|
|
@ -1140,7 +1141,7 @@ namespace vm
|
|||
}
|
||||
}
|
||||
|
||||
u32 block_t::alloc(const u32 orig_size, u32 align, const std::shared_ptr<utils::shm>* src, u64 flags)
|
||||
u32 block_t::alloc(const u32 orig_size, const std::shared_ptr<utils::shm>* src, u32 align, u64 flags)
|
||||
{
|
||||
if (!src)
|
||||
{
|
||||
|
|
@ -1148,8 +1149,6 @@ namespace vm
|
|||
flags = this->flags;
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
// Determine minimal alignment
|
||||
const u32 min_page_size = flags & 0x100 ? 0x1000 : 0x10000;
|
||||
|
||||
|
|
@ -1187,7 +1186,11 @@ namespace vm
|
|||
else if (src)
|
||||
shm = *src;
|
||||
else
|
||||
{
|
||||
shm = std::make_shared<utils::shm>(size);
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
// Search for an appropriate place (unoptimized)
|
||||
for (u32 addr = ::align(this->addr, align); u64{addr} + size <= u64{this->addr} + this->size; addr += align)
|
||||
|
|
@ -1209,8 +1212,6 @@ namespace vm
|
|||
flags = this->flags;
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
// Determine minimal alignment
|
||||
const u32 min_page_size = flags & 0x100 ? 0x1000 : 0x10000;
|
||||
|
||||
|
|
@ -1242,7 +1243,11 @@ namespace vm
|
|||
else if (src)
|
||||
shm = *src;
|
||||
else
|
||||
{
|
||||
shm = std::make_shared<utils::shm>(size);
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
if (!try_alloc(addr, pflags, size, std::move(shm)))
|
||||
{
|
||||
|
|
@ -1289,7 +1294,7 @@ namespace vm
|
|||
}
|
||||
}
|
||||
|
||||
std::pair<u32, std::shared_ptr<utils::shm>> block_t::get(u32 addr, u32 size)
|
||||
std::pair<u32, std::shared_ptr<utils::shm>> block_t::peek(u32 addr, u32 size)
|
||||
{
|
||||
if (addr < this->addr || addr + u64{size} > this->addr + u64{this->size})
|
||||
{
|
||||
|
|
@ -1602,12 +1607,12 @@ namespace vm
|
|||
|
||||
g_locations =
|
||||
{
|
||||
std::make_shared<block_t>(0x00010000, 0x1FFF0000, 0x200), // main
|
||||
std::make_shared<block_t>(0x00010000, 0x1FFF0000, 0x220), // main
|
||||
std::make_shared<block_t>(0x20000000, 0x10000000, 0x201), // user 64k pages
|
||||
nullptr, // user 1m pages
|
||||
nullptr, // rsx context
|
||||
std::make_shared<block_t>(0xC0000000, 0x10000000), // video
|
||||
std::make_shared<block_t>(0xD0000000, 0x10000000, 0x111), // stack
|
||||
std::make_shared<block_t>(0xC0000000, 0x10000000, 0x220), // video
|
||||
std::make_shared<block_t>(0xD0000000, 0x10000000, 0x131), // stack
|
||||
std::make_shared<block_t>(0xE0000000, 0x20000000), // SPU reserved
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue