kernel/socket: Refactor {get|put}_stack_interface_module and keep it loaded.

* Make the consumer-count int32 atomic, avoiding the need for
   all get/put operations to go through a global lock.

 * Disable the code that unloads the stack interface when there
   are no consumers. Otherwise, we wind up repeatedly loading/
   unloading the stack interface during the boot process (e.g.
   while sockets are being created and destroyed during net_server
   startup.)

   In the future, if we want to really unload it, we can add some
   interaction with low_resource_monitor or something like that.

Reduces register_domain call count during boot from 31 to 7
(it appears the stack was loaded and unloaded 5 times, before
it stayed loaded the 6th.)
This commit is contained in:
Augustin Cavalier 2024-05-27 19:45:57 -04:00
parent 757031348e
commit 61eed15db9

View File

@ -42,26 +42,34 @@
static net_stack_interface_module_info* sStackInterface = NULL;
static vint32 sStackInterfaceInitialized = 0;
static mutex sLock = MUTEX_INITIALIZER("stack interface");
static int32 sStackInterfaceConsumers = 0;
static rw_lock sLock = RW_LOCK_INITIALIZER("stack interface");
static net_stack_interface_module_info*
get_stack_interface_module()
{
MutexLocker _(sLock);
atomic_add(&sStackInterfaceConsumers, 1);
if (sStackInterfaceInitialized++ == 0) {
// load module
net_stack_interface_module_info* module;
// TODO: Add driver settings option to load the userland net stack.
status_t error = get_module(NET_STACK_INTERFACE_MODULE_NAME,
(module_info**)&module);
if (error == B_OK)
sStackInterface = module;
else
sStackInterface = NULL;
}
ReadLocker readLocker(sLock);
if (sStackInterface != NULL)
return sStackInterface;
readLocker.Unlock();
WriteLocker writeLocker(sLock);
if (sStackInterface != NULL)
return sStackInterface;
// load module
net_stack_interface_module_info* module;
// TODO: Add driver settings option to load the userland net stack.
status_t error = get_module(NET_STACK_INTERFACE_MODULE_NAME,
(module_info**)&module);
if (error == B_OK)
sStackInterface = module;
if (sStackInterface == NULL)
atomic_add(&sStackInterfaceConsumers, -1);
return sStackInterface;
}
@ -70,10 +78,19 @@ get_stack_interface_module()
static void
put_stack_interface_module()
{
MutexLocker _(sLock);
if (atomic_add(&sStackInterfaceConsumers, -1) != 1)
return;
if (sStackInterfaceInitialized-- == 1)
put_module(NET_STACK_INTERFACE_MODULE_NAME);
#if 0 /* Just leave the stack loaded, for now. */
WriteLocker _(sLock);
if (atomic_get(&sStackInterfaceConsumers) > 0)
return;
if (sStackInterface == NULL)
return;
put_module(NET_STACK_INTERFACE_MODULE_NAME);
sStackInterface = NULL;
#endif
}