1*1249c01aSStefan Metzmacher // SPDX-License-Identifier: GPL-2.0-or-later 2*1249c01aSStefan Metzmacher /* 3*1249c01aSStefan Metzmacher * Copyright (c) 2025, Stefan Metzmacher 4*1249c01aSStefan Metzmacher */ 5*1249c01aSStefan Metzmacher 6*1249c01aSStefan Metzmacher #include "internal.h" 7*1249c01aSStefan Metzmacher #include <linux/module.h> 8*1249c01aSStefan Metzmacher 9*1249c01aSStefan Metzmacher struct smbdirect_module_state smbdirect_globals = { 10*1249c01aSStefan Metzmacher .mutex = __MUTEX_INITIALIZER(smbdirect_globals.mutex), 11*1249c01aSStefan Metzmacher }; 12*1249c01aSStefan Metzmacher 13*1249c01aSStefan Metzmacher static __init int smbdirect_module_init(void) 14*1249c01aSStefan Metzmacher { 15*1249c01aSStefan Metzmacher int ret = -ENOMEM; 16*1249c01aSStefan Metzmacher 17*1249c01aSStefan Metzmacher pr_notice("subsystem loading...\n"); 18*1249c01aSStefan Metzmacher mutex_lock(&smbdirect_globals.mutex); 19*1249c01aSStefan Metzmacher 20*1249c01aSStefan Metzmacher smbdirect_globals.workqueues.accept = alloc_workqueue("smbdirect-accept", 21*1249c01aSStefan Metzmacher WQ_SYSFS | 22*1249c01aSStefan Metzmacher WQ_PERCPU | 23*1249c01aSStefan Metzmacher WQ_POWER_EFFICIENT, 24*1249c01aSStefan Metzmacher 0); 25*1249c01aSStefan Metzmacher if (smbdirect_globals.workqueues.accept == NULL) 26*1249c01aSStefan Metzmacher goto alloc_accept_wq_failed; 27*1249c01aSStefan Metzmacher 28*1249c01aSStefan Metzmacher smbdirect_globals.workqueues.connect = alloc_workqueue("smbdirect-connect", 29*1249c01aSStefan Metzmacher WQ_SYSFS | 30*1249c01aSStefan Metzmacher WQ_PERCPU | 31*1249c01aSStefan Metzmacher WQ_POWER_EFFICIENT, 32*1249c01aSStefan Metzmacher 0); 33*1249c01aSStefan Metzmacher if (smbdirect_globals.workqueues.connect == NULL) 34*1249c01aSStefan Metzmacher goto alloc_connect_wq_failed; 35*1249c01aSStefan Metzmacher 36*1249c01aSStefan Metzmacher smbdirect_globals.workqueues.idle = alloc_workqueue("smbdirect-idle", 37*1249c01aSStefan Metzmacher WQ_SYSFS | 38*1249c01aSStefan Metzmacher WQ_PERCPU | 39*1249c01aSStefan Metzmacher WQ_POWER_EFFICIENT, 40*1249c01aSStefan Metzmacher 0); 41*1249c01aSStefan Metzmacher if (smbdirect_globals.workqueues.idle == NULL) 42*1249c01aSStefan Metzmacher goto alloc_idle_wq_failed; 43*1249c01aSStefan Metzmacher 44*1249c01aSStefan Metzmacher smbdirect_globals.workqueues.refill = alloc_workqueue("smbdirect-refill", 45*1249c01aSStefan Metzmacher WQ_HIGHPRI | 46*1249c01aSStefan Metzmacher WQ_SYSFS | 47*1249c01aSStefan Metzmacher WQ_PERCPU | 48*1249c01aSStefan Metzmacher WQ_POWER_EFFICIENT, 49*1249c01aSStefan Metzmacher 0); 50*1249c01aSStefan Metzmacher if (smbdirect_globals.workqueues.refill == NULL) 51*1249c01aSStefan Metzmacher goto alloc_refill_wq_failed; 52*1249c01aSStefan Metzmacher 53*1249c01aSStefan Metzmacher smbdirect_globals.workqueues.immediate = alloc_workqueue("smbdirect-immediate", 54*1249c01aSStefan Metzmacher WQ_HIGHPRI | 55*1249c01aSStefan Metzmacher WQ_SYSFS | 56*1249c01aSStefan Metzmacher WQ_PERCPU | 57*1249c01aSStefan Metzmacher WQ_POWER_EFFICIENT, 58*1249c01aSStefan Metzmacher 0); 59*1249c01aSStefan Metzmacher if (smbdirect_globals.workqueues.immediate == NULL) 60*1249c01aSStefan Metzmacher goto alloc_immediate_wq_failed; 61*1249c01aSStefan Metzmacher 62*1249c01aSStefan Metzmacher smbdirect_globals.workqueues.cleanup = alloc_workqueue("smbdirect-cleanup", 63*1249c01aSStefan Metzmacher WQ_MEM_RECLAIM | 64*1249c01aSStefan Metzmacher WQ_HIGHPRI | 65*1249c01aSStefan Metzmacher WQ_SYSFS | 66*1249c01aSStefan Metzmacher WQ_PERCPU | 67*1249c01aSStefan Metzmacher WQ_POWER_EFFICIENT, 68*1249c01aSStefan Metzmacher 0); 69*1249c01aSStefan Metzmacher if (smbdirect_globals.workqueues.cleanup == NULL) 70*1249c01aSStefan Metzmacher goto alloc_cleanup_wq_failed; 71*1249c01aSStefan Metzmacher 72*1249c01aSStefan Metzmacher ret = smbdirect_devices_init(); 73*1249c01aSStefan Metzmacher if (ret) 74*1249c01aSStefan Metzmacher goto devices_init_failed; 75*1249c01aSStefan Metzmacher 76*1249c01aSStefan Metzmacher mutex_unlock(&smbdirect_globals.mutex); 77*1249c01aSStefan Metzmacher pr_notice("subsystem loaded\n"); 78*1249c01aSStefan Metzmacher return 0; 79*1249c01aSStefan Metzmacher 80*1249c01aSStefan Metzmacher devices_init_failed: 81*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.cleanup); 82*1249c01aSStefan Metzmacher alloc_cleanup_wq_failed: 83*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.immediate); 84*1249c01aSStefan Metzmacher alloc_immediate_wq_failed: 85*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.refill); 86*1249c01aSStefan Metzmacher alloc_refill_wq_failed: 87*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.idle); 88*1249c01aSStefan Metzmacher alloc_idle_wq_failed: 89*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.connect); 90*1249c01aSStefan Metzmacher alloc_connect_wq_failed: 91*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.accept); 92*1249c01aSStefan Metzmacher alloc_accept_wq_failed: 93*1249c01aSStefan Metzmacher mutex_unlock(&smbdirect_globals.mutex); 94*1249c01aSStefan Metzmacher pr_crit("failed to loaded: %d (%1pe)\n", 95*1249c01aSStefan Metzmacher ret, SMBDIRECT_DEBUG_ERR_PTR(ret)); 96*1249c01aSStefan Metzmacher return ret; 97*1249c01aSStefan Metzmacher } 98*1249c01aSStefan Metzmacher 99*1249c01aSStefan Metzmacher static __exit void smbdirect_module_exit(void) 100*1249c01aSStefan Metzmacher { 101*1249c01aSStefan Metzmacher pr_notice("subsystem unloading...\n"); 102*1249c01aSStefan Metzmacher mutex_lock(&smbdirect_globals.mutex); 103*1249c01aSStefan Metzmacher 104*1249c01aSStefan Metzmacher smbdirect_devices_exit(); 105*1249c01aSStefan Metzmacher 106*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.accept); 107*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.connect); 108*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.idle); 109*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.refill); 110*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.immediate); 111*1249c01aSStefan Metzmacher destroy_workqueue(smbdirect_globals.workqueues.cleanup); 112*1249c01aSStefan Metzmacher 113*1249c01aSStefan Metzmacher mutex_unlock(&smbdirect_globals.mutex); 114*1249c01aSStefan Metzmacher pr_notice("subsystem unloaded\n"); 115*1249c01aSStefan Metzmacher } 116*1249c01aSStefan Metzmacher 117*1249c01aSStefan Metzmacher module_init(smbdirect_module_init); 118*1249c01aSStefan Metzmacher module_exit(smbdirect_module_exit); 119*1249c01aSStefan Metzmacher 120*1249c01aSStefan Metzmacher MODULE_DESCRIPTION("smbdirect subsystem"); 121*1249c01aSStefan Metzmacher MODULE_LICENSE("GPL"); 122