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;
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #10
0
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;
}