Skip to content

Commit

Permalink
USB: Acquire the device manager lock before Explore.
Browse files Browse the repository at this point in the history
We must do this to prevent lock order inversion: when busses are
initialized, they are started by the (locked) device manager, and
then acquire the explore lock. We must do the same in Explore itself,
for when called by the explore thread, we would otherwise first acquire
the explore lock, then (when publishing new nodes) acquire the device lock.

Should fix #18421 and #18393.
  • Loading branch information
waddlesplash committed May 31, 2023
1 parent bd90416 commit 0450e7b
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 0 deletions.
3 changes: 3 additions & 0 deletions headers/private/kernel/kdevice_manager.h
Expand Up @@ -7,6 +7,7 @@


#include <device_manager.h>
#include <lock.h>

struct kernel_args;

Expand All @@ -21,6 +22,8 @@ status_t device_manager_probe(const char *path, uint32 updateCycle);
status_t device_manager_init(struct kernel_args *args);
status_t device_manager_init_post_modules(struct kernel_args *args);

recursive_lock* device_manager_get_lock();

#ifdef __cplusplus
}
#endif
Expand Down
6 changes: 6 additions & 0 deletions src/add-ons/kernel/bus_managers/usb/Stack.cpp
Expand Up @@ -11,10 +11,13 @@
#include <module.h>
#include <unistd.h>
#include <util/kernel_cpp.h>
#include <util/AutoLock.h>

#include "usb_private.h"
#include "PhysicalMemoryAllocator.h"

#include <fs/devfs.h>
#include <kdevice_manager.h>


Stack::Stack()
Expand Down Expand Up @@ -214,6 +217,9 @@ Stack::ExploreThread(void *data)
void
Stack::Explore()
{
// Acquire the device manager lock before the explore lock, to prevent lock-order inversion.
RecursiveLocker dmLocker(device_manager_get_lock());

if (mutex_lock(&fExploreLock) != B_OK)
return;

Expand Down
7 changes: 7 additions & 0 deletions src/system/kernel/device_manager/device_manager.cpp
Expand Up @@ -2489,3 +2489,10 @@ device_manager_init_post_modules(struct kernel_args* args)
RecursiveLocker _(sLock);
return sRootNode->Reprobe();
}


recursive_lock*
device_manager_get_lock()
{
return &sLock;
}

0 comments on commit 0450e7b

Please sign in to comment.