mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-25 12:12:50 +01: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");
|
fmt::append(ret, "Reservation Data:\n");
|
||||||
|
|
||||||
be_t<u32> data[32]{};
|
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)
|
for (usz i = 0; i < std::size(data); i += 4)
|
||||||
{
|
{
|
||||||
@ -1705,18 +1705,10 @@ void spu_thread::cleanup()
|
|||||||
|
|
||||||
spu_thread::~spu_thread()
|
spu_thread::~spu_thread()
|
||||||
{
|
{
|
||||||
{
|
// Unmap LS and its mirrors
|
||||||
vm::writer_lock lock(0);
|
shm->unmap(ls + SPU_LS_SIZE);
|
||||||
|
shm->unmap(ls);
|
||||||
for (s32 i = -1; i < 2; i++)
|
shm->unmap(ls - SPU_LS_SIZE);
|
||||||
{
|
|
||||||
// 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);
|
|
||||||
|
|
||||||
// Free range lock if not freed already
|
// Free range lock if not freed already
|
||||||
if (range_lock) vm::free_range_lock(range_lock);
|
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));
|
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
|
if (auto ptr = shm->try_map(reinterpret_cast<u8*>(addr)))
|
||||||
const auto ptr = addr + (i * SPU_LS_SIZE);
|
{
|
||||||
ensure(shm->map_critical(ptr) == ptr);
|
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
|
fmt::throw_exception("Failed to map SPU LS memory");
|
||||||
return addr + (SPU_LS_SIZE * 2);
|
|
||||||
}())
|
}())
|
||||||
, thread_type(group ? spu_type::threaded : is_isolated ? spu_type::isolated : spu_type::raw)
|
, thread_type(group ? spu_type::threaded : is_isolated ? spu_type::isolated : spu_type::raw)
|
||||||
, group(group)
|
, group(group)
|
||||||
|
@ -26,7 +26,7 @@ namespace vm
|
|||||||
{
|
{
|
||||||
static u8* memory_reserve_4GiB(void* _addr, u64 size = 0x100000000)
|
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)))
|
if (auto ptr = utils::memory_reserve(size, reinterpret_cast<void*>(addr)))
|
||||||
{
|
{
|
||||||
@ -34,8 +34,7 @@ namespace vm
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: a condition to break loop
|
fmt::throw_exception("Failed to reserve vm memory");
|
||||||
return static_cast<u8*>(utils::memory_reserve(size));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Emulated virtual memory
|
// Emulated virtual memory
|
||||||
@ -50,6 +49,9 @@ namespace vm
|
|||||||
// Stats for debugging
|
// Stats for debugging
|
||||||
u8* const g_stat_addr = memory_reserve_4GiB(g_exec_addr);
|
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
|
// Reservation stats
|
||||||
alignas(4096) u8 g_reservations[65536 / 128 * 64]{0};
|
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_sudo_addr;
|
||||||
extern u8* const g_exec_addr;
|
extern u8* const g_exec_addr;
|
||||||
extern u8* const g_stat_addr;
|
extern u8* const g_stat_addr;
|
||||||
|
extern u8* const g_free_addr;
|
||||||
extern u8 g_reservations[];
|
extern u8 g_reservations[];
|
||||||
|
|
||||||
struct writer_lock;
|
struct writer_lock;
|
||||||
|
Loading…
Reference in New Issue
Block a user