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--;` :^)
This commit is contained in:
parent
6d67cb516a
commit
1b5a565e55
Notes:
sideshowbarker
2024-07-17 09:56:35 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/1b5a565e55 Pull-request: https://github.com/SerenityOS/serenity/pull/16394 Reviewed-by: https://github.com/bgianfo Reviewed-by: https://github.com/ccapitalK Reviewed-by: https://github.com/linusg Reviewed-by: https://github.com/supercomputer7
3 changed files with 32 additions and 13 deletions
|
@ -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 {};
|
||||
|
|
|
@ -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>();
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue