1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 15:17:36 +00:00

Kernel: Allow WorkQueue items allocation failures propagation

In most cases it's safe to abort the requested operation and go forward,
however, in some places it's not clear yet how to handle these failures,
therefore, we use the MUST() wrapper to force a kernel panic for now.
This commit is contained in:
Liav A 2022-03-06 22:07:04 +02:00 committed by Linus Groh
parent 02566d8091
commit 1462211ccf
9 changed files with 75 additions and 19 deletions

View file

@ -70,13 +70,23 @@ void AHCIPort::handle_interrupt()
if ((m_port_registers.ssts & 0xf) != 3 && m_connected_device) {
m_connected_device->prepare_for_unplug();
StorageManagement::the().remove_device(*m_connected_device);
g_io_work->queue([this]() {
auto work_item_creation_result = g_io_work->try_queue([this]() {
m_connected_device.clear();
});
if (work_item_creation_result.is_error()) {
auto current_request = m_current_request;
m_current_request.clear();
current_request->complete(AsyncDeviceRequest::OutOfMemory);
}
} else {
g_io_work->queue([this]() {
auto work_item_creation_result = g_io_work->try_queue([this]() {
reset();
});
if (work_item_creation_result.is_error()) {
auto current_request = m_current_request;
m_current_request.clear();
current_request->complete(AsyncDeviceRequest::OutOfMemory);
}
}
return;
}
@ -86,15 +96,25 @@ void AHCIPort::handle_interrupt()
if (m_interrupt_status.is_set(AHCI::PortInterruptFlag::INF)) {
// We need to defer the reset, because we can receive interrupts when
// resetting the device.
g_io_work->queue([this]() {
auto work_item_creation_result = g_io_work->try_queue([this]() {
reset();
});
if (work_item_creation_result.is_error()) {
auto current_request = m_current_request;
m_current_request.clear();
current_request->complete(AsyncDeviceRequest::OutOfMemory);
}
return;
}
if (m_interrupt_status.is_set(AHCI::PortInterruptFlag::IF) || m_interrupt_status.is_set(AHCI::PortInterruptFlag::TFE) || m_interrupt_status.is_set(AHCI::PortInterruptFlag::HBD) || m_interrupt_status.is_set(AHCI::PortInterruptFlag::HBF)) {
g_io_work->queue([this]() {
auto work_item_creation_result = g_io_work->try_queue([this]() {
recover_from_fatal_error();
});
if (work_item_creation_result.is_error()) {
auto current_request = m_current_request;
m_current_request.clear();
current_request->complete(AsyncDeviceRequest::OutOfMemory);
}
return;
}
if (m_interrupt_status.is_set(AHCI::PortInterruptFlag::DHR) || m_interrupt_status.is_set(AHCI::PortInterruptFlag::PS)) {
@ -106,7 +126,7 @@ void AHCIPort::handle_interrupt()
if (!m_current_request) {
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Request handled, probably identify request", representative_port_index());
} else {
g_io_work->queue([this]() {
auto work_item_creation_result = g_io_work->try_queue([this]() {
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Request handled", representative_port_index());
MutexLocker locker(m_lock);
VERIFY(m_current_request);
@ -128,6 +148,11 @@ void AHCIPort::handle_interrupt()
dbgln_if(AHCI_DEBUG, "AHCI Port {}: Request success", representative_port_index());
complete_current_request(AsyncDeviceRequest::Success);
});
if (work_item_creation_result.is_error()) {
auto current_request = m_current_request;
m_current_request.clear();
current_request->complete(AsyncDeviceRequest::OutOfMemory);
}
}
}