mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 05:47:35 +00:00
Kernel/USB: Make UHCI descriptor pool thread-safe
Right now the TD and QH descriptor pools look to be susceptible to a race condition in the event they are accessed simultaneously by separate threads making USB transfers. This fix does not seem to add any noticeable overhead.
This commit is contained in:
parent
00e13b5b27
commit
6aea13e229
1 changed files with 7 additions and 0 deletions
|
@ -9,6 +9,7 @@
|
||||||
#include <AK/NonnullOwnPtr.h>
|
#include <AK/NonnullOwnPtr.h>
|
||||||
#include <AK/OwnPtr.h>
|
#include <AK/OwnPtr.h>
|
||||||
#include <AK/Stack.h>
|
#include <AK/Stack.h>
|
||||||
|
#include <Kernel/Locking/Spinlock.h>
|
||||||
#include <Kernel/Memory/MemoryManager.h>
|
#include <Kernel/Memory/MemoryManager.h>
|
||||||
#include <Kernel/Memory/Region.h>
|
#include <Kernel/Memory/Region.h>
|
||||||
#include <Kernel/StdLib.h>
|
#include <Kernel/StdLib.h>
|
||||||
|
@ -38,6 +39,8 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] T* try_take_free_descriptor()
|
[[nodiscard]] T* try_take_free_descriptor()
|
||||||
{
|
{
|
||||||
|
SpinlockLocker locker(m_pool_lock);
|
||||||
|
|
||||||
// We're out of descriptors!
|
// We're out of descriptors!
|
||||||
if (m_free_descriptor_stack.is_empty())
|
if (m_free_descriptor_stack.is_empty())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -51,6 +54,8 @@ public:
|
||||||
|
|
||||||
void release_to_pool(T* ptr)
|
void release_to_pool(T* ptr)
|
||||||
{
|
{
|
||||||
|
SpinlockLocker locker(m_pool_lock);
|
||||||
|
|
||||||
dbgln_if(UHCI_VERBOSE_DEBUG, "Returning descriptor @ {} to pool {}", ptr, m_pool_name);
|
dbgln_if(UHCI_VERBOSE_DEBUG, "Returning descriptor @ {} to pool {}", ptr, m_pool_name);
|
||||||
if (!m_free_descriptor_stack.push(ptr))
|
if (!m_free_descriptor_stack.push(ptr))
|
||||||
dbgln("Failed to return descriptor to pool {}. Stack overflow!", m_pool_name);
|
dbgln("Failed to return descriptor to pool {}. Stack overflow!", m_pool_name);
|
||||||
|
@ -78,5 +83,7 @@ private:
|
||||||
StringView m_pool_name; // Name of this pool
|
StringView m_pool_name; // Name of this pool
|
||||||
NonnullOwnPtr<Memory::Region> m_pool_region; // Memory region where descriptors actually reside
|
NonnullOwnPtr<Memory::Region> m_pool_region; // Memory region where descriptors actually reside
|
||||||
Stack<T*, PAGE_SIZE / sizeof(T)> m_free_descriptor_stack; // Stack of currently free descriptor pointers
|
Stack<T*, PAGE_SIZE / sizeof(T)> m_free_descriptor_stack; // Stack of currently free descriptor pointers
|
||||||
|
Spinlock m_pool_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue