mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 05:37:35 +00:00
Kernel/Storage: Remove NVMeQueue DMA buffer create method
Instead, try to allocate the DMA buffer before trying to construct the NVMeQueue. This allows us to fail early if we can't allocate the DMA buffer before allocating and creating the heavier NVMeQueue object.
This commit is contained in:
parent
0778043d73
commit
fc2c2c8a6d
2 changed files with 11 additions and 15 deletions
|
@ -15,12 +15,14 @@ namespace Kernel {
|
||||||
|
|
||||||
ErrorOr<NonnullRefPtr<NVMeQueue>> NVMeQueue::try_create(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs)
|
ErrorOr<NonnullRefPtr<NVMeQueue>> NVMeQueue::try_create(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs)
|
||||||
{
|
{
|
||||||
auto queue = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) NVMeQueue(qid, irq, q_depth, move(cq_dma_region), cq_dma_page, move(sq_dma_region), sq_dma_page, move(db_regs))));
|
// Note: Allocate DMA region for RW operation. For now the requests don't exceed more than 4096 bytes (Storage device takes care of it)
|
||||||
TRY(queue->create());
|
RefPtr<Memory::PhysicalPage> rw_dma_page;
|
||||||
|
auto rw_dma_region = TRY(MM.allocate_dma_buffer_page("NVMe Queue Read/Write DMA"sv, Memory::Region::Access::ReadWrite, rw_dma_page));
|
||||||
|
auto queue = TRY(adopt_nonnull_ref_or_enomem(new (nothrow) NVMeQueue(move(rw_dma_region), *rw_dma_page, qid, irq, q_depth, move(cq_dma_region), cq_dma_page, move(sq_dma_region), sq_dma_page, move(db_regs))));
|
||||||
return queue;
|
return queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT NVMeQueue::NVMeQueue(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs)
|
UNMAP_AFTER_INIT NVMeQueue::NVMeQueue(NonnullOwnPtr<Memory::Region> rw_dma_region, Memory::PhysicalPage const& rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs)
|
||||||
: IRQHandler(irq)
|
: IRQHandler(irq)
|
||||||
, m_qid(qid)
|
, m_qid(qid)
|
||||||
, m_admin_queue(qid == 0)
|
, m_admin_queue(qid == 0)
|
||||||
|
@ -30,7 +32,9 @@ UNMAP_AFTER_INIT NVMeQueue::NVMeQueue(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memor
|
||||||
, m_cq_dma_page(cq_dma_page)
|
, m_cq_dma_page(cq_dma_page)
|
||||||
, m_sq_dma_region(move(sq_dma_region))
|
, m_sq_dma_region(move(sq_dma_region))
|
||||||
, m_sq_dma_page(sq_dma_page)
|
, m_sq_dma_page(sq_dma_page)
|
||||||
|
, m_rw_dma_region(move(rw_dma_region))
|
||||||
, m_db_regs(move(db_regs))
|
, m_db_regs(move(db_regs))
|
||||||
|
, m_rw_dma_page(rw_dma_page)
|
||||||
, m_current_request(nullptr)
|
, m_current_request(nullptr)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -38,14 +42,6 @@ UNMAP_AFTER_INIT NVMeQueue::NVMeQueue(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memor
|
||||||
m_cqe_array = { reinterpret_cast<NVMeCompletion*>(m_cq_dma_region->vaddr().as_ptr()), m_qdepth };
|
m_cqe_array = { reinterpret_cast<NVMeCompletion*>(m_cq_dma_region->vaddr().as_ptr()), m_qdepth };
|
||||||
}
|
}
|
||||||
|
|
||||||
UNMAP_AFTER_INIT ErrorOr<void> NVMeQueue::create()
|
|
||||||
{
|
|
||||||
// DMA region for RW operation. For now the requests don't exceed more than 4096 bytes(Storage device takes of it)
|
|
||||||
auto buffer = TRY(MM.allocate_dma_buffer_page("NVMe Queue"sv, Memory::Region::Access::ReadWrite, m_rw_dma_page));
|
|
||||||
m_rw_dma_region = move(buffer);
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NVMeQueue::cqe_available()
|
bool NVMeQueue::cqe_available()
|
||||||
{
|
{
|
||||||
return PHASE_TAG(m_cqe_array[m_cq_head].status) == m_cq_valid_phase;
|
return PHASE_TAG(m_cqe_array[m_cq_head].status) == m_cq_valid_phase;
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <AK/NonnullRefPtr.h>
|
||||||
#include <AK/NonnullRefPtrVector.h>
|
#include <AK/NonnullRefPtrVector.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/RefCounted.h>
|
#include <AK/RefCounted.h>
|
||||||
|
@ -30,7 +31,6 @@ class NVMeQueue : public IRQHandler
|
||||||
, public RefCounted<NVMeQueue> {
|
, public RefCounted<NVMeQueue> {
|
||||||
public:
|
public:
|
||||||
static ErrorOr<NonnullRefPtr<NVMeQueue>> try_create(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs);
|
static ErrorOr<NonnullRefPtr<NVMeQueue>> try_create(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs);
|
||||||
ErrorOr<void> create();
|
|
||||||
bool is_admin_queue() { return m_admin_queue; };
|
bool is_admin_queue() { return m_admin_queue; };
|
||||||
void submit_sqe(NVMeSubmission&);
|
void submit_sqe(NVMeSubmission&);
|
||||||
u16 submit_sync_sqe(NVMeSubmission&);
|
u16 submit_sync_sqe(NVMeSubmission&);
|
||||||
|
@ -40,7 +40,7 @@ public:
|
||||||
void disable_interrupts() { disable_irq(); };
|
void disable_interrupts() { disable_irq(); };
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NVMeQueue(u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs);
|
NVMeQueue(NonnullOwnPtr<Memory::Region> rw_dma_region, Memory::PhysicalPage const& rw_dma_page, u16 qid, u8 irq, u32 q_depth, OwnPtr<Memory::Region> cq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> cq_dma_page, OwnPtr<Memory::Region> sq_dma_region, NonnullRefPtrVector<Memory::PhysicalPage> sq_dma_page, Memory::TypedMapping<volatile DoorbellRegister> db_regs);
|
||||||
|
|
||||||
virtual bool handle_irq(const RegisterState&) override;
|
virtual bool handle_irq(const RegisterState&) override;
|
||||||
|
|
||||||
|
@ -73,9 +73,9 @@ private:
|
||||||
OwnPtr<Memory::Region> m_sq_dma_region;
|
OwnPtr<Memory::Region> m_sq_dma_region;
|
||||||
NonnullRefPtrVector<Memory::PhysicalPage> m_sq_dma_page;
|
NonnullRefPtrVector<Memory::PhysicalPage> m_sq_dma_page;
|
||||||
Span<NVMeCompletion> m_cqe_array;
|
Span<NVMeCompletion> m_cqe_array;
|
||||||
OwnPtr<Memory::Region> m_rw_dma_region;
|
NonnullOwnPtr<Memory::Region> m_rw_dma_region;
|
||||||
Memory::TypedMapping<volatile DoorbellRegister> m_db_regs;
|
Memory::TypedMapping<volatile DoorbellRegister> m_db_regs;
|
||||||
RefPtr<Memory::PhysicalPage> m_rw_dma_page;
|
NonnullRefPtr<Memory::PhysicalPage> m_rw_dma_page;
|
||||||
Spinlock m_request_lock;
|
Spinlock m_request_lock;
|
||||||
RefPtr<AsyncBlockDeviceRequest> m_current_request;
|
RefPtr<AsyncBlockDeviceRequest> m_current_request;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue