From a21b8824fb8a0bd7bcb44fd50559f26718f5dbc4 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Mon, 1 Nov 2021 15:25:06 +0100 Subject: [PATCH] NVDRV: Cleanup. --- .../hle/service/nvdrv/devices/nvhost_ctrl.cpp | 4 +- src/core/hle/service/nvdrv/nvdrv.cpp | 53 ++++++++++--------- src/core/hle/service/nvdrv/nvdrv.h | 9 ++-- .../hle/service/nvdrv/nvdrv_interface.cpp | 6 ++- 4 files changed, 40 insertions(+), 32 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 9b393521aa..55acd4f78e 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -125,8 +125,10 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector } }(); + must_unmark_fail = true; + const auto check_failing = [&]() { - if (events_interface.fails[slot] > 1) { + if (events_interface.fails[slot] > 2) { { auto lk = system.StallProcesses(); gpu.WaitFence(fence_id, target_value); diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 7c0f89c127..df46562403 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -29,6 +29,29 @@ namespace Service::Nvidia { +EventInterface::EventInterface(Module& module_) : module{module_} { + events_mask = 0; + for (u32 i = 0; i < MaxNvEvents; i++) { + status[i] = EventState::Available; + events[i] = nullptr; + registered[i] = false; + } +} + +EventInterface::~EventInterface() { + auto lk = Lock(); + for (u32 i = 0; i < MaxNvEvents; i++) { + if (registered[i]) { + module.service_context.CloseEvent(events[i]); + events[i] = nullptr; + registered[i] = false; + } + } + for (auto* event : basic_events) { + module.service_context.CloseEvent(event); + } +} + std::unique_lock EventInterface::Lock() { return std::unique_lock(events_mutex); } @@ -45,27 +68,25 @@ void EventInterface::Create(u32 event_id) { ASSERT(!events[event_id]); ASSERT(!registered[event_id]); ASSERT(!IsBeingUsed(event_id)); - events[event_id] = backup[event_id]; + events[event_id] = + module.service_context.CreateEvent(fmt::format("NVDRV::NvEvent_{}", event_id)); status[event_id] = EventState::Available; registered[event_id] = true; const u64 mask = 1ULL << event_id; fails[event_id] = 0; events_mask |= mask; - LOG_CRITICAL(Service_NVDRV, "Created Event {}", event_id); } void EventInterface::Free(u32 event_id) { ASSERT(events[event_id]); ASSERT(registered[event_id]); ASSERT(!IsBeingUsed(event_id)); - - backup[event_id]->GetWritableEvent().Clear(); + module.service_context.CloseEvent(events[event_id]); events[event_id] = nullptr; status[event_id] = EventState::Available; registered[event_id] = false; const u64 mask = ~(1ULL << event_id); events_mask &= mask; - LOG_CRITICAL(Service_NVDRV, "Freed Event {}", event_id); } u32 EventInterface::FindFreeEvent(u32 syncpoint_id) { @@ -114,15 +135,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger } Module::Module(Core::System& system) - : syncpoint_manager{system.GPU()}, events_interface{*this}, service_context{system, "nvdrv"} { - events_interface.events_mask = 0; - for (u32 i = 0; i < MaxNvEvents; i++) { - events_interface.status[i] = EventState::Available; - events_interface.events[i] = nullptr; - events_interface.registered[i] = false; - events_interface.backup[i] = - service_context.CreateEvent(fmt::format("NVDRV::NvEvent_{}", i)); - } + : syncpoint_manager{system.GPU()}, service_context{system, "nvdrv"}, events_interface{*this} { auto nvmap_dev = std::make_shared(system); devices["/dev/nvhost-as-gpu"] = std::make_shared(system, nvmap_dev); devices["/dev/nvhost-gpu"] = std::make_shared( @@ -140,15 +153,7 @@ Module::Module(Core::System& system) std::make_shared(system, nvmap_dev, syncpoint_manager); } -Module::~Module() { - auto lock = events_interface.Lock(); - for (u32 i = 0; i < MaxNvEvents; i++) { - if (events_interface.registered[i]) { - events_interface.Free(i); - } - service_context.CloseEvent(events_interface.backup[i]); - } -} +Module::~Module() = default; NvResult Module::VerifyFD(DeviceFD fd) const { if (fd < 0) { @@ -255,7 +260,7 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) { const u32 max = MaxNvEvents - std::countl_zero(events_interface.events_mask); const u32 min = std::countr_zero(events_interface.events_mask); for (u32 i = min; i < max; i++) { - if (events_interface.registered[i] && events_interface.assigned_syncpt[i] == syncpoint_id && + if (events_interface.assigned_syncpt[i] == syncpoint_id && events_interface.assigned_value[i] == value) { events_interface.Signal(i); } diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index be8813c978..d24b575399 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -41,14 +41,13 @@ class Module; class EventInterface { public: - EventInterface(Module& module_) : module{module_} {} + EventInterface(Module& module_); + ~EventInterface(); // Mask representing registered events u64 events_mask{}; // Each kernel event associated to an NV event std::array events{}; - // Backup NV event - std::array backup{}; // The status of the current NVEvent std::array, MaxNvEvents> status{}; // Tells if an NVEvent is registered or not @@ -139,10 +138,10 @@ private: /// Mapping of device node names to their implementation. std::unordered_map> devices; - EventInterface events_interface; - KernelHelpers::ServiceContext service_context; + EventInterface events_interface; + void CreateEvent(u32 event_id); void FreeEvent(u32 event_id); }; diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index 81ee28f319..bd41205b88 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp @@ -1,5 +1,7 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later +// SPDX-FileCopyrightText: 2021 yuzu emulator team and Skyline Team and Contributors +// (https://github.com/skyline-emu/) +// SPDX-License-Identifier: GPL-3.0-or-later Licensed under GPLv3 +// or any later version Refer to the license.txt file included. #include #include "common/logging/log.h"