diff options
author | Luke <luke.wilde@live.co.uk> | 2021-08-11 22:59:32 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-08-14 21:22:44 +0200 |
commit | 14da080dcfc08953e2a78e95111c32d4d32edcf5 (patch) | |
tree | b38be60a82fd83bdfbb7eb66296bc25b0fa9a0de | |
parent | 1ca5b6caa9f66d01ffb3af953e06f5d9fe9ba732 (diff) | |
download | serenity-14da080dcfc08953e2a78e95111c32d4d32edcf5.zip |
Kernel/USB: Use allocate_kernel_region in Transfer buffer allocations
Previously it would create a contiguous AVMO manually and pass it to
MM. This uses supervisor pages that quickly run out as they never get
returned and crash the system.
Instead, use allocate_kernel_region as we're only allocating a page so
it will be contiguous and will be returned when destroyed.
A potentially better solution would be to use a pool of transfers to
avoid all the allocations. This just prevents the system from crashing
within ~5 seconds from the continuous hub polling.
-rw-r--r-- | Kernel/Bus/USB/USBTransfer.cpp | 16 | ||||
-rw-r--r-- | Kernel/Bus/USB/USBTransfer.h | 14 |
2 files changed, 15 insertions, 15 deletions
diff --git a/Kernel/Bus/USB/USBTransfer.cpp b/Kernel/Bus/USB/USBTransfer.cpp index 82fb695e76..09a0959efb 100644 --- a/Kernel/Bus/USB/USBTransfer.cpp +++ b/Kernel/Bus/USB/USBTransfer.cpp @@ -11,20 +11,20 @@ namespace Kernel::USB { RefPtr<Transfer> Transfer::try_create(Pipe& pipe, u16 len) { - auto vmobject = Memory::AnonymousVMObject::try_create_physically_contiguous_with_size(PAGE_SIZE); - if (!vmobject) - return nullptr; + // Initialize data buffer for transfer + // This will definitely need to be refactored in the future, I doubt this will scale well... + auto data_buffer = MM.allocate_kernel_region(PAGE_SIZE, "USB Transfer Buffer", Memory::Region::Access::ReadWrite); + if (!data_buffer) + return {}; - return AK::try_create<Transfer>(pipe, len, *vmobject); + return AK::try_create<Transfer>(pipe, len, data_buffer.release_nonnull()); } -Transfer::Transfer(Pipe& pipe, u16 len, Memory::AnonymousVMObject& vmobject) +Transfer::Transfer(Pipe& pipe, u16 len, NonnullOwnPtr<Memory::Region> data_buffer) : m_pipe(pipe) + , m_data_buffer(move(data_buffer)) , m_transfer_data_size(len) { - // Initialize data buffer for transfer - // This will definitely need to be refactored in the future, I doubt this will scale well... - m_data_buffer = MM.allocate_kernel_region_with_vmobject(vmobject, PAGE_SIZE, "USB Transfer Buffer", Memory::Region::Access::ReadWrite); } Transfer::~Transfer() diff --git a/Kernel/Bus/USB/USBTransfer.h b/Kernel/Bus/USB/USBTransfer.h index 9afead95e9..298bb38af7 100644 --- a/Kernel/Bus/USB/USBTransfer.h +++ b/Kernel/Bus/USB/USBTransfer.h @@ -23,7 +23,7 @@ public: public: Transfer() = delete; - Transfer(Pipe& pipe, u16 len, Memory::AnonymousVMObject&); + Transfer(Pipe& pipe, u16 len, NonnullOwnPtr<Memory::Region>); ~Transfer(); void set_setup_packet(const USBRequestData& request); @@ -41,11 +41,11 @@ public: bool error_occurred() const { return m_error_occurred; } private: - Pipe& m_pipe; // Pipe that initiated this transfer - USBRequestData m_request; // USB request - OwnPtr<Memory::Region> m_data_buffer; // DMA Data buffer for transaction - u16 m_transfer_data_size { 0 }; // Size of the transfer's data stage - bool m_complete { false }; // Has this transfer been completed? - bool m_error_occurred { false }; // Did an error occur during this transfer? + Pipe& m_pipe; // Pipe that initiated this transfer + USBRequestData m_request; // USB request + NonnullOwnPtr<Memory::Region> m_data_buffer; // DMA Data buffer for transaction + u16 m_transfer_data_size { 0 }; // Size of the transfer's data stage + bool m_complete { false }; // Has this transfer been completed? + bool m_error_occurred { false }; // Did an error occur during this transfer? }; } |