From 61eed15db94ecbe4d2c67e2acb3ff368146a7b4c Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Mon, 27 May 2024 19:45:57 -0400 Subject: [PATCH] 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.) --- src/system/kernel/fs/socket.cpp | 51 ++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/system/kernel/fs/socket.cpp b/src/system/kernel/fs/socket.cpp index 890ec35288..1fc0066d6c 100644 --- a/src/system/kernel/fs/socket.cpp +++ b/src/system/kernel/fs/socket.cpp @@ -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 }