static int __init ModInit(void) { int rc; if (!commOSModInit) { CommOS_Log(("%s: Can't find \'init\' function for module \'" COMM_OS_MOD_SHORT_NAME_STRING "\'.\n", __func__)); return -1; } CommOS_Debug(("%s: Module parameters: [%s].\n", __func__, modParams)); rc = (*commOSModInit)(modParams); if (rc == 0) CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING "\' has been successfully initialized.\n", __func__)); else CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING "\' could not be initialized [%d].\n", __func__, rc)); return rc > 0 ? -rc : rc; }
static int Halt(void) { unsigned int maxTries = 10; int rc = -1; if (!running) { rc = 0; goto out; } for ( ; maxTries; maxTries--) { unsigned long long timeout = 2000ULL; CommOS_Debug(("%s: Attempting to halt...\n", __FUNCTION__)); if (!Comm_Finish(&timeout)) { running = 0; rc = 0; break; } } out: return rc; }
static int CommOSModStart(void) { int rc; /* Comm is initialized. Called with modules_lock taken. */ commOSModStart = NULL; if (!commOSModInit) { CommOS_Log(("%s: Can't find \'init\' function for module \'" \ COMM_OS_MOD_SHORT_NAME_STRING "\'.\n", __FUNCTION__)); return -1; } CommOS_Debug(("%s: Module parameters: [%s].\n", __FUNCTION__, modParams)); rc = (*commOSModInit)(modParams); if (rc == 0) { CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \ "\' has been successfully initialized.\n", __FUNCTION__)); } else { CommOS_Log(("%s: Module \'" COMM_OS_MOD_SHORT_NAME_STRING \ "\' could not be initialized [%d].\n", __FUNCTION__, rc)); } return rc > 0 ? -rc : rc; }
static int ExitCondition(void *arg1, void *arg2) { unsigned int i; int rc; (void)arg1; (void)arg2; CommOS_Debug(("%s: running [%d] " "commChannelAllocated [%u] commChannelSize [%u].\n", __FUNCTION__, running, commChannelAllocated, commChannelSize)); rc = !running && (commChannelAllocated == 0); if (!rc) { for (i = 0; i < commChannelCapacity; i++) { CommOS_Debug(("%s: channel[%u] state [0x%x].\n", __FUNCTION__, i, commChannels[i].lifecycleState)); } } return rc; }
static int DefaultTranspListener(CommTranspInitArgs *transpArgs, void *probeData) { int rc = -1; const int inBH = 1; const CommImpl *impl; if (!transpArgs || !probeData) { CommOS_Debug(("%s: NULL args [0x%p, 0x%p].\n", __FUNCTION__, transpArgs, probeData)); goto out; } impl = probeData; CommOS_Debug(("%s: Received attach info [%u,%u,%u:%u].\n", __FUNCTION__, transpArgs->capacity, transpArgs->type, transpArgs->id.d32[0], transpArgs->id.d32[1])); if (impl->checkArgs(transpArgs)) { goto out; } transpArgs->mode = COMM_TRANSP_INIT_ATTACH; /* Ensure we attach. */ /* We recognized it, so don't let others waste any time. Even if we fail. */ rc = 0; if (Comm_Alloc(transpArgs, impl, inBH, NULL)) { impl->closeNtf(impl->closeNtfData, transpArgs, inBH); CommOS_Log(("%s: Can't allocate new channel!\n", __FUNCTION__)); } out: return rc; }
static void DestroyTransp(CommTransp transp) { CommTranspID transpID; int32 rc; if (!transp) { CommOS_Debug(("Failed to close channel: Bad handle\n")); return; } CommOS_Log(("%s: Detaching channel [%u:%u]\n", __FUNCTION__, transp->qp->id.context, transp->qp->id.resource)); transpID.d32[0] = transp->qp->id.context; transpID.d32[1] = transp->qp->id.resource; #if !defined(COMM_BUILDING_SERVER) /* * Tell the host to detach, will block in the host * until the host has unmapped memory. Once the * host has unmapped, it is safe to free. */ CommTranspEvent_Raise(transp->peerEvID, &transpID, COMM_TRANSP_IO_DETACH); #endif rc = QP_Detach(transp->qp); #if defined(COMM_BUILDING_SERVER) /* * Wake up waiters now that unmapping is complete */ CommOS_WakeUp(&transpTable[transp->backRef].wq); #endif CommOS_Kfree(transp); if (rc != QP_SUCCESS) { CommOS_Log(("%s: Failed to detach. rc: %d\n", __FUNCTION__, rc)); } else { CommOS_Log(("%s: Channel detached.\n", __FUNCTION__)); } }
static int Init(void *argsIn) { int rc = -1; unsigned int maxChannels = 8; /* * On the host side, infinite timeout. 1 polling cycle. * see kernel/time.c: msecs_to_jiffies() */ #if defined(COMM_BUILDING_SERVER) unsigned int pollingMillis = (unsigned int)-1; #else unsigned int pollingMillis = 2000; #endif unsigned int pollingCycles = 1; const char *args = argsIn; if (args && *args) { /* coverity[secure_coding] */ sscanf(args, "max_channels:%u,poll_millis:%u,poll_cycles:%u", &maxChannels, &pollingMillis, &pollingCycles); CommOS_Debug(("%s: arguments [%s].\n", __FUNCTION__, args)); } rc = Comm_Init(maxChannels); if (rc) { goto out; } rc = CommOS_StartIO(COMM_OS_MOD_SHORT_NAME_STRING "-disp", Comm_DispatchAll, pollingMillis, pollingCycles, COMM_OS_MOD_SHORT_NAME_STRING "-aio"); if (rc) { unsigned long long timeout = 0; Comm_Finish(&timeout); /* Nothing started, guaranteed to succeed. */ goto out; } running = 1; rc = 0; out: return rc; }
static int Init(void *argsIn) { int rc = -1; unsigned int maxChannels = 8; #if defined(COMM_BUILDING_SERVER) unsigned int pollingMillis = (unsigned int)-1; #else unsigned int pollingMillis = 2000; #endif unsigned int pollingCycles = 1; const char *args = argsIn; if (args && *args) { sscanf(args, "max_channels:%u,poll_millis:%u,poll_cycles:%u", &maxChannels, &pollingMillis, &pollingCycles); CommOS_Debug(("%s: arguments [%s].\n", __FUNCTION__, args)); } rc = Comm_Init(maxChannels); if (rc) { goto out; } rc = CommOS_StartIO(COMM_OS_MOD_SHORT_NAME_STRING "-disp", Comm_DispatchAll, pollingMillis, pollingCycles, COMM_OS_MOD_SHORT_NAME_STRING "-aio"); if (rc) { unsigned long long timeout = 0; Comm_Finish(&timeout); goto out; } running = 1; rc = 0; out: return rc; }
static inline CommTransp TranspTableGet(CommTranspID *id) { CommTransp transp; uint32 i; if (!id) return NULL; for (i = 0; i < QP_MAX_QUEUE_PAIRS; i++) { transp = transpTable[i].transp; if (transp && (transp->qp->id.context == id->d32[0]) && (transp->qp->id.resource == id->d32[1])) { CommOS_AddReturnAtomic(&transpTable[i].holds, 1); return transp; } } CommOS_Debug(("%s: couldn't find transport object\n", __func__)); return NULL; }
static void DestroyTransp(CommTransp transp) { CommTranspID transpID; int32 rc; if (!transp) { CommOS_Debug(("Failed to close channel: Bad handle\n")); return; } CommOS_Log(("%s: Detaching channel [%u:%u]\n", __FUNCTION__, transp->qp->id.context, transp->qp->id.resource)); transpID.d32[0] = transp->qp->id.context; transpID.d32[1] = transp->qp->id.resource; #if !defined(COMM_BUILDING_SERVER) CommTranspEvent_Raise(transp->peerEvID, &transpID, COMM_TRANSP_IO_DETACH); #endif rc = QP_Detach(transp->qp); #if defined(COMM_BUILDING_SERVER) CommOS_WakeUp(&transpTable[transp->backRef].wq); #endif CommOS_Kfree(transp); if (rc != QP_SUCCESS) { CommOS_Log(("%s: Failed to detach. rc: %d\n", __FUNCTION__, rc)); } else { CommOS_Log(("%s: Channel detached.\n", __FUNCTION__)); } }
int CommOS_StartIO(const char *dispatchTaskName, CommOSDispatchFunc dispatchFunc, unsigned int intervalMillis, unsigned int maxCycles, const char *aioTaskName) { int rc; int cpu; if (running) { CommOS_Debug(("%s: I/O tasks already running.\n", __FUNCTION__)); return 0; } if (!dispatchFunc) { CommOS_Log(("%s: a NULL Dispatch handler was passed.\n", __FUNCTION__)); return -1; } dispatch = dispatchFunc; if (intervalMillis == 0) { intervalMillis = 4; } if ((dispatchInterval = msecs_to_jiffies(intervalMillis)) < 1) { dispatchInterval = 1; } if (maxCycles > DISPATCH_MAX_CYCLES) { dispatchMaxCycles = DISPATCH_MAX_CYCLES; } else if (maxCycles > 0) { dispatchMaxCycles = maxCycles; } CommOS_Debug(("%s: Interval millis %u (jif:%u).\n", __FUNCTION__, intervalMillis, dispatchInterval)); CommOS_Debug(("%s: Max cycles %u.\n", __FUNCTION__, dispatchMaxCycles)); numCpus = num_present_cpus(); dispatchWQ = CreateWorkqueue(dispatchTaskName); if (!dispatchWQ) { CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__, dispatchTaskName)); return -1; } if (aioTaskName) { aioWQ = CreateWorkqueue(aioTaskName); if (!aioWQ) { CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__, aioTaskName)); DestroyWorkqueue(dispatchWQ); return -1; } } else { aioWQ = NULL; } running = 1; for (cpu = 0; cpu < numCpus; cpu++) { CommOS_InitWork(&dispatchWorksNow[cpu], DispatchWrapper); CommOS_InitWork(&dispatchWorks[cpu], DispatchWrapper); rc = QueueDelayedWorkOn(cpu, dispatchWQ, &dispatchWorks[cpu], dispatchInterval); if (rc != 0) { CommOS_StopIO(); return -1; } } CommOS_Log(("%s: Created I/O task(s) successfully.\n", __FUNCTION__)); return 0; }
int CommOS_StartIO(const char *dispatchTaskName, // IN CommOSDispatchFunc dispatchFunc, // IN unsigned int intervalMillis, // IN unsigned int maxCycles, // IN const char *aioTaskName) // IN { int cpu; if (running) { CommOS_Debug(("%s: I/O tasks already running.\n", __FUNCTION__)); return 0; } /* * OK, let's test the handler against NULL. Though, the whole concept * of checking for NULL pointers, outside cases where NULL is meaningful * to the implementation, is relatively useless: garbage, random pointers * rarely happen to be all-zeros. */ if (!dispatchFunc) { CommOS_Log(("%s: a NULL Dispatch handler was passed.\n", __FUNCTION__)); return -1; } dispatch = dispatchFunc; if (intervalMillis == 0) { intervalMillis = 4; } if ((dispatchInterval = msecs_to_jiffies(intervalMillis)) < 1) { dispatchInterval = 1; } if (maxCycles > DISPATCH_MAX_CYCLES) { dispatchMaxCycles = DISPATCH_MAX_CYCLES; } else if (maxCycles > 0) { dispatchMaxCycles = maxCycles; } CommOS_Debug(("%s: Interval millis %u (jif:%u).\n", __FUNCTION__, intervalMillis, dispatchInterval)); CommOS_Debug(("%s: Max cycles %u.\n", __FUNCTION__, dispatchMaxCycles)); dispatchWQ = CreateWorkqueue(dispatchTaskName); if (!dispatchWQ) { CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__, dispatchTaskName)); return -1; } if (aioTaskName) { aioWQ = CreateWorkqueue(aioTaskName); if (!aioWQ) { CommOS_Log(("%s: Couldn't create %s task(s).\n", __FUNCTION__, aioTaskName)); DestroyWorkqueue(dispatchWQ); return -1; } } else { aioWQ = NULL; } running = 1; for_each_possible_cpu(cpu) { CommOS_InitWork(&dispatchWorksNow[cpu], DispatchWrapper); CommOS_InitWork(&dispatchWorks[cpu], DispatchWrapper); } #ifdef CONFIG_HOTPLUG_CPU register_hotcpu_notifier(&CpuNotifier); #endif get_online_cpus(); for_each_online_cpu(cpu) { QueueDelayedWorkOn(cpu, dispatchWQ, &dispatchWorks[cpu], dispatchInterval); } put_online_cpus(); CommOS_Log(("%s: Created I/O task(s) successfully.\n", __FUNCTION__)); return 0; }