NVDRV: Cleanup.
This commit is contained in:
		| @@ -125,8 +125,10 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | |||||||
|         } |         } | ||||||
|     }(); |     }(); | ||||||
|  |  | ||||||
|  |     must_unmark_fail = true; | ||||||
|  |  | ||||||
|     const auto check_failing = [&]() { |     const auto check_failing = [&]() { | ||||||
|         if (events_interface.fails[slot] > 1) { |         if (events_interface.fails[slot] > 2) { | ||||||
|             { |             { | ||||||
|                 auto lk = system.StallProcesses(); |                 auto lk = system.StallProcesses(); | ||||||
|                 gpu.WaitFence(fence_id, target_value); |                 gpu.WaitFence(fence_id, target_value); | ||||||
|   | |||||||
| @@ -29,6 +29,29 @@ | |||||||
|  |  | ||||||
| namespace Service::Nvidia { | 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<std::mutex> EventInterface::Lock() { | std::unique_lock<std::mutex> EventInterface::Lock() { | ||||||
|     return std::unique_lock<std::mutex>(events_mutex); |     return std::unique_lock<std::mutex>(events_mutex); | ||||||
| } | } | ||||||
| @@ -45,27 +68,25 @@ void EventInterface::Create(u32 event_id) { | |||||||
|     ASSERT(!events[event_id]); |     ASSERT(!events[event_id]); | ||||||
|     ASSERT(!registered[event_id]); |     ASSERT(!registered[event_id]); | ||||||
|     ASSERT(!IsBeingUsed(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; |     status[event_id] = EventState::Available; | ||||||
|     registered[event_id] = true; |     registered[event_id] = true; | ||||||
|     const u64 mask = 1ULL << event_id; |     const u64 mask = 1ULL << event_id; | ||||||
|     fails[event_id] = 0; |     fails[event_id] = 0; | ||||||
|     events_mask |= mask; |     events_mask |= mask; | ||||||
|     LOG_CRITICAL(Service_NVDRV, "Created Event {}", event_id); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| void EventInterface::Free(u32 event_id) { | void EventInterface::Free(u32 event_id) { | ||||||
|     ASSERT(events[event_id]); |     ASSERT(events[event_id]); | ||||||
|     ASSERT(registered[event_id]); |     ASSERT(registered[event_id]); | ||||||
|     ASSERT(!IsBeingUsed(event_id)); |     ASSERT(!IsBeingUsed(event_id)); | ||||||
|  |     module.service_context.CloseEvent(events[event_id]); | ||||||
|     backup[event_id]->GetWritableEvent().Clear(); |  | ||||||
|     events[event_id] = nullptr; |     events[event_id] = nullptr; | ||||||
|     status[event_id] = EventState::Available; |     status[event_id] = EventState::Available; | ||||||
|     registered[event_id] = false; |     registered[event_id] = false; | ||||||
|     const u64 mask = ~(1ULL << event_id); |     const u64 mask = ~(1ULL << event_id); | ||||||
|     events_mask &= mask; |     events_mask &= mask; | ||||||
|     LOG_CRITICAL(Service_NVDRV, "Freed Event {}", event_id); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| u32 EventInterface::FindFreeEvent(u32 syncpoint_id) { | u32 EventInterface::FindFreeEvent(u32 syncpoint_id) { | ||||||
| @@ -114,15 +135,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger | |||||||
| } | } | ||||||
|  |  | ||||||
| Module::Module(Core::System& system) | Module::Module(Core::System& system) | ||||||
|     : syncpoint_manager{system.GPU()}, events_interface{*this}, service_context{system, "nvdrv"} { |     : syncpoint_manager{system.GPU()}, service_context{system, "nvdrv"}, events_interface{*this} { | ||||||
|     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)); |  | ||||||
|     } |  | ||||||
|     auto nvmap_dev = std::make_shared<Devices::nvmap>(system); |     auto nvmap_dev = std::make_shared<Devices::nvmap>(system); | ||||||
|     devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(system, nvmap_dev); |     devices["/dev/nvhost-as-gpu"] = std::make_shared<Devices::nvhost_as_gpu>(system, nvmap_dev); | ||||||
|     devices["/dev/nvhost-gpu"] = std::make_shared<Devices::nvhost_gpu>( |     devices["/dev/nvhost-gpu"] = std::make_shared<Devices::nvhost_gpu>( | ||||||
| @@ -140,15 +153,7 @@ Module::Module(Core::System& system) | |||||||
|         std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager); |         std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager); | ||||||
| } | } | ||||||
|  |  | ||||||
| Module::~Module() { | Module::~Module() = default; | ||||||
|     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]); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| NvResult Module::VerifyFD(DeviceFD fd) const { | NvResult Module::VerifyFD(DeviceFD fd) const { | ||||||
|     if (fd < 0) { |     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 max = MaxNvEvents - std::countl_zero(events_interface.events_mask); | ||||||
|     const u32 min = std::countr_zero(events_interface.events_mask); |     const u32 min = std::countr_zero(events_interface.events_mask); | ||||||
|     for (u32 i = min; i < max; i++) { |     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.assigned_value[i] == value) { | ||||||
|             events_interface.Signal(i); |             events_interface.Signal(i); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -41,14 +41,13 @@ class Module; | |||||||
|  |  | ||||||
| class EventInterface { | class EventInterface { | ||||||
| public: | public: | ||||||
|     EventInterface(Module& module_) : module{module_} {} |     EventInterface(Module& module_); | ||||||
|  |     ~EventInterface(); | ||||||
|  |  | ||||||
|     // Mask representing registered events |     // Mask representing registered events | ||||||
|     u64 events_mask{}; |     u64 events_mask{}; | ||||||
|     // Each kernel event associated to an NV event |     // Each kernel event associated to an NV event | ||||||
|     std::array<Kernel::KEvent*, MaxNvEvents> events{}; |     std::array<Kernel::KEvent*, MaxNvEvents> events{}; | ||||||
|     // Backup NV event |  | ||||||
|     std::array<Kernel::KEvent*, MaxNvEvents> backup{}; |  | ||||||
|     // The status of the current NVEvent |     // The status of the current NVEvent | ||||||
|     std::array<std::atomic<EventState>, MaxNvEvents> status{}; |     std::array<std::atomic<EventState>, MaxNvEvents> status{}; | ||||||
|     // Tells if an NVEvent is registered or not |     // Tells if an NVEvent is registered or not | ||||||
| @@ -139,10 +138,10 @@ private: | |||||||
|     /// Mapping of device node names to their implementation. |     /// Mapping of device node names to their implementation. | ||||||
|     std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; |     std::unordered_map<std::string, std::shared_ptr<Devices::nvdevice>> devices; | ||||||
|  |  | ||||||
|     EventInterface events_interface; |  | ||||||
|  |  | ||||||
|     KernelHelpers::ServiceContext service_context; |     KernelHelpers::ServiceContext service_context; | ||||||
|  |  | ||||||
|  |     EventInterface events_interface; | ||||||
|  |  | ||||||
|     void CreateEvent(u32 event_id); |     void CreateEvent(u32 event_id); | ||||||
|     void FreeEvent(u32 event_id); |     void FreeEvent(u32 event_id); | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -1,5 +1,7 @@ | |||||||
| // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project | // SPDX-FileCopyrightText: 2021 yuzu emulator team and Skyline Team and Contributors | ||||||
| // SPDX-License-Identifier: GPL-2.0-or-later | // (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 <cinttypes> | #include <cinttypes> | ||||||
| #include "common/logging/log.h" | #include "common/logging/log.h" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user