diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-12-09 14:53:55 +0000 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-12-15 22:04:28 +0000 |
commit | 1b5a565e5587bcf58d8801601a2c519771c1e971 (patch) | |
tree | 4841bb9dcfdb9f6fada0429e7e73fc41c067f7df /Kernel | |
parent | 6d67cb516a78f7d9131cf88cc1bf2d8439d95ee8 (diff) | |
download | serenity-1b5a565e5587bcf58d8801601a2c519771c1e971.zip |
Kernel: Allocate VirtIOGPU context IDs from a bitmap, with ErrorOr
As is, we never *deallocate* them, so we will run out eventually.
Creating a context, or allocating a context ID, now returns ErrorOr if
there are no available free context IDs.
`number_of_fixmes--;` :^)
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Graphics/VirtIOGPU/GPU3DDevice.cpp | 4 | ||||
-rw-r--r-- | Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp | 33 | ||||
-rw-r--r-- | Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h | 8 |
3 files changed, 32 insertions, 13 deletions
diff --git a/Kernel/Graphics/VirtIOGPU/GPU3DDevice.cpp b/Kernel/Graphics/VirtIOGPU/GPU3DDevice.cpp index 90f0fcc4dc..3ed02a12d1 100644 --- a/Kernel/Graphics/VirtIOGPU/GPU3DDevice.cpp +++ b/Kernel/Graphics/VirtIOGPU/GPU3DDevice.cpp @@ -39,7 +39,7 @@ VirtIOGPU3DDevice::VirtIOGPU3DDevice(VirtIOGraphicsAdapter const& graphics_adapt , m_graphics_adapter(graphics_adapter) , m_transfer_buffer_region(move(transfer_buffer_region)) { - m_kernel_context_id = m_graphics_adapter->create_context(); + m_kernel_context_id = MUST(m_graphics_adapter->create_context()); } void VirtIOGPU3DDevice::detach(OpenFileDescription& description) @@ -65,7 +65,7 @@ ErrorOr<void> VirtIOGPU3DDevice::ioctl(OpenFileDescription& description, unsigne return EEXIST; SpinlockLocker locker(m_graphics_adapter->operation_lock()); // TODO: Delete the context if it fails to be set in m_context_state_lookup - auto context_id = m_graphics_adapter->create_context(); + auto context_id = TRY(m_graphics_adapter->create_context()); LockRefPtr<PerContextState> per_context_state = TRY(PerContextState::try_create(context_id)); TRY(m_context_state_lookup.try_set(&description, per_context_state)); return {}; diff --git a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp index 1c0a37bbed..be3059316d 100644 --- a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp +++ b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.cpp @@ -30,7 +30,8 @@ NonnullLockRefPtr<VirtIOGraphicsAdapter> VirtIOGraphicsAdapter::initialize(PCI:: "VirtGPU Scratch Space"sv, Memory::Region::Access::ReadWrite)); - auto adapter = adopt_lock_ref(*new (nothrow) VirtIOGraphicsAdapter(device_identifier, move(scratch_space_region))); + auto active_context_ids = Bitmap::must_create(VREND_MAX_CTX, false); + auto adapter = adopt_lock_ref(*new (nothrow) VirtIOGraphicsAdapter(device_identifier, move(active_context_ids), move(scratch_space_region))); adapter->initialize(); MUST(adapter->initialize_adapter()); return adapter; @@ -125,10 +126,15 @@ ErrorOr<void> VirtIOGraphicsAdapter::attach_physical_range_to_framebuffer(VirtIO return {}; } -VirtIOGraphicsAdapter::VirtIOGraphicsAdapter(PCI::DeviceIdentifier const& device_identifier, NonnullOwnPtr<Memory::Region> scratch_space_region) +VirtIOGraphicsAdapter::VirtIOGraphicsAdapter(PCI::DeviceIdentifier const& device_identifier, Bitmap&& active_context_ids, NonnullOwnPtr<Memory::Region> scratch_space_region) : VirtIO::Device(device_identifier) , m_scratch_space(move(scratch_space_region)) { + m_active_context_ids.with([&](Bitmap& my_active_context_ids) { + my_active_context_ids = move(active_context_ids); + // Note: Context ID 0 is invalid, so mark it as in use. + my_active_context_ids.set(0, true); + }); } void VirtIOGraphicsAdapter::initialize() @@ -410,10 +416,23 @@ Graphics::VirtIOGPU::ResourceID VirtIOGraphicsAdapter::allocate_resource_id() return m_resource_id_counter++; } -Graphics::VirtIOGPU::ContextID VirtIOGraphicsAdapter::allocate_context_id() +ErrorOr<Graphics::VirtIOGPU::ContextID> VirtIOGraphicsAdapter::allocate_context_id() { - // FIXME: This should really be tracked using a bitmap, instead of an atomic counter - return m_context_id_counter++; + Optional<Graphics::VirtIOGPU::ContextID> new_context_id; + + m_active_context_ids.with([&new_context_id](Bitmap& active_context_ids) { + auto maybe_available_id = active_context_ids.find_first_unset(); + if (!maybe_available_id.has_value()) + return; + new_context_id = maybe_available_id.value(); + active_context_ids.set(maybe_available_id.value(), true); + }); + + if (new_context_id.has_value()) + return new_context_id.value(); + + dmesgln("VirtIO::GraphicsAdapter: No available context IDs."); + return Error::from_errno(ENXIO); } void VirtIOGraphicsAdapter::delete_resource(Graphics::VirtIOGPU::ResourceID resource_id) @@ -439,10 +458,10 @@ void VirtIOGraphicsAdapter::initialize_3d_device() } } -Graphics::VirtIOGPU::ContextID VirtIOGraphicsAdapter::create_context() +ErrorOr<Graphics::VirtIOGPU::ContextID> VirtIOGraphicsAdapter::create_context() { VERIFY(m_operation_lock.is_locked()); - auto ctx_id = allocate_context_id(); + auto ctx_id = TRY(allocate_context_id()); auto writer = create_scratchspace_writer(); auto& request = writer.append_structure<Graphics::VirtIOGPU::Protocol::ContextCreate>(); auto& response = writer.append_structure<Graphics::VirtIOGPU::Protocol::ControlHeader>(); diff --git a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h index 0e35d162b8..81e496a202 100644 --- a/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h +++ b/Kernel/Graphics/VirtIOGPU/GraphicsAdapter.h @@ -63,7 +63,7 @@ private: PhysicalBuffer back_buffer; }; - VirtIOGraphicsAdapter(PCI::DeviceIdentifier const&, NonnullOwnPtr<Memory::Region> scratch_space_region); + VirtIOGraphicsAdapter(PCI::DeviceIdentifier const&, Bitmap&& active_context_ids, NonnullOwnPtr<Memory::Region> scratch_space_region); ErrorOr<void> initialize_adapter(); @@ -80,14 +80,14 @@ private: } // 3D Command stuff - Graphics::VirtIOGPU::ContextID create_context(); + ErrorOr<Graphics::VirtIOGPU::ContextID> create_context(); void attach_resource_to_context(Graphics::VirtIOGPU::ResourceID resource_id, Graphics::VirtIOGPU::ContextID context_id); void submit_command_buffer(Graphics::VirtIOGPU::ContextID, Function<size_t(Bytes)> buffer_writer); Graphics::VirtIOGPU::Protocol::TextureFormat get_framebuffer_format() const { return Graphics::VirtIOGPU::Protocol::TextureFormat::VIRTIO_GPU_FORMAT_B8G8R8X8_UNORM; } auto& operation_lock() { return m_operation_lock; } Graphics::VirtIOGPU::ResourceID allocate_resource_id(); - Graphics::VirtIOGPU::ContextID allocate_context_id(); + ErrorOr<Graphics::VirtIOGPU::ContextID> allocate_context_id(); PhysicalAddress start_of_scratch_space() const { return m_scratch_space->physical_page(0)->paddr(); } AK::BinaryBufferWriter create_scratchspace_writer() @@ -113,7 +113,7 @@ private: VirtIO::Configuration const* m_device_configuration { nullptr }; // Note: Resource ID 0 is invalid, and we must not allocate 0 as the first resource ID. Atomic<u32> m_resource_id_counter { 1 }; - Atomic<u32> m_context_id_counter { 1 }; + SpinlockProtected<Bitmap> m_active_context_ids { LockRank::None }; LockRefPtr<VirtIOGPU3DDevice> m_3d_device; bool m_has_virgl_support { false }; |