mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-17 08:11:51 +00:00
SPU: Don't use shm::map_critical in SPU LS allocations
Use shm::try_map instead until proper area is found.
This commit is contained in:
parent
caa83d20f7
commit
a69248299d
@ -1332,7 +1332,7 @@ std::string spu_thread::dump_regs() const
|
||||
fmt::append(ret, "Reservation Data:\n");
|
||||
|
||||
be_t<u32> data[32]{};
|
||||
std::memcpy(data, rdata, sizeof(rdata)); // Show the data even if the reservation was lost inside the atomic loop
|
||||
std::memcpy(data, rdata, sizeof(rdata)); // Show the data even if the reservation was lost inside the atomic loop
|
||||
|
||||
for (usz i = 0; i < std::size(data); i += 4)
|
||||
{
|
||||
@ -1705,18 +1705,10 @@ void spu_thread::cleanup()
|
||||
|
||||
spu_thread::~spu_thread()
|
||||
{
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
for (s32 i = -1; i < 2; i++)
|
||||
{
|
||||
// Unmap LS mirrors
|
||||
shm->unmap_critical(ls + (i * SPU_LS_SIZE));
|
||||
}
|
||||
}
|
||||
|
||||
// Release LS mirrors area
|
||||
utils::memory_release(ls - (SPU_LS_SIZE * 2), SPU_LS_SIZE * 5);
|
||||
// Unmap LS and its mirrors
|
||||
shm->unmap(ls + SPU_LS_SIZE);
|
||||
shm->unmap(ls);
|
||||
shm->unmap(ls - SPU_LS_SIZE);
|
||||
|
||||
// Free range lock if not freed already
|
||||
if (range_lock) vm::free_range_lock(range_lock);
|
||||
@ -1741,19 +1733,39 @@ spu_thread::spu_thread(lv2_spu_group* group, u32 index, std::string_view name, u
|
||||
ensure(vm::get(vm::spu)->falloc(SPU_FAKE_BASE_ADDR + SPU_LS_SIZE * (cpu_thread::id & 0xffffff), SPU_LS_SIZE, &shm, 0x1000));
|
||||
}
|
||||
|
||||
vm::writer_lock lock(0);
|
||||
// Try to guess free area
|
||||
const auto start = vm::g_free_addr + SPU_LS_SIZE * (cpu_thread::id & 0xffffff) * 12;
|
||||
|
||||
const auto addr = static_cast<u8*>(utils::memory_reserve(SPU_LS_SIZE * 5));
|
||||
u32 total = 0;
|
||||
|
||||
for (u32 i = 1; i < 4; i++)
|
||||
// Map LS and its mirrors
|
||||
for (u64 addr = reinterpret_cast<u64>(start); addr < 0x8000'0000'0000;)
|
||||
{
|
||||
// Map LS mirrors
|
||||
const auto ptr = addr + (i * SPU_LS_SIZE);
|
||||
ensure(shm->map_critical(ptr) == ptr);
|
||||
if (auto ptr = shm->try_map(reinterpret_cast<u8*>(addr)))
|
||||
{
|
||||
if (++total == 3)
|
||||
{
|
||||
// Use the middle mirror
|
||||
return ptr - SPU_LS_SIZE;
|
||||
}
|
||||
|
||||
addr += SPU_LS_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reset, cleanup and start again
|
||||
for (u32 i = 1; i <= total; i++)
|
||||
{
|
||||
shm->unmap(reinterpret_cast<u8*>(addr - i * SPU_LS_SIZE));
|
||||
}
|
||||
|
||||
total = 0;
|
||||
|
||||
addr += 0x10000;
|
||||
}
|
||||
}
|
||||
|
||||
// Use the middle mirror
|
||||
return addr + (SPU_LS_SIZE * 2);
|
||||
fmt::throw_exception("Failed to map SPU LS memory");
|
||||
}())
|
||||
, thread_type(group ? spu_type::threaded : is_isolated ? spu_type::isolated : spu_type::raw)
|
||||
, group(group)
|
||||
|
@ -26,7 +26,7 @@ namespace vm
|
||||
{
|
||||
static u8* memory_reserve_4GiB(void* _addr, u64 size = 0x100000000)
|
||||
{
|
||||
for (u64 addr = reinterpret_cast<u64>(_addr) + 0x100000000;; addr += 0x100000000)
|
||||
for (u64 addr = reinterpret_cast<u64>(_addr) + 0x100000000; addr < 0x8000'0000'0000; addr += 0x100000000)
|
||||
{
|
||||
if (auto ptr = utils::memory_reserve(size, reinterpret_cast<void*>(addr)))
|
||||
{
|
||||
@ -34,8 +34,7 @@ namespace vm
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: a condition to break loop
|
||||
return static_cast<u8*>(utils::memory_reserve(size));
|
||||
fmt::throw_exception("Failed to reserve vm memory");
|
||||
}
|
||||
|
||||
// Emulated virtual memory
|
||||
@ -50,6 +49,9 @@ namespace vm
|
||||
// Stats for debugging
|
||||
u8* const g_stat_addr = memory_reserve_4GiB(g_exec_addr);
|
||||
|
||||
// For SPU
|
||||
u8* const g_free_addr = g_stat_addr + 0x1'0000'0000;
|
||||
|
||||
// Reservation stats
|
||||
alignas(4096) u8 g_reservations[65536 / 128 * 64]{0};
|
||||
|
||||
|
@ -19,6 +19,7 @@ namespace vm
|
||||
extern u8* const g_sudo_addr;
|
||||
extern u8* const g_exec_addr;
|
||||
extern u8* const g_stat_addr;
|
||||
extern u8* const g_free_addr;
|
||||
extern u8 g_reservations[];
|
||||
|
||||
struct writer_lock;
|
||||
|
Loading…
Reference in New Issue
Block a user