Example #1
0
/*
 * reserving context inserts it into the hash table if !hashed
 * and increments reference count
*/
Status_t
sa_cntxt_reserve( sa_cntxt_t* sa_cntxt )
{
	int         bucket;
	Status_t	status;

	IB_ENTER( "sa_cntxt_reserve", sa_cntxt, 0, 0, 0 );

    if ((status = vs_lock(&sa_cntxt_lock)) != VSTATUS_OK) {
        IB_LOG_ERRORRC("sa_cntxt_reserve: Failed to lock SA context rc:", status);
    } else {
        sa_cntxt->ref ++;
        if( sa_cntxt->hashed == 0 ) {
            // This context needs to be inserted into the hash table
            bucket = sa_cntxt->lid % SA_CNTXT_HASH_TABLE_DEPTH;
            sa_cntxt->hashed = 1 ;
            vs_time_get( &sa_cntxt->tstamp );
            sa_cntxt_insert_head( sa_hash[ bucket ], sa_cntxt );
        }
        if ((status = vs_unlock(&sa_cntxt_lock)) != VSTATUS_OK) {
            IB_LOG_ERRORRC("sa_cntxt_reserve: Failed to unlock SA context rc:", status);
        }
    }

	IB_EXIT( "sa_cntxt_reserve", VSTATUS_OK );
	return VSTATUS_OK ;
}
Example #2
0
/*
 * Age context and do resends for those that timed out
 */
void sa_cntxt_age(void)
{
	sa_cntxt_t* sa_cntxt = NULL ;
	sa_cntxt_t*	tout_cntxt ;
    int i;
	Status_t	status;

    if ((status = vs_lock(&sa_cntxt_lock)) != VSTATUS_OK) {
        IB_LOG_ERRORRC("sa_cntxt_age: Failed to lock SA context rc:", status);
    } else {
        vs_time_get( &timeLastAged );
        for (i=0; i<SA_CNTXT_HASH_TABLE_DEPTH; i++) {
            sa_cntxt = sa_hash[ i ];
            while( sa_cntxt ) {
                // Iterate before the pointers are destroyed ;
                tout_cntxt = sa_cntxt ;
                sa_cntxt = sa_cntxt->next ;

                // Though list is sorted, it does not hurt to 
                // do a simple comparison
                if( timeLastAged - tout_cntxt->tstamp > tout_cntxt->RespTimeout) { // used to be VTIMER_1S
                    // Timeout this entry
                    sa_cntxt_delete_entry( sa_hash[ i ], tout_cntxt );
                    sa_cntxt_insert_head( sa_hash[ i ], tout_cntxt );
                    // Touch the entry
                    tout_cntxt->tstamp = timeLastAged ;
                    // Call timeout
                    tout_cntxt->sendFd = fd_sa_w;       // use sa writer mai handle for restransmits
                    if (tout_cntxt->method == SA_CM_GETMULTI && tout_cntxt->reqInProg) {
                        // resend the getMulti request ACK
                        sa_getMulti_resend_ack(tout_cntxt);
                        /* if need to release the context.  Call local safe release */
                        if( tout_cntxt->retries > sm_config.max_retries ) cntxt_release(sa_cntxt);
                    } else {
                        // resend the reply
                        sa_send_reply( NULL, tout_cntxt );
                        if( tout_cntxt->retries > sm_config.max_retries ) {
                            /* need to release the context.  Call local safe release */
                            cntxt_release(tout_cntxt);
                        }
                    }
                }
            }
        }
        if ((status = vs_unlock(&sa_cntxt_lock)) != VSTATUS_OK) {
            IB_LOG_ERRORRC("cs_cntxt_age: Failed to unlock SA context rc:", status);
        }
    }
}
Example #3
0
int bitset_resize(bitset_t *bitset, size_t n) {
    Status_t	status;
	size_t orig_nbits = bitset->nbits_m;
	size_t orig_nset = bitset->nset_m;
	size_t orig_nwords = bitset->nwords_m;
	uint32_t *orig_bits = bitset->bits_m;

	if (n == bitset->nbits_m) return 1;

	bitset->bits_m = NULL;

	if (!bitset_init(bitset->pool_m, bitset, n)) {
		bitset->nbits_m = orig_nbits;
		bitset->nset_m = orig_nset;
		bitset->nwords_m = orig_nwords;
		bitset->bits_m = orig_bits;
		return 0;
	}

	if (!orig_bits) return 1;

	if (n > orig_nbits) {
		memcpy(bitset->bits_m, orig_bits, orig_nwords*sizeof(uint32_t));
		bitset->nset_m = orig_nset;
	} else {
		memcpy(bitset->bits_m, orig_bits, bitset->nwords_m*sizeof(uint32_t));
		bitset->nset_m = count_nset(bitset);
	}

	if ((status = vs_pool_free(bitset->pool_m, orig_bits)) != VSTATUS_OK) {
		IB_LOG_ERRORRC("can't free allocated space for bitset, rc:", status);
	}
	return 1;
}
Example #4
0
int
mai_spawn_dc_reader(int qp, int dev, int port)
{
    int             rc;
    unsigned char name[VS_NAME_MAX];
 
    IB_ENTER(__func__, qp, dev, port, 0);

    dc_reader_args.qp = qp;
    dc_reader_args.dev = dev;
    dc_reader_args.port = port;

    /*
     * start the workert thread 
     */
    (void) memset (name, 8, sizeof(name));
    (void) sprintf((void *)name,"mai_dc");
    rc  =   vs_thread_create (&dc_thandle, 
			      name, 
			      (void (*)(uint32_t, uint8_t **))dc_reader_start,
			      0,NULL ,
			      MAI_DC_STACK_SIZE);
    if (rc) {
			IB_LOG_ERRORRC("failed to create MAI layer server thread rc:", rc);
	IB_EXIT(__func__, rc);
	  return rc;
    } else {
        /* need to wait (up to 2 seconds) for the dedicated dcthread to initialize here */
		return(cs_psema_wait(&gMAI_DCTHREAD_SEMA, 2));
	}

    IB_LOG_INFO("INFO:  MAI layer server thread created ", rc);
    IB_EXIT(__func__, 0);
    return VSTATUS_OK;
}
Example #5
0
Status_t
sm_fsm_discovering(Mai_t *maip, char *nodename)
{
	Status_t	status;
    STL_SM_INFO theirSmInfo;
    Lid_t       slid=maip->addrInfo.slid;    // original source lid; mai_reply swaps slid-dlid

	IB_ENTER(__func__, maip->base.amod, sm_state, 0, 0);

    BSWAPCOPY_STL_SM_INFO((STL_SM_INFO *)STL_GET_SMP_DATA(maip), &theirSmInfo);
//
//	The SM in the DISCOVERING state does not have any valid transitions via
//	the Set(SMInfo) method.
//
	maip->base.status = MAD_STATUS_BAD_ATTR;
    
	sm_smInfo.ActCount++;
    BSWAPCOPY_STL_SM_INFO(&sm_smInfo, (STL_SM_INFO *)STL_GET_SMP_DATA(maip));

	status = mai_stl_reply(fd_async, maip, sizeof(STL_SM_INFO));
	if (status != VSTATUS_OK) {
		IB_LOG_ERRORRC("sm_fsm_discovering - bad mai_reply rc:", status);
	}
    IB_LOG_WARN_FMT(__func__, 
           "No transitions allowed from DISCOVERING state; Got %s request from [%s] SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
           getAmod(maip->base.amod), sm_getStateText(theirSmInfo.u.s.SMStateCurrent), nodename, slid, theirSmInfo.PortGUID, maip->base.tid);

	IB_EXIT(__func__, 0);
	return(VSTATUS_OK);
}
Example #6
0
Status_t
sm_routing_alloc_cost_matrix(Topology_t *topop)
{
	Status_t status;
	size_t   bytesCost;

	/* Allocate space for the cost array. */
	bytesCost = topop->max_sws * topop->max_sws * sizeof(uint16_t);
	if (bytesCost > topop->bytes) {
		topop->bytes = 0;

		if (topop->cost != NULL) {
			(void)vs_pool_free(&sm_pool, (void *)topop->cost);
			topop->cost = NULL;
		}

		status = vs_pool_alloc(&sm_pool, bytesCost, (void *)&topop->cost);
		if (status != VSTATUS_OK) {
			IB_LOG_ERRORRC("can't malloc cost array rc:", status);
			IB_EXIT(__func__, status);
			return status;
		}

		topop->bytes = bytesCost;
	}

	return VSTATUS_OK;
}
Example #7
0
/*
 * clear the contents of the context pool
 */
void sa_cntxt_clear(void) {
    int i;
	Status_t status;

    if ((status = vs_lock(&sa_cntxt_lock)) != VSTATUS_OK) {
        IB_LOG_ERRORRC("sa_cntxt_clear: Failed to lock SA context, rc:", status);
    } else {
    	memset( sa_hash, 0, sizeof( sa_hash ));
    	memset( sa_cntxt_pool, 0, sizeof( sa_cntxt_t ) * sa_max_cntxt);
    	sa_cntxt_free_list = NULL ;
    	for( i = 0 ; i < sa_max_cntxt ; ++i ) {
    		sa_cntxt_insert_head( sa_cntxt_free_list, &sa_cntxt_pool[i] );
    	}
        if ((status = vs_unlock(&sa_cntxt_lock)) != VSTATUS_OK) {
            IB_LOG_ERRORRC("sa_cntxt_clear: Failed to unlock SA contex, rc:", status);
        }
    }
}
Example #8
0
uint32_t fe_vieo_init(uint8_t *logName)
{
    uint32_t rc = SUCCESS;
    static const char func[] = "fe_vieo_init"; 

    IB_ENTER(func, 0, 0, 0, 0); 

    fd_dm = INVALID_HANDLE;
    fdsa  = INVALID_HANDLE;
    
	// initialize MAI subsystem
	mai_set_num_end_ports( MIN(fe_config.subnet_size, MAI_MAX_QUEUED_DEFAULT) );
    mai_init(); 

    IB_LOG_INFO("Device = ", fe_config.hca);

    rc = if3_register_fe(fe_config.hca,fe_config.port,(void *)FE_SERVICE_NAME,FE_SERVICE_ID, IF3_REGFORCE_PORT,&fdsa);
    if (rc != VSTATUS_OK) {
        if (fe_config.debug) IB_LOG_INFINI_INFORC("Failed to register with IF3, will try later. rc:", rc);
    } else {
        rc = fe_if3_subscribe_sa();    
        if (rc != VSTATUS_OK) {
            IB_LOG_ERRORRC("Failed to subscribe for traps in SA rc:", rc);
        }

        // connect to Performance Manager
        if (pm_lid)
            rc = if3_lid_mngr_cnx(fe_config.hca,fe_config.port,MAD_CV_VFI_PM,pm_lid,&fd_pm);
        else
            rc = if3_sid_mngr_cnx(fe_config.hca,fe_config.port,(void *)PM_SERVICE_NAME,PM_SERVICE_ID,
                               MAD_CV_VFI_PM,&fd_pm);

        if (rc != VSTATUS_OK) {
            IB_LOG_INFINI_INFORC("Failed to open Performance Manager, will try later. rc:", rc);
            fd_pm = INVALID_HANDLE;
        }

#ifdef DEVICE_MANAGER   // not implemented yet
        // connect to Device Manager
        if (dm_lid)
            rc = if3_lid_mngr_cnx(fe_config.hca,fe_config.port,DM_IF3_MCLASS,dm_lid,&fd_dm);
        else
            rc = if3_sid_mngr_cnx(fe_config.hca,fe_config.port,DM_SERVICE_NAME,DM_SERVICE_ID,
                               DM_IF3_MCLASS,&fd_dm);

        if (rc != VSTATUS_OK) {
            IB_LOG_INFINI_INFORC("Failed to open Device Manager, wil try later. rc:", rc);
            fd_dm = INVALID_HANDLE;
        }

#endif
    }

    IB_EXIT(func, 0); 
    return(rc);
}
Example #9
0
void bitset_free(bitset_t *bitset) {
    Status_t	status;

	if (bitset->bits_m) {
		if ((status = vs_pool_free(bitset->pool_m, bitset->bits_m)) != VSTATUS_OK) {
			IB_LOG_ERRORRC("can't free allocated space for bitset, rc:", status);
		}
	}
    memset(bitset, 0, sizeof(bitset_t));
}
Example #10
0
Status_t
state_event_timeout(void) {
	uint64_t	now;
	Status_t	status;
	static uint64_t lastStandbyCheck=0;

	IB_ENTER(__func__, 0, 0, 0, 0);

//
//	If this is the STANDBY state, then we need to heartbeat the Master.
//	If this is the MASTER or DISCOVERING state, then we need to do a topology sweep.
//
//  Note that sweeping in DISCOVERING is required to avoid deadlocks when we
//  abort a sweep before transitioning out of DISCOVERING.
//
	if (lastStandbyCheck == 0) {
		(void)vs_time_get(&lastStandbyCheck);
	}

	if (sm_state == SM_STATE_STANDBY) {
#if defined(IB_STACK_OPENIB)
		status = ib_refresh_devport();
		if (status != VSTATUS_OK) {
			IB_LOG_ERRORRC("cannot refresh sm pkeys rc:", status);
		}
#endif
		status = sm_check_Master();
		if (status != VSTATUS_OK) {
            /* Master in trouble, start discovery */
            (void)sm_transition(SM_STATE_DISCOVERING);
			sm_trigger_sweep(SM_SWEEP_REASON_MASTER_TROUBLE);
		}
	} else if (sm_state == SM_STATE_DISCOVERING || sm_state == SM_STATE_MASTER) {
		(void)vs_time_get(&now);
		if ((topology_wakeup_time != 0ull) && (now >= topology_wakeup_time)) {
			topology_wakeup_time = 0ull;
			lastStandbyCheck = now;
			sm_trigger_sweep(SM_SWEEP_REASON_SCHEDULED);

		} else if (sm_config.monitor_standby_enable &&
				   topology_wakeup_time != 0ull && 
				   sm_state == SM_STATE_MASTER && 
				   ((now - lastStandbyCheck) > sm_masterCheckInterval * sm_config.master_ping_max_fail)) {
			sm_dbsync_standbyCheck();
			lastStandbyCheck = now;
		}
	} else if (sm_state == SM_STATE_NOTACTIVE) {
		// Notify master sm that we are going away.  Most HSMs and the X switches
		// don't currently support capabilityMask trap indicating IsSm off.
		status = sm_check_Master();
	}

	IB_EXIT(__func__, VSTATUS_OK);
	return(VSTATUS_OK);
}
Example #11
0
Status_t
sa_cntxt_release( sa_cntxt_t* sa_cntxt )
{
	int         bucket;
	Status_t	status;

	IB_ENTER( "sa_cntxt_release", sa_cntxt, 0, 0, 0 );

    if (!sa_cntxt) {
        IB_LOG_ERROR0("sa_cntxt_release: SA context is NULL!!!");
        return VSTATUS_OK ;
    }
    if ((status = vs_lock(&sa_cntxt_lock)) != VSTATUS_OK) {
        IB_LOG_ERRORRC("sa_cntxt_release: Failed to lock SA context rc:", status);
    } else {
        if( sa_cntxt->ref == 0 ) {
            IB_LOG_INFINI_INFO0("sa_cntxt_release: reference count is already zero");
        } else {
            --sa_cntxt->ref;
            if( sa_cntxt->ref == 0 ) {

                // This context needs to be removed from hash
                if( sa_cntxt->hashed ) {
                    bucket = sa_cntxt->lid % SA_CNTXT_HASH_TABLE_DEPTH;
                    sa_cntxt_delete_entry( sa_hash[ bucket ], sa_cntxt );
                }

                sa_cntxt->prev = sa_cntxt->next = NULL ;
                sa_cntxt_retire( sa_cntxt );

            }
        }
        if ((status = vs_unlock(&sa_cntxt_lock)) != VSTATUS_OK) {
            IB_LOG_ERRORRC("sa_cntxt_release: Failed to unlock SA context rc:", status);
        }
    }

	IB_EXIT( "sa_cntxt_release", VSTATUS_OK );
	return VSTATUS_OK ;
}
Example #12
0
//
// find context entry matching input mad
//
sa_cntxt_t *sa_cntxt_find( Mai_t* mad ) {
	uint64_t	now ;
	int 		bucket;
	Status_t	status;
	sa_cntxt_t* sa_cntxt;
	sa_cntxt_t*	req_cntxt = NULL;

    if ((status = vs_lock(&sa_cntxt_lock)) != VSTATUS_OK) {
        IB_LOG_ERRORRC("sa_cntxt_find: Failed to lock SA context rc:", status);
    } else {
        vs_time_get( &now );
        // Search the hash table for the context 	
        bucket = mad->addrInfo.slid % SA_CNTXT_HASH_TABLE_DEPTH ;
        sa_cntxt = sa_hash[ bucket ];
        while( sa_cntxt ) {
            if( sa_cntxt->lid == mad->addrInfo.slid  && sa_cntxt->tid == mad->base.tid ) {
                req_cntxt = sa_cntxt ;
                sa_cntxt = sa_cntxt->next ;
                req_cntxt->tstamp = now ;
                break ;
            } else {
                sa_cntxt = sa_cntxt->next;
            }
        }
        // Table is sorted with respect to timeout
        if( req_cntxt ) {
            // Touch current context
            req_cntxt->tstamp = now ;
            sa_cntxt_delete_entry( sa_hash[ bucket ], req_cntxt );
            sa_cntxt_insert_head( sa_hash[ bucket ], req_cntxt );
            // A get on an existing context reserves it
            req_cntxt->ref ++ ;
        }
        if ((status = vs_unlock(&sa_cntxt_lock)) != VSTATUS_OK) {
            IB_LOG_ERRORRC("sa_cntxt_find: Failed to unlock SA context rc:", status);
        }
    }
	IB_EXIT("sa_cntxt_find", req_cntxt );
    return req_cntxt;
} // end cntxt_find
Example #13
0
int
mai_dc_read(IBhandle_t fd)
{
    int             rc;

    IB_ENTER(__func__, fd, 0, 0, 0);

    if (gMAI_USE_DEDICATED_DCTHREAD) {

        if (gMAI_DCTHREAD_HANDLE != MAI_INVALID) {
            IB_LOG_WARNX("down call thread handle is busy handle:",
                        gMAI_DCTHREAD_HANDLE);
            IB_EXIT(__func__, VSTATUS_BUSY);
            return VSTATUS_BUSY;
        }

        /*
         * Remember the handle associated with the thread 
         */
        gMAI_DCTHREAD_HANDLE = fd;
        /*  release the waiting initiator thread */
		cs_vsema(&gMAI_DCTHREAD_SEMA);
    }
    mai_dc_read_exit = 0;
    if (mai_dc_read_exit == 1) {
        IB_LOG_VERBOSE0("Mai DC Task exiting OK.");
        return VSTATUS_OK;
    }
    do {
        rc = mai_recv(fd, &mad, DC_THREAD_TIMEOUT);
    } while (rc == VSTATUS_TIMEOUT);

    if (rc != VSTATUS_TIMEOUT) {
        if (rc == VSTATUS_CONNECT_GONE) {
            IB_LOG_VERBOSERC("mai is shutting down rc:", rc);
        } else {
            IB_LOG_ERRORRC("bad status rc:", rc);
        }
    }

    if (gMAI_USE_DEDICATED_DCTHREAD) {
        /*
         * Reset the handle associated with the DC thread 
         */
        gMAI_DCTHREAD_HANDLE = MAI_INVALID;
    }

    IB_EXIT(__func__, rc);
    return rc;

}
Example #14
0
/**********************************************************************
*
* FUNCTION
*    vs_pool_alloc
*
* DESCRIPTION
*    Does fundamental common validation for vs_pool_alloc
*    parameters and invokes environment specific implmentation.
*
* INPUTS
*
* OUTPUTS
*      Status_t - On success VSTATUS_OK is returned, otherwise
*      the cause of the error.
*
*
* HISTORY
*
*   NAME    DATE        REMARKS
*   DKJ     03/07/02    Initial creation of function.
**********************************************************************/
Status_t
vs_pool_alloc (Pool_t * handle, size_t length, void **loc)
{
  Status_t rc;

  IB_ENTER (function, (unint) handle, (uint32_t) length, (unint) loc,
	    (uint32_t) 0U);

  if (handle == 0)
    {
      IB_LOG_ERROR0 ("handle is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (handle->magic != VSPOOL_MAGIC)
    {
      IB_LOG_ERRORX ("invalid handle magic:", handle->magic);
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (loc == 0)
    {
      IB_LOG_ERROR0 ("loc is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (length == (size_t) 0x00U)
    {
      IB_LOG_ERROR0 ("length is zero");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  // TBD - do we need to lock here?
  rc = vs_lock (&handle->lock);
  if (rc != VSTATUS_OK)
    {
      IB_LOG_ERRORRC("vs_lock failed rc:", rc);
      IB_EXIT (function, VSTATUS_NXIO);
      return VSTATUS_NXIO;
    }

  rc = vs_implpool_alloc (handle, length, loc);

  (void) vs_unlock (&handle->lock);
  IB_EXIT (function, rc);
  return rc;
}
Example #15
0
Status_t
sm_fsm_notactive(Mai_t *maip, char *nodename)
{
	Status_t	status;
    long        new_state=-1;
    STL_SM_INFO    theirSmInfo;

	IB_ENTER(__func__, maip->base.amod, sm_state, 0, 0);

    BSWAPCOPY_STL_SM_INFO((STL_SM_INFO *)STL_GET_SMP_DATA(maip), &theirSmInfo);

	switch (maip->base.amod) {
    case SM_AMOD_STANDBY:				// C14-54.1.1
        IB_LOG_INFINI_INFO_FMT(__func__, 
               "[%s] SM received request to transition to STANDBY from SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
               sm_getStateText(sm_smInfo.u.s.SMStateCurrent), nodename, maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
		new_state = SM_STATE_STANDBY;
		break;
    case SM_AMOD_DISABLE:
        IB_LOG_WARN_FMT(__func__, 
               "[%s] SM received request to transition to NOTACTIVE from SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
               sm_getStateText(sm_smInfo.u.s.SMStateCurrent), nodename, maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
		new_state = SM_STATE_NOTACTIVE;
		break;
	default:
		maip->base.status = MAD_STATUS_BAD_ATTR;
		IB_LOG_WARN_FMT(__func__,
			"[%s] SM received invalid transition request %s (%u) from SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
			sm_getStateText(sm_smInfo.u.s.SMStateCurrent), getAmod(maip->base.amod), maip->base.amod,
			nodename, maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
		break;
	}
    
    /*
     * Reply to this Set(SMInfo).
     */
	sm_smInfo.ActCount++;
    BSWAPCOPY_STL_SM_INFO(&sm_smInfo, (STL_SM_INFO *)STL_GET_SMP_DATA(maip));
	status = mai_stl_reply(fd_async, maip, sizeof(STL_SM_INFO));
	if (status != VSTATUS_OK) {
		IB_LOG_ERRORRC("sm_fsm_notactive - bad mai_reply rc:", status);
	}

    /* make appropriate transition if necessary */
    if (new_state >= SM_STATE_NOTACTIVE) 
        (void)sm_transition(new_state);
    
	IB_EXIT(__func__, 0);
	return(VSTATUS_OK);
}
Example #16
0
/**********************************************************************
*
* FUNCTION
*    vs_pool_delete
*
* DESCRIPTION
*    Does fundamental common validation for vs_pool_delete
*    parameters and invokes environment specific implmentation.
*
* INPUTS
*
* OUTPUTS
*      Status_t - On success VSTATUS_OK is returned, otherwise
*      the cause of the error.
*
*
* HISTORY
*
*   NAME    DATE        REMARKS
*   DKJ     03/07/02    Initial creation of function.
**********************************************************************/
Status_t
vs_pool_delete (Pool_t * handle)
{
  Status_t rc;

  IB_ENTER (function, (unint) handle, (uint32_t) 0U, (uint32_t) 0U,
	    (uint32_t) 0U);

  if (handle == 0)
    {
      IB_LOG_ERROR0 ("handle is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (handle->magic != VSPOOL_MAGIC)
    {
      IB_LOG_ERRORX ("invalid handle magic:", handle->magic);
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  rc = vs_lock (&handle->lock);
  if (rc != VSTATUS_OK)
    {
      IB_LOG_ERRORRC("vs_lock failed rc:", rc);
      IB_EXIT (function, VSTATUS_NXIO);
      return VSTATUS_NXIO;
    }

  rc = vs_implpool_delete (handle);
  if (rc == VSTATUS_OK)
    {
      handle->magic = ~VSPOOL_MAGIC;
      (void) vs_unlock (&handle->lock);
      (void) vs_lock_delete (&handle->lock);
    }
  else
    {
      (void) vs_unlock (&handle->lock);
    }
  (void) memset (handle, 0, sizeof (Pool_t));

  IB_EXIT (function, rc);
  return rc;
}
Example #17
0
/**********************************************************************
*
* FUNCTION
*    vs_pool_size
*
* DESCRIPTION
*    Does fundamental common validation for vs_pool_size
*    parameters and invokes environment specific implmentation.
*
* INPUTS
*
* OUTPUTS
*      number of bytes allocated from pool.
**********************************************************************/
Status_t
vs_pool_size (Pool_t * handle, uint64_t *numBytesAlloc)
{
  Status_t rc;

  IB_ENTER (function, (unint) handle, 0, 0, 0);

  if (handle == 0)
    {
      IB_LOG_ERROR0 ("handle is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (handle->magic != VSPOOL_MAGIC)
    {
      IB_LOG_ERRORX ("invalid handle magic:", handle->magic);
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (numBytesAlloc == 0)
    {
      IB_LOG_ERROR0 ("numBytesAlloc is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  // TBD - do we need to lock here?
  rc = vs_lock (&handle->lock);
  if (rc != VSTATUS_OK)
    {
      IB_LOG_ERRORRC("vs_lock failed rc:", rc);
	  *numBytesAlloc = 0;
      IB_EXIT (function, VSTATUS_NXIO);
      return VSTATUS_NXIO;
    }

  rc = vs_implpool_size (handle, numBytesAlloc);

  (void) vs_unlock (&handle->lock);
  IB_EXIT (function, rc);
  return rc;
}
Example #18
0
/**********************************************************************
*
* FUNCTION
*    vs_pool_free
*
* DESCRIPTION
*    Does fundamental common validation for vs_pool_free
*    parameters and invokes environment specific implmentation.
*
* INPUTS
*
* OUTPUTS
*      Status_t - On success VSTATUS_OK is returned, otherwise
*      the cause of the error.
*
*
* HISTORY
*
*   NAME    DATE        REMARKS
*   DKJ     03/07/02    Initial creation of function.
**********************************************************************/
Status_t
vs_pool_free (Pool_t * handle, void *loc)
{
  Status_t rc;

  IB_ENTER (function, (unint) handle, (unint) loc, (uint32_t) 0U,
	    (uint32_t) 0U);

  if (handle == 0)
    {
      IB_LOG_ERROR0 ("handle is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (handle->magic != VSPOOL_MAGIC)
    {
      IB_LOG_ERRORX ("invalid handle magic:", handle->magic);
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if (loc == 0)
    {
      IB_LOG_ERROR0 ("loc is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  rc = vs_lock (&handle->lock);
  if (rc != VSTATUS_OK)
    {
      IB_LOG_ERRORRC("vs_lock failed rc:", rc);
      IB_EXIT (function, VSTATUS_NXIO);
      return VSTATUS_NXIO;
    }

  rc = vs_implpool_free (handle, loc);

  (void) vs_unlock (&handle->lock);
  IB_EXIT (function, rc);
  return rc;
}
Example #19
0
void fe_shutdown(void)
{
    Status_t rc = SUCCESS; 
    NetError nerr; 
    
    IB_ENTER(__func__, 0, 0, 0, 0); 
    
    /* Close Performance Manager Connecttion */
    if (fd_pm != INVALID_HANDLE) {
        if3_close_mngr_cnx(fd_pm);
    } else {
        /* Complete termination of the RMPP connection. */
        (void)if3_close_mngr_rmpp_cnx(fd_pm);
    }
    
    /* Close Device Manager Connecttion */
    if (fd_dm != INVALID_HANDLE) {
        if3_close_mngr_cnx(fd_dm);
    }   
    
    /* Deregister FE Manager and Unsubscribe from SA    */
    if (fdsa != INVALID_HANDLE) {
        fe_if3_unsubscribe_sa(TRUE); 
        if3_deregister_fe(fdsa);
    } else {
        /* Complete termination of the RMPP connection. */
        (void)if3_close_mngr_rmpp_cnx(fdsa);
    }
    
    /* Shutdown the net and free the pool */
    nerr = fe_net_shutdown(); 
    if (nerr != NET_NO_ERROR) {
        IB_LOG_ERROR("Error shutting down libnet. nerr:", nerr);
    }
    
    rc = vs_pool_delete(&fe_pool);  
    if (rc != VSTATUS_OK) {
        IB_LOG_ERRORRC("Error destroying fe memory pool. rc:", rc);
    }
    
    IB_EXIT(__func__, 0); 
    return;
}
Example #20
0
int bitset_init(Pool_t* pool, bitset_t *bitset, size_t nbits) {
    Status_t	status;

	bitset->pool_m = pool;
	bitset->bits_m = NULL;
	bitset->nset_m = 0;
	bitset->nbits_m = nbits;
	bitset->nwords_m = (nbits/32);
	if (nbits%32) {
		bitset->nwords_m++;
	}
	status = vs_pool_alloc(pool, sizeof(uint32_t)*bitset->nwords_m, (void *)&bitset->bits_m);
	if (status != VSTATUS_OK) {
		IB_LOG_ERRORRC("can't allocate space for bitset, rc:", status);
		memset(bitset, 0, sizeof(bitset_t));
		return 0;
	}
	memset(bitset->bits_m, 0, sizeof(uint32_t)*bitset->nwords_m);
	return 1;
}
Example #21
0
void
sa_main_reader(uint32_t argc, uint8_t ** argv) {
	Status_t	status;
	Mai_t		in_mad;
	Filter_t	filter;
	sa_cntxt_t	*sa_cntxt=NULL;
	uint64_t	now, delta, max_delta;
	int			tries=0, retry=0;
    uint64_t    reqTimeToLive=0;
    SAContextGet_t  cntxGetStatus=0;
    int         numContextBusy=0;

	IB_ENTER("sa_main_reader", 0, 0, 0, 0);

	sa_main_reader_exit = 0;
    
    /*
     *	Create the SubnAdm(*) MAD filter for the SA thread.
     */
	SA_Filter_Init(&filter);
	filter.value.mclass = MAD_CV_SUBN_ADM;
	filter.mask.mclass = 0xff;
	filter.value.method = 0x00;
	filter.mask.method = 0x80;
	filter.mai_filter_check_packet = sa_reader_filter;
	MAI_SET_FILTER_NAME (&filter, "SA Reader");

	if (mai_filter_create(fd_sa, &filter, VFILTER_SHARE) != VSTATUS_OK) {
		IB_LOG_ERROR0("sa_main_reader: can't create SubnAdm(*) filter");
		(void)vs_thread_exit(&sm_threads[SM_THREAD_SA_READER].handle);
	}

    timeMftLastUpdated = 0;
    /* 
     * calculate request time to live on queue
     * ~ 3.2secs for defaults: sa_packetLifetime=18 and sa_respTimeValue=18 
     */
    reqTimeToLive = 4ull * ( (2*(1 << sm_config.sa_packet_lifetime_n2)) + (1 << sm_config.sa_resp_time_n2) ); 
	while (1) {
		status = mai_recv(fd_sa, &in_mad, VTIMER_1S/4);

        if (sa_main_reader_exit == 1){
#ifdef __VXWORKS__
            ESM_LOG_ESMINFO("sa_main_reader: exiting OK.", 0);
#endif
            break;
        }
        /* don't process messages if not master SM or still doing first sweep */
		if ((sm_state != SM_STATE_MASTER) ||
		    (topology_passcount < 1)) {
            continue;
        }

		/* 
         * If the mai layer shuts down we end up in this infinite loop here.
		 * This may happen on initialization
         */
		if( status != VSTATUS_OK ){
            if (status != VSTATUS_TIMEOUT)
                IB_LOG_ERRORRC("sa_main_reader: error on mai_recv rc:", status);
        } else {
            /* 
             * Drop new requests that have been sitting on SA reader queue for too long 
             */
            if (in_mad.intime) {
				/* PR 110586 - On some RHEL 5 systems, we've seen  weird issues with gettimeofday() [used by vs_time_get()]
				 * where once in a while the time difference calculated from successive calls to gettimeofday()
				 * results in a negative value. Due to this, we might actually consider a request stale even if
				 * its not. Work around this by making calls to gettimeofday() till it returns us some
				 * sane values. Just to be extra cautious, bound the retries so that we don't get stuck in the loop.  
				 */
				tries = 0;
				/* Along with negative values also check for unreasonably high values of delta*/
				max_delta = 30*reqTimeToLive;
				do {
					vs_time_get( &now );
					delta = now - in_mad.intime;
					tries++;
					
					if ((now < in_mad.intime) || (delta > max_delta)) {
						vs_thread_sleep(1);
						retry = 1;
					} else {
						retry = 0;
					}	
				} while (retry && tries < 20);

                if (delta > reqTimeToLive) {
					INCREMENT_COUNTER(smCounterSaDroppedRequests);
                    if (smDebugPerf || saDebugPerf) {
                        IB_LOG_INFINI_INFO_FMT( "sa_main_reader",
                               "Dropping stale %s[%s] request from LID[0x%x], TID="FMT_U64"; On queue for %d.%d seconds.", 
                               sa_getMethodText((int)in_mad.base.method), sa_getAidName((int)in_mad.base.aid), in_mad.addrInfo.slid, 
                               in_mad.base.tid, (int)(delta/1000000), (int)((delta - delta/1000000*1000000))/1000);
                    }
                    /* drop the request without returning a response; sender will retry */
                    continue;
                }
            }
            /* 
             * get a context to process request; sa_cntxt can be:
             *   1. NULL if resources are scarce
             *   2. NULL if request is dup of existing request
             *   3. in progress getMulti request context
             *   4. New context for a brand new request 
             */
            cntxGetStatus = sa_cntxt_get( &in_mad, (void *)&sa_cntxt );
            if (cntxGetStatus == ContextAllocated) {
				/* process the new request */
				sa_process_mad( &in_mad, sa_cntxt );
				/* 
				 * This may not necessarily release context based on if someone else has reserved it
				 */
				if(sa_cntxt) sa_cntxt_release( sa_cntxt );
			} else if (cntxGetStatus == ContextExist) {
				INCREMENT_COUNTER(smCounterSaDuplicateRequests);
				/* this is a duplicate request */
				if (saDebugPerf || saDebugRmpp) {
					IB_LOG_INFINI_INFO_FMT( "sa_main_reader",
					       "SA_READER received duplicate %s[%s] from LID [0x%x] with TID ["FMT_U64"] ", 
					       sa_getMethodText((int)in_mad.base.method), sa_getAidName((int)in_mad.base.aid),in_mad.addrInfo.slid, in_mad.base.tid);
				}
            } else if (cntxGetStatus == ContextNotAvailable) {
				INCREMENT_COUNTER(smCounterSaContextNotAvailable);
                /* we are swamped, return BUSY to caller */
                if (saDebugPerf || saDebugRmpp) { /* log msg before send changes method and lids */
                    IB_LOG_INFINI_INFO_FMT( "sa_main_reader",
                           "NO CONTEXT AVAILABLE, returning MAD_STATUS_BUSY to %s[%s] request from LID [0x%x], TID ["FMT_U64"]!",
                           sa_getMethodText((int)in_mad.base.method), sa_getAidName((int)in_mad.base.aid), in_mad.addrInfo.slid, in_mad.base.tid);
                }
                in_mad.base.status = MAD_STATUS_BUSY;
                sa_send_reply( &in_mad, sa_cntxt );
                if ((++numContextBusy % sa_max_cntxt) == 0) {
                    IB_LOG_INFINI_INFO_FMT( "sa_main_reader",
                           "Had to drop %d SA requests since start due to no available contexts",
                           numContextBusy);
                }
            } else if (cntxGetStatus == ContextExistGetMulti) {
                /* continue processing the getMulti request */
                sa_process_getmulti( &in_mad, sa_cntxt );
                if(sa_cntxt) sa_cntxt_release( sa_cntxt );
            } else {
                IB_LOG_WARN("sa_main_reader: Invalid sa_cntxt_get return code:", cntxGetStatus);
            }
        }

        /* 
         * signal sm_top to reprogram the MFTs
         * Wait one second to allow mcmember requests to accumulate before asking
         */
        vs_time_get( &now );
        if (sa_mft_reprog && timeMftLastUpdated == 0) {
            timeMftLastUpdated = now;
        } else if (sa_mft_reprog && (now - timeMftLastUpdated) > VTIMER_1S) {
            topology_wakeup_time = 0ull;
            if ((status = vs_lock(&sa_lock)) != VSTATUS_OK) {
                IB_LOG_ERRORRC("sa_main_reader: Failed to lock sa_lock rc:", status);
            } else {
                sm_McGroups_Need_Prog = 1;      /* tells Topoloy thread that MFT reprogramming is needed */
                (void)vs_unlock(&sa_lock);
            }
            sm_trigger_sweep(SM_SWEEP_REASON_MCMEMBER);
            /* clear the indicators */
            timeMftLastUpdated = 0;
            sa_mft_reprog = 0;
        }
	}
    /* cleanup before exit, but allow some time for the other threads to flush out first */
    (void)vs_thread_sleep(VTIMER_1S);     
    (void)sa_SubscriberDelete();
    (void)sa_ServiceRecDelete();
    (void)sa_McGroupDelete();
	if (mai_filter_delete(fd_sa, &filter, VFILTER_SHARE) != VSTATUS_OK) {
		IB_LOG_ERROR0("sa_main_reader: can't delete SubnAdm(*) filter");
	}
	//IB_LOG_INFINI_INFO0("sa_main_reader thread: Exiting OK");
}
Example #22
0
Status_t
sm_fsm_standby(Mai_t *maip, char *nodename)
{
	int		i;
	uint8_t		ipath[64];
	uint8_t		*rpath;
	uint8_t		*path;
	Status_t	status;
    long        new_state=-1;
    STL_SM_INFO    theirSmInfo;
	STL_SM_INFO smInfoCopy;
    Lid_t       slid=maip->addrInfo.slid;    // original source lid; mai_reply swaps slid-dlid
    Lid_t       dlid=maip->addrInfo.dlid;    // original destination lid(us); mai_reply swaps slid-dlid

	IB_ENTER(__func__, maip->base.amod, 0, 0, 0);

    BSWAPCOPY_STL_SM_INFO((STL_SM_INFO *)STL_GET_SMP_DATA(maip), &theirSmInfo);

	switch (maip->base.amod) {
	case SM_AMOD_DISCOVER:				// C14-48
		new_state = SM_STATE_DISCOVERING;
		break;
	case SM_AMOD_DISABLE:				// C14-19
		new_state = SM_STATE_NOTACTIVE;
		break;
	case SM_AMOD_HANDOVER:				// C14-50
		new_state = SM_STATE_MASTER;
		break;
	case SM_AMOD_ACKNOWLEDGE:			// from previous HANDOVER
		break;
	default:
		maip->base.status = MAD_STATUS_BAD_ATTR;
		break;
	}

    if (maip->base.status > MAD_STATUS_OK) {
		IB_LOG_WARN_FMT(__func__,
			"[%s] SM received invalid AMOD[%d] from SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
			sm_getStateText(sm_smInfo.u.s.SMStateCurrent), maip->base.amod, nodename,
			maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
    } else {
        IB_LOG_INFINI_INFO_FMT(__func__, 
               "SM in [%s] state after processing %s smInfo control from SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
               (new_state < 0 ? sm_getStateText(sm_smInfo.u.s.SMStateCurrent):sm_getStateText(new_state)), getAmod(maip->base.amod), 
               nodename, maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
    }
    
    /*
     * Reply to this Set(SMInfo).
     */
	sm_smInfo.ActCount++;
    BSWAPCOPY_STL_SM_INFO(&sm_smInfo, (STL_SM_INFO *)STL_GET_SMP_DATA(maip));
	status = mai_stl_reply(fd_async, maip, sizeof(STL_SM_INFO));
	if (status != VSTATUS_OK) {
		IB_LOG_ERRORRC("sm_fsm_standby - bad mai_reply rc:", status);
	}
    
	(void)vs_lock(&new_topology_lock);

    /* make appropriate none master transition if necessary */
    if (new_state >= SM_STATE_NOTACTIVE && new_state != SM_STATE_MASTER) {
        (void)sm_transition(new_state);
        if (new_state == SM_STATE_DISCOVERING) {
            sm_trigger_sweep(SM_SWEEP_REASON_STATE_TRANSITION); // wakeup the topology thread to start sweep
        }
    }

    /*
     * If this was a HANDOVER, we need to ACK back.
     */
	if (maip->base.amod == SM_AMOD_HANDOVER) {
		maip->addrInfo.destqp &= 0x00ffffff;

		if (maip->base.mclass == MAD_CV_SUBN_LR) {
			path = NULL;
            sm_topop->dlid = slid;    // this is original sender of SmInfo
            sm_topop->slid = dlid;    // this is us
            IB_LOG_INFINI_INFO_FMT(__func__, "sending LR HANDOVER ACK to node %s, Lid [0x%x], portguid "FMT_U64,
                   nodename, slid, theirSmInfo.PortGUID);
		} else {
            DRStlSmp_t *drsmp = (DRStlSmp_t *)maip->data;

			path = ipath;
			memset((void *)ipath, 0, 64);

			ipath[0] = maip->base.hopCount;
			rpath = drsmp->RetPath;
			for (i = 1; i <= maip->base.hopCount; i++) {
				ipath[i] = rpath[maip->base.hopCount + 1 - i];
			}
            IB_LOG_INFINI_INFO_FMT(__func__, "sending DR HANDOVER ACK to node %s, portguid "FMT_U64,
                   nodename, theirSmInfo.PortGUID);
		}
		smInfoCopy = sm_smInfo;
		status = SM_Set_SMInfo(fd_sminfo, SM_AMOD_ACKNOWLEDGE, path, &smInfoCopy, sm_config.mkey);
		if (status != VSTATUS_OK) {
            IB_LOG_WARN_FMT(__func__, 
                   "[%s] SM did not receive response to Handover Acknowledgement from SM node %s, LID [0x%x], portguid ["FMT_U64"]",
                   sm_getStateText(new_state), nodename, slid, theirSmInfo.PortGUID);
		} 
        /* make transition to MASTER state */
        (void)sm_transition(new_state);
        sm_trigger_sweep(SM_SWEEP_REASON_STATE_TRANSITION);
    }
	(void)vs_unlock(&new_topology_lock);

	IB_EXIT(__func__, 0);
	return(VSTATUS_OK);
}
Example #23
0
Status_t
sm_fsm_master(Mai_t *maip, char *nodename)
{
	Status_t	status;
    long        new_state=-1;
    STL_SM_INFO    theirSmInfo;
	uint8_t		ipath[64];
	uint8_t		*rpath;
	uint8_t		*path;
    int         i, wakeTpThread=0;
	STL_SM_INFO 	smInfoCopy;
    Lid_t       slid=maip->addrInfo.slid;    // original source lid; mai_reply swaps slid-dlid
    Lid_t       dlid=maip->addrInfo.dlid;    // original destination lid(us); mai_reply swaps slid-dlid

	IB_ENTER(__func__, maip->base.amod, sm_state, 0, 0);

    BSWAPCOPY_STL_SM_INFO((STL_SM_INFO *)STL_GET_SMP_DATA(maip), &theirSmInfo);

	switch (maip->base.amod) {
    case SM_AMOD_HANDOVER:				// C14-61
        new_state = SM_STATE_MASTER;
        IB_LOG_INFINI_INFO_FMT(__func__, 
               "[%s] SM received '%s' from SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
               sm_getStateText(sm_smInfo.u.s.SMStateCurrent), getAmod(maip->base.amod), nodename, maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
		break;
    case SM_AMOD_ACKNOWLEDGE:
        if (theirSmInfo.u.s.SMStateCurrent < SM_STATE_STANDBY) {  // C14-38.1.1 almost
            maip->base.status = MAD_STATUS_BAD_FIELD;
            IB_LOG_WARN_FMT(__func__, 
                   "[%s] SM received invalid Handover Ack from remote SM %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64"; remote not in STANDBY state [%s]",
                   sm_getStateText(sm_smInfo.u.s.SMStateCurrent), nodename, maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid, sm_getStateText(theirSmInfo.u.s.SMStateCurrent));
        } else {
            new_state = SM_STATE_STANDBY;
            wakeTpThread = 1;
            IB_LOG_INFINI_INFO_FMT(__func__, 
                   "[%s] SM received '%s' from SM node %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
                   sm_getStateText(sm_smInfo.u.s.SMStateCurrent), getAmod(maip->base.amod), nodename, maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
        }
		break;
	default:
		maip->base.status = MAD_STATUS_BAD_ATTR;
        IB_LOG_WARN_FMT(__func__, 
               "[%s] SM received invalid MASTER transition [%s] from remote [%s] SM %s, LID [0x%x], portguid ["FMT_U64"], TID="FMT_U64,
               sm_getStateText(sm_smInfo.u.s.SMStateCurrent), getAmod(maip->base.amod), sm_getStateText(theirSmInfo.u.s.SMStateCurrent), nodename, 
               maip->addrInfo.slid, theirSmInfo.PortGUID, maip->base.tid);
		break;
	}
    
    /*
     * Reply to this Set(SMInfo).
     */
	sm_smInfo.ActCount++;
    BSWAPCOPY_STL_SM_INFO(&sm_smInfo, (STL_SM_INFO *)STL_GET_SMP_DATA(maip));
	status = mai_stl_reply(fd_async, maip, sizeof(STL_SM_INFO));
	if (status != VSTATUS_OK) {
		IB_LOG_ERRORRC("sm_fsm_master - bad mai_reply rc:", status);
    }

	(void)vs_lock(&new_topology_lock);

    /* make appropriate transition if necessary */
    if (new_state >= SM_STATE_NOTACTIVE && new_state != sm_state)
        (void)sm_transition(new_state);
    if (wakeTpThread) {
        /* wakeup the topology thread to clean up SA tables */
        sm_trigger_sweep(SM_SWEEP_REASON_HANDOFF);
    }
    
    /*
     * If this was a HANDOVER, we need to ACK back.
     */
    if (maip->base.amod == SM_AMOD_HANDOVER) {
        maip->addrInfo.destqp &= 0x00ffffff;

        if (maip->base.mclass == MAD_CV_SUBN_LR) {
            path = NULL;
            sm_topop->dlid = slid;    // this is original sender of SmInfo
            sm_topop->slid = dlid;    // this is us
            IB_LOG_INFINI_INFO_FMT(__func__, "sending LR HANDOVER ACK to node %s, Lid [0x%x], portguid "FMT_U64,
                   nodename, slid, theirSmInfo.PortGUID);
        } else {
            DRStlSmp_t *drsmp = (DRStlSmp_t *)maip->data;

            path = ipath;
            memset((void *)ipath, 0, 64);

            ipath[0] = maip->base.hopCount;
			rpath = drsmp->RetPath;
            for (i = 1; i <= maip->base.hopCount; i++) {
                ipath[i] = rpath[maip->base.hopCount + 1 - i];
            }
            IB_LOG_INFINI_INFO_FMT(__func__, "sending DR HANDOVER ACK to node %s, portguid "FMT_U64,
                   nodename, theirSmInfo.PortGUID);
        }
        smInfoCopy = sm_smInfo;
        status = SM_Set_SMInfo(fd_sminfo, SM_AMOD_ACKNOWLEDGE, path, &smInfoCopy, sm_config.mkey);
        if (status != VSTATUS_OK) {
            IB_LOG_WARN_FMT(__func__, 
                   "[%s] SM did not receive response to Handover Acknowledgement from [%s] SM node %s, LID [0x%x], portguid ["FMT_U64"]",
                   sm_getStateText(sm_smInfo.u.s.SMStateCurrent), sm_getStateText(theirSmInfo.u.s.SMStateCurrent), nodename, slid, theirSmInfo.PortGUID);
        } else {
            IB_LOG_INFINI_INFO_FMT(__func__, 
                   "[%s] SM successfully acknowleded Handover from remote SM node %s, LID [0x%x], portguid ["FMT_U64"]",
                   sm_getStateText(sm_smInfo.u.s.SMStateCurrent), nodename, slid, theirSmInfo.PortGUID);
        }
        /* make transition to MASTER state */
        (void)sm_transition(new_state);
        sm_trigger_sweep(SM_SWEEP_REASON_STATE_TRANSITION); // wakeup the topology thread
    }
	(void)vs_unlock(&new_topology_lock);

	IB_EXIT(__func__, 0);
	return(VSTATUS_OK);
}
Example #24
0
Status_t
sm_check_Master() {
	Status_t	status;
	STL_SM_INFO	theirSmInfo;
	STL_PORT_INFO	portInfo;
	uint8_t		path[64];

    static  uint32_t fsmCheckMasterFailed=0; // count of fails to check master
    static  uint32_t fsmMultMaxFail = 1; // multiplier for sm_config.master_ping_max_fail

    IB_ENTER(__func__, 0, 0, 0, 0);

    (void)memset((void *)path, 0, 64);

    if ((status = SM_Get_PortInfo(fd_sminfo, 1<<24, path, &portInfo)) != VSTATUS_OK) {
        IB_LOG_ERRORRC("failed to get master SM Lid from my PortInfo, rc:", status);
        // having a local problem
        // reset count, must be healthy before we can consider becoming master
        fsmCheckMasterFailed = 0;
        goto stay_standby;
    }

    if (portInfo.LID == 0 || portInfo.MasterSMLID == 0
        || portInfo.PortStates.s.PortState != IB_PORT_ACTIVE
        ) {
        if (smDebugPerf) {
            if (portInfo.PortStates.s.PortState != IB_PORT_ACTIVE) {
                IB_LOG_INFINI_INFO("our portInfo indicates state not active; portState=", (int)portInfo.PortStates.s.PortState);
            } else
            if (portInfo.MasterSMLID == 0) {
                IB_LOG_INFINI_INFOX("our portInfo smLid is not set yet; Lid=", portInfo.LID);
            }
        }
        // stay in standby until link comes up
        if (portInfo.PortStates.s.PortState > IB_PORT_DOWN) {
            IB_LOG_WARN0("Switching to DISCOVERY state; Local port uninitialized");
            goto discovering;
        }
        goto stay_standby;
    }

    // make sure we aren't trying to talk to ourself during the handover window
    if (portInfo.LID == portInfo.MasterSMLID) {
        // we're talking to ourself.  if a master SM doesn't come along and
        // reprogram our SM LID in the timeout period, attempt a discovery.
        // Since for large fabrics, the master can take some time to program
        // our LID, use a higher upper limit for failure count to give the
        // master enough time to program our SM LID.
        fsmMultMaxFail = 2;
        if (++fsmCheckMasterFailed >= fsmMultMaxFail * sm_config.master_ping_max_fail) {
            IB_LOG_WARN0("Switching to DISCOVERY state; Timed out waiting for SM LID to get reprogrammed");
            goto discovering;
        }
        if (smDebugPerf) {
            IB_LOG_INFINI_INFOX("our portInfo smLid is not set yet; smLid=", portInfo.MasterSMLID);
        }
        goto stay_standby; // not yet at threshold
    }

    sm_topop->slid = portInfo.LID;
    sm_topop->dlid = portInfo.MasterSMLID;
    if ((status = SM_Get_SMInfo(fd_sminfo, 0, NULL, &theirSmInfo)) != VSTATUS_OK) {
        if (++fsmCheckMasterFailed >= fsmMultMaxFail * sm_config.master_ping_max_fail) {
            IB_LOG_WARNX("Switching to DISCOVERY state; Failed to get SmInfo from master SM at LID:", portInfo.MasterSMLID);
            goto discovering;
        } else {
            IB_LOG_INFINI_INFO_FMT(__func__,
                   "failed to get SmInfo from master SM at LID[0x%X], retry count=%d",
                   portInfo.MasterSMLID, fsmCheckMasterFailed);
            goto stay_standby; // not yet at threshold
        }
    }

    sm_saw_another_sm = TRUE;

    /* 
     * PR 105313 - restart results in 2 standby SMs 
     * Must check the state we get back to make sure master is still master
     */
    if (theirSmInfo.u.s.SMStateCurrent != SM_STATE_MASTER) {
        IB_LOG_WARN_FMT(__func__,
               "SmInfo from SM at SMLID[0x%X] indicates SM is no longer master, switching to DISCOVERY state",
               portInfo.MasterSMLID);
        goto discovering;
    }

    // all OK, save data about master, reset fail count and threshold
    sm_topop->sm_count = theirSmInfo.ActCount;
    sm_topop->sm_key = theirSmInfo.SM_Key;

    fsmCheckMasterFailed = 0;
    fsmMultMaxFail = 1;

    if (smDebugPerf) {
        IB_LOG_INFINI_INFO_FMT(__func__, 
               "Master SM["FMT_U64"] at LID=0x%x has priority[%d] and smKey ["FMT_U64"]",
               theirSmInfo.PortGUID, portInfo.MasterSMLID, theirSmInfo.u.s.Priority, theirSmInfo.SM_Key);
    }

stay_standby:
    status = VSTATUS_OK;

done:
    IB_EXIT(__func__, status);
    return(status);

discovering:
    // reset count and threshold in case stay standby
    fsmCheckMasterFailed = 0;
    fsmMultMaxFail = 1;
    status = VSTATUS_BAD;
    goto done;
}
Example #25
0
/*
 * Very simple hashing implemented. This function is modular and can be 
 * changed to use any algorithm, if hashing turns out to be bad.
 * Returns new context for new requests, existing context for in progress 
 * getMulti requests and NULL for duplicate requests
 */
SAContextGet_t
sa_cntxt_get( Mai_t* mad, void **context)
{
	uint64_t	now ;
	int 		bucket;
	Status_t	status;
	sa_cntxt_t* sa_cntxt;
    SAContextGet_t getStatus=0;
	sa_cntxt_t*	req_cntxt = NULL;

	IB_ENTER( "sa_cntxt_get", mad, 0, 0, 0 );

    if ((status = vs_lock(&sa_cntxt_lock)) != VSTATUS_OK) {
        IB_LOG_ERRORRC("sa_cntxt_get: Failed to lock SA context rc:", status);
    } else {
        vs_time_get( &now );
        // Search the hash table for the context 	
        bucket = mad->addrInfo.slid % SA_CNTXT_HASH_TABLE_DEPTH ;
        sa_cntxt = sa_hash[ bucket ];
        while( sa_cntxt ) {
            if( sa_cntxt->lid == mad->addrInfo.slid  &&
                    sa_cntxt->tid == mad->base.tid ) {
                req_cntxt = sa_cntxt ;
                break ;
            } else {
                sa_cntxt = sa_cntxt->next;
            }
        }
		if( req_cntxt ) {
			if ( req_cntxt->method == SA_CM_GETMULTI && req_cntxt->reqInProg ) {
				/* In progress getMulti request. Touch and reserve it. */
				getStatus = ContextExistGetMulti;
				req_cntxt->tstamp = now ;
				sa_cntxt_delete_entry( sa_hash[ bucket ], req_cntxt );
				sa_cntxt_insert_head( sa_hash[ bucket ], req_cntxt );
				/* A get on an existing context reserves it */
				req_cntxt->ref ++ ;
			} else {
				/* dup of an existing request */
				getStatus = ContextExist;
				req_cntxt = NULL;
			}
		} else {
			/* Allocate a new context and set appropriate status */
			req_cntxt = sa_cntxt_free_list ;
			if( req_cntxt ) {
				getStatus = ContextAllocated;
				sa_cntxt_delete_entry( sa_cntxt_free_list, req_cntxt );
				req_cntxt->ref = 1;  /* set ref count to 1 */
				INCR_SA_CNTXT_NALLOC();
				DECR_SA_CNTXT_NFREE();
				req_cntxt->lid = mad->addrInfo.slid ;
				req_cntxt->tid = mad->base.tid ;
				req_cntxt->method = mad->base.method ;
				req_cntxt->tstamp = now;
			} else {
				/* out of context */
				getStatus = ContextNotAvailable;
			}
		}
		if ((status = vs_unlock(&sa_cntxt_lock)) != VSTATUS_OK) {
			IB_LOG_ERRORRC("sa_cntxt_get: Failed to unlock SA context rc:", status);
		}
	}
    /* return new context or existing getmulti context or NULL */
    *context = req_cntxt;

	IB_EXIT("sa_cntxt_get", getStatus );
	return getStatus;
}
Example #26
0
int
sa_main(void) {
	Status_t		status;
	int 			i;

	IB_ENTER("sa_main", 0, 0, 0, 0);

    if (sa_SubscriberInit() != VSTATUS_OK) {
		IB_FATAL_ERROR("sa_main: Can't allocate Subscriber hash table");
		return 1;
	}
    
    if (sa_ServiceRecInit() != VSTATUS_OK) {
		IB_FATAL_ERROR("sa_main: Can't allocate Service Record hash table");
		return 1;
	}
    
    // 
    //  Zero context hash table
    //
	memset( sa_hash, 0, sizeof( sa_hash ));
	sa_cntxt_pool = NULL;
    IB_LOG_VERBOSE("sa_main: Allocating SA context pool with num entries=", sa_max_cntxt);
	status = vs_pool_alloc(&sm_pool, sizeof(sa_cntxt_t) * sa_max_cntxt, (void *)&sa_cntxt_pool);
	if (status != VSTATUS_OK) {
		IB_FATAL_ERROR("sa_main: Can't allocate SA context pool");
		return 2;
	}
	memset( sa_cntxt_pool, 0, sizeof( sa_cntxt_t ) * sa_max_cntxt);
	sa_cntxt_free_list = NULL ;
	for( i = 0 ; i < sa_max_cntxt ; ++i ) {
		sa_cntxt_insert_head( sa_cntxt_free_list, &sa_cntxt_pool[i] );
	}
    sa_cntxt_nfree = sa_max_cntxt;
    sa_cntxt_nalloc = 0;

    // initialize SA context lock
	status = vs_lock_init(&sa_cntxt_lock, VLOCK_FREE, VLOCK_THREAD);
	if (status != VSTATUS_OK) {
		IB_LOG_ERRORRC("sa_main: can't initialize SA context pool lock rc:", status);
        return 3;
	}
    //
    //	Allocate the SA storage pool.
    //
	status = vs_pool_alloc(&sm_pool, sa_data_length, (void*)&sa_data);
	if (status != VSTATUS_OK) {
		IB_FATAL_ERROR("sa_main: can't allocate sa data");
		return 4;
	}

    //
    //	Fill in my ClassPortInfo_t and add it to the database.
    //
	(void)memset((void *)&saClassPortInfo, 0, sizeof(STL_CLASS_PORT_INFO));
	saClassPortInfo.BaseVersion = STL_BASE_VERSION; //MAD_BVERSION;
	saClassPortInfo.ClassVersion = STL_SA_CLASS_VERSION; //SA_MAD_CVERSION;
	saClassPortInfo.CapMask =
		STL_CLASS_PORT_CAPMASK_CM2 |
		STL_SA_CAPABILITY_MULTICAST_SUPPORT |
		STL_SA_CAPABILITY_PORTINFO_CAPMASK_MATCH |
		STL_SA_CAPABILITY_PA_SERVICES_SUPPORT;
	saClassPortInfo.u1.s.CapMask2 =
		STL_SA_CAPABILITY2_QOS_SUPPORT |
		STL_SA_CAPABILITY2_MFTTOP_SUPPORT |
		STL_SA_CAPABILITY2_FULL_PORTINFO |
		STL_SA_CAPABILITY2_EXT_SUPPORT;
	saClassPortInfo.u1.s.RespTimeValue = sm_config.sa_resp_time_n2;
	saClassPortInfo.u3.s.RedirectQP = 1;
	saClassPortInfo.u5.s.TrapHopLimit = 0xff;
	saClassPortInfo.u5.s.TrapQP = 1;

    //
    //	Init Sa Groups table and Set up the default Multicast group if one is set.
    //
    status = sa_McGroupInit();
	if (status != VSTATUS_OK) {
		IB_FATAL_ERROR("sa_main: can't initialize SA McMember/Groups table lock");
        return 5;
	}
	sa_SetDefBcGrp();

	//
	//	Init SA caching
	//
	status = sa_cache_init();
	if (status != VSTATUS_OK) {
		IB_FATAL_ERROR("sa_main: can't initialize SA caching");
		return 6;
	}

	return 0;
}
Example #27
0
int
main(int argc, char* argv[])
{
  int rc,i;
  uint64_t tid;
  IBhandle_t fd = -1,fh;
  Mai_t mad, rmad;
  uint8_t         name[16];


  /* Parse command line arguments */
  if (argc > 1)
      parse_cmd_line(argc,argv);


   /* Initialize MAD */
   memset(&rmad,0,sizeof(rmad));

   /* Initialize MAD */
   memset(&mad,0,sizeof(mad));

  /* Initialize MAI subsystem */
  mai_init();

  rc=ib_init_devport(&ib_dev, &ib_port, NULL);
  if (rc)
    {
      printf("ib_init_devport failed, %d\n",rc);
      return rc;
    }

  /* Create MAI handle to used to communicate */
  rc = mai_open(MAI_GSI_QP,ib_dev,ib_port,&fd);

  if (rc)
    {
      printf("MAI_OPEN failed, %d\n",rc);
      return rc;
    }

  /* Initialize MAD that will be sent */
  if(oob)
    mad.type = MAI_TYPE_INTERNAL;
  else
    mad.type = MAI_TYPE_EXTERNAL;


  mad.base.method = method;
  mad.base.mclass = mclass;
  mad.base.aid = aid;
  AddrInfo_Init(&mad, slid, dlid, 0, STL_DEFAULT_FM_PKEY, MAI_GSI_QP, MAI_GSI_QP, GSI_WELLKNOWN_QKEY);
  mad.base.bversion = MAD_BVERSION;
  mad.base.cversion = MAD_CVERSION;
  mad.active = MAI_ACT_BASE | MAI_ACT_DATA | MAI_ACT_TYPE |
               MAI_ACT_ADDRINFO;


  /* Create filter to listen for response */
  rc = mai_filter_method(fd,VFILTER_SHARE,MAI_TYPE_ANY, &fh, mclass,
                         RESPONSE);
  if (rc)
    {
      printf("Cannot create filter to listen for responses \n");
      return rc;
    }


  if(use_event)
    {
      sprintf((char *) name, "client");
      rc = vs_event_create(&event, name, (Eventset_t) 0x00U);

      if (rc)
	{
	  IB_LOG_ERRORRC("vs_event_create failed rc:", rc);
	  return rc;
	}

    }


  /* Loop which sends MADS to receiver */
  for (i = 0; i < loop; i++)
    {
      /* Get a transaction ID for message we are about to send */
      rc = mai_alloc_tid(fd, mclass, &tid);

      /* Assign transaction ID to the MAD to be sent */
      mad.base.tid = tid;

      /* Send command to receiver */
      rc = mai_send(fd,&mad);
      if (rc)
        {
          printf("MAI send failed %d \n",rc);
          return rc;
        }

      printf("MAD sent\n");
      printf("Waiting for acknowledgement\n");


      if(use_event)
	{
	  Eventset_t      events = (Eventset_t) 0U;

	   do{
	    rc = vs_event_wait(event.event_handle,
			       timeout,0x1,&events);
	  }while(rc == VSTATUS_AGAIN);

	  if(rc == VSTATUS_OK)
	    {
	      rc = mai_recv(fd,&rmad,MAI_RECV_NOWAIT);
	    }
	  printf("Event wait returned %d\n",rc);
	}
      else
	{
	  /* Get acknowledgement */
	  rc = mai_recv(fd,&rmad,timeout);
	}


      if (rc != VSTATUS_OK)
        {
          printf("Acknowledgement not received \n");
          return rc;
        }

      printf("Acknowledgement received\n");
      printf("Passed Loop %d\n ",i);

      //sleep(1);
    }

  /* Delete filter */
  mai_filter_hdelete(fd,fh);

  /* Close MAI channel */
  rc = mai_close(fd);
  if (rc)
    {
      printf("Close failed\n");
      return rc;
    }

  printf("Test successful!!\n");
  return rc;
}
Example #28
0
/**********************************************************************
*
* FUNCTION
*    vs_pool_create
*
* DESCRIPTION
*    Does fundamental common validation for vs_pool_create
*    parameters and invokes environment specific implmentation.
*
* INPUTS
*
* OUTPUTS
*      Status_t - On success VSTATUS_OK is returned, otherwise
*      the cause of the error.
*
*
* HISTORY
*
*   NAME    DATE        REMARKS
*   DKJ     03/07/02    Initial creation of function.
*   DKJ     03/21/02    Updated prototype
**********************************************************************/
Status_t
vs_pool_create (Pool_t * handle, uint32_t options, 
		    unsigned char * name, void *address, size_t size)
{
  Status_t rc;
  size_t namesize;
  const uint32_t valid_options = 0;

  IB_ENTER (function, (unint) handle, options, (unint) address,
	    (uint32_t) size);

  if (handle == 0)
    {
      IB_LOG_ERROR0 ("handle is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }
  (void) memset (handle, 0, sizeof (Pool_t));

  rc = vs_lock_init (&handle->lock, VLOCK_LOCKED, VLOCK_THREAD);
  if (rc != VSTATUS_OK)
    {
      IB_LOG_ERRORRC("vs_lock_init failed rc:", rc);
      IB_EXIT (function, VSTATUS_NOMEM);
      return VSTATUS_NOMEM;
    }

  if (name == 0)
    {
      (void) vs_unlock (&handle->lock);
      (void) vs_lock_delete (&handle->lock);
      IB_LOG_ERROR0 ("name is null");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  for (namesize = (size_t) 0U; namesize < sizeof (handle->name); namesize++)
    {
      handle->name[namesize] = name[namesize];
      if (name[namesize] == (unsigned char) 0x00U)
	{
	  break;
	}
    }

  if (namesize >= sizeof (handle->name))
    {
      (void) vs_unlock (&handle->lock);
      (void) vs_lock_delete (&handle->lock);
      IB_LOG_ERROR0 ("name doesn't contain a terminator");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

  if ((options & ~valid_options) != (uint32_t) 0x00U)
    {
      (void) vs_unlock (&handle->lock);
      (void) vs_lock_delete (&handle->lock);
      IB_LOG_ERROR ("Invalid options specified: ", options);
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }
  handle->options = options;

  if (size == (size_t) 0x00U)
    {
      (void) vs_unlock (&handle->lock);
      (void) vs_lock_delete (&handle->lock);
      IB_LOG_ERROR0 ("Pool size is zero");
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }

#ifdef __VXWORKS__
  /* cap size on VxWorks only */

  if (size > (size_t) 0xFFFFFFF0U)
    {
      (void) vs_unlock (&handle->lock);
      (void) vs_lock_delete (&handle->lock);
      IB_LOG_ERROR ("Pool size is too big: high:", (uint32_t) (size));
      IB_LOG_ERROR ("Pool size is too big: low:", (uint32_t) (size));
      IB_EXIT (function, VSTATUS_ILLPARM);
      return VSTATUS_ILLPARM;
    }
#endif

  handle->pagesize = vs_pool_page_size ();

  if ((options & VMEM_PAGE) == VMEM_PAGE)
    {
      if (size < handle->pagesize)
	{
	  (void) vs_unlock (&handle->lock);
	  (void) vs_lock_delete (&handle->lock);
	  IB_LOG_ERROR ("size is less than pagesize:", size);
	  IB_EXIT (function, VSTATUS_NOMEM);
	  return VSTATUS_NOMEM;
	}
    }

  rc = vs_implpool_create (handle, options, name, address, size);
  if (rc == VSTATUS_OK)
    {
      handle->magic = VSPOOL_MAGIC;
      (void) vs_unlock (&handle->lock);
    }
  else
    {
      (void) vs_unlock (&handle->lock);
      (void) vs_lock_delete (&handle->lock);
    }

  IB_EXIT (function, rc);
  return rc;
}
Example #29
0
Status_t
sa_SMInfoRecord_GetTable(Mai_t *maip, uint32_t *records) {
	uint8_t		*data;
	uint32_t	bytes;
	STL_SA_MAD	samad;
	Status_t	status;
    SmRecp      smrecp;
    CS_HashTableItr_t itr;
    STL_SMINFO_RECORD * record;

	IB_ENTER("sa_SMInfoRecord_GetTable", maip, *records, 0, 0);

	*records = 0;
	data = sa_data;
	bytes = Calculate_Padding(sizeof(STL_SMINFO_RECORD));

//
//  Verify the size of the data received for the request
//
	if ( maip->datasize-sizeof(STL_SA_MAD_HEADER) < sizeof(STL_SMINFO_RECORD) ) {
		IB_LOG_ERROR_FMT("sa_SMInfoRecord_GetTable",
						 "invalid MAD length; size of STL_SMINFO_RECORD[%lu], datasize[%d]", sizeof(STL_SMINFO_RECORD), maip->datasize-sizeof(STL_SA_MAD_HEADER));
		maip->base.status = MAD_STATUS_SA_REQ_INVALID;
		IB_EXIT("sa_SMInfoRecord_GetTable", MAD_STATUS_SA_REQ_INVALID);
		return (MAD_STATUS_SA_REQ_INVALID);
	}

	BSWAPCOPY_STL_SA_MAD((STL_SA_MAD*)maip->data, &samad, sizeof(STL_SMINFO_RECORD));

	/*
	 * Create the template mask for the lookup.
	 */
	status = sa_create_template_mask(maip->base.aid, samad.header.mask);
	if (status != VSTATUS_OK) {
		IB_EXIT("sa_SMInfoRecord_GetTable", VSTATUS_OK);
		return(VSTATUS_OK);
	}

	if ((status = vs_lock(&smRecords.smLock)) != VSTATUS_OK) {
		IB_LOG_ERRORRC("sa_SMInfoRecord_GetTable: Can't lock SM Record table, rc:",
						status);
    } else if (cs_hashtable_count(smRecords.smMap) > 0) {
		cs_hashtable_iterator(smRecords.smMap, &itr);
		do {
			smrecp = cs_hashtable_iterator_value(&itr);

			// Support ElapsedTime...
			// Work with the outbound copy (Do not modify the SMs db)
			record = (STL_SMINFO_RECORD *)data;
			memcpy(record, &smrecp->smInfoRec, sizeof(*record));

			// If this SM is Master, then fill in the elapsed time.
			// [Verify that the master is us... just in case]
			if (record->SMInfo.u.s.SMStateCurrent == SM_STATE_MASTER) {
				if (smrecp->portguid != sm_smInfo.PortGUID) {
					IB_LOG_WARN64("sa_SMInfoRecord_GetTable: Master SM is not us:", smrecp->portguid);
				}
				record->SMInfo.ElapsedTime = (uint32_t)difftime(time(NULL),sm_masterStartTime);
			} else if ( (record->SMInfo.u.s.SMStateCurrent == SM_STATE_STANDBY) &&
						(smrecp->dbsync.fullSyncStatus > DBSYNC_STAT_UNINITIALIZED) &&
						(smrecp->dbsync.fullTimeLastSync!=0)) {
					record->SMInfo.ElapsedTime = (uint32_t)difftime(time(NULL), smrecp->dbsync.fullTimeLastSync);
			} else {
				record->SMInfo.ElapsedTime = 0;
				IB_LOG_INFO64("sa_SMInfoRecord_GetTable: SM never syncd:", smrecp->portguid);
			}

			record->Reserved = 0;

			BSWAP_STL_SMINFO_RECORD(record);
			(void)sa_template_test_mask(samad.header.mask, samad.data, &data, sizeof(STL_SMINFO_RECORD), 
									bytes, records);
		} while (cs_hashtable_iterator_advance(&itr));
	}

    (void)vs_unlock(&smRecords.smLock);

	IB_EXIT("sa_SMInfoRecord_GetTable", VSTATUS_OK);
	return(VSTATUS_OK);
}
Example #30
0
void
sa_main_writer(uint32_t argc, uint8_t ** argv) {
	Status_t	status;
	Mai_t		in_mad;
	Filter_t	filter;
	sa_cntxt_t	*sa_cntxt;
	uint64_t	now, srLastAged=0, cacheLastCleaned=0;
    uint32_t    records=0;

	IB_ENTER("sa_main_writer", 0, 0, 0, 0);

	sa_main_writer_exit = 0;
    
    //
    //	Create the SubnAdm(*) MAD filter for the SA thread.
    //
	SA_Filter_Init(&filter);
	filter.value.mclass = MAD_CV_SUBN_ADM;
	filter.mask.mclass = 0xff;
	filter.value.method = 0x00;
	filter.mask.method = 0x80;
	filter.mai_filter_check_packet = sa_writer_filter;
	MAI_SET_FILTER_NAME (&filter, "SA Writer");

	if (mai_filter_create(fd_sa_w, &filter, VFILTER_SHARE) != VSTATUS_OK) {
		IB_LOG_ERROR0("esm_saw: can't create SubnAdm(*) filter");
		(void)vs_thread_exit(&sm_threads[SM_THREAD_SA_WRITER].handle);
	}

	while (1) {
		status = mai_recv(fd_sa_w, &in_mad, VTIMER_1S/4);
        if (status != VSTATUS_OK && status != VSTATUS_TIMEOUT) {
            IB_LOG_ERRORRC("sa_main_writer: error on mai_recv rc:", status);
            vs_thread_sleep(VTIMER_1S/10);
        }

        if (sa_main_writer_exit == 1){
#ifdef __VXWORKS__
            ESM_LOG_ESMINFO("SA Writer Task exiting OK.", 0);
#endif
            break;
        }
        /* don't process messages if not master SM or still doing first sweep */
		if (sm_state != SM_STATE_MASTER || topology_passcount < 1) {
            continue;
        }
		/* 
         * process the rmpp ack and send out the next set of segments
         */
        if (status == VSTATUS_OK) {
            /* locate and process in flight rmpp request */
            sa_cntxt = sa_cntxt_find( &in_mad );
            if (sa_cntxt) {
                sa_process_inflight_rmpp_request( &in_mad, sa_cntxt );
                /*
                 * This may not necessarily release context
                 * based on if someone else has reserved it
                 */
                sa_cntxt_release( sa_cntxt );
            } else {
				INCREMENT_COUNTER(smCounterSaDeadRmppPacket);
                if (saDebugRmpp) {
                    IB_LOG_INFINI_INFO_FMT( "sa_main_writer", 
                           "dropping %s[%s] RMPP packet from LID[0x%x], TID ["FMT_U64"] already completed/aborted",
                           sa_getMethodText((int)in_mad.base.method), sa_getAidName(in_mad.base.aid), 
                           in_mad.addrInfo.slid, in_mad.base.tid);
                }
            }
        }

        /* age contexts if more than 1 second since last time */
        vs_time_get( &now );
        if ((now - timeLastAged) > (VTIMER_1S)) {
            (void) sa_cntxt_age();
        }

        /* age the service records */
        if ((now - srLastAged) > 5*VTIMER_1S) {
            srLastAged = now;
            if ((status = sa_ServiceRecord_Age(&records)) != VSTATUS_OK) {
                IB_LOG_ERRORRC("sa_main_writer: failed to age service records, rc:", status);
            } else if (records) {
                if (smDebugPerf) IB_LOG_INFINI_INFO("sa_main_writer: Number of service records aged out was", records);
            }
        }
		
		/* clean the SA cache */
		if ((now - cacheLastCleaned) > SA_CACHE_CLEAN_INTERVAL) {
			cacheLastCleaned = now;
			(void)vs_lock(&saCache.lock);
			sa_cache_clean();
			(void)vs_unlock(&saCache.lock);
		}
	}
    /* clean up cache before exit */
    sa_cache_clean();
    (void)vs_lock_delete(&saCache.lock);
	//IB_LOG_INFINI_INFO0("sa_main_writer thread: Exiting OK");
} // SA_MAIN_WRITER