Пример #1
0
/**********************************************************************
 * Clear all the counters from the db
 **********************************************************************/
void perfmgr_db_clear_counters(perfmgr_db_t * db)
{
	cl_plock_excl_acquire(&db->lock);
	cl_qmap_apply_func(&db->pc_data, clear_counters, (void *)db);
	cl_plock_release(&db->lock);
#if 0
	if (db->db_impl->clear_counters)
		db->db_impl->clear_counters(db->db_data);
#endif
}
Пример #2
0
perfmgr_db_err_t
perfmgr_db_mark_active(perfmgr_db_t *db, uint64_t guid, boolean_t active)
{
	db_node_t *node = NULL;

	cl_plock_excl_acquire(&db->lock);
	node = get(db, guid);
	if (node)
		node->active = active;
	cl_plock_release(&db->lock);
	return (PERFMGR_EVENT_DB_SUCCESS);
}
Пример #3
0
perfmgr_db_err_t
perfmgr_db_update_name(perfmgr_db_t * db, uint64_t node_guid, char *name)
{
	db_node_t *node = NULL;

	cl_plock_excl_acquire(&db->lock);
	node = get(db, node_guid);
	if (node)
		snprintf(node->node_name, sizeof(node->node_name), "%s", name);
	cl_plock_release(&db->lock);
	return (PERFMGR_EVENT_DB_SUCCESS);
}
Пример #4
0
/**********************************************************************
 * print all node data to fp
 **********************************************************************/
void
perfmgr_db_print_all(perfmgr_db_t * db, FILE *fp, int err_only)
{
	cl_map_item_t *item;
	db_node_t *node;

	cl_plock_acquire(&db->lock);
	item = cl_qmap_head(&db->pc_data);
	while (item != cl_qmap_end(&db->pc_data)) {
		node = (db_node_t *)item;
		dump_node_hr(node, fp, NULL, err_only);
		item = cl_qmap_next(item);
	}
	cl_plock_release(&db->lock);
}
Пример #5
0
/**********************************************************************
 * dump the data to the file "file"
 **********************************************************************/
perfmgr_db_err_t
perfmgr_db_dump(perfmgr_db_t * db, char *file, perfmgr_db_dump_t dump_type)
{
	dump_context_t context;

	context.fp = fopen(file, "w+");
	if (!context.fp)
		return PERFMGR_EVENT_DB_FAIL;
	context.dump_type = dump_type;

	cl_plock_acquire(&db->lock);
	cl_qmap_apply_func(&db->pc_data, db_dump, (void *)&context);
	cl_plock_release(&db->lock);
	fclose(context.fp);
	return PERFMGR_EVENT_DB_SUCCESS;
}
Пример #6
0
/**********************************************************************
 * print node data to fp
 **********************************************************************/
void
perfmgr_db_print_by_guid(perfmgr_db_t * db, uint64_t nodeguid, FILE *fp,
			 char *port, int err_only)
{
	cl_map_item_t *node;

	cl_plock_acquire(&db->lock);

	node = cl_qmap_get(&db->pc_data, nodeguid);
	if (node != cl_qmap_end(&db->pc_data))
		dump_node_hr((db_node_t *)node, fp, port, err_only);
	else
		fprintf(fp, "Node 0x%" PRIx64 " not found...\n", nodeguid);

	cl_plock_release(&db->lock);
}
Пример #7
0
/*
 *  SA DB Loader
 */
static osm_mgrp_t *load_mcgroup(osm_opensm_t * p_osm, ib_net16_t mlid,
				ib_member_rec_t * p_mcm_rec,
				unsigned well_known)
{
	ib_net64_t comp_mask;
	osm_mgrp_t *p_mgrp;

	cl_plock_excl_acquire(&p_osm->lock);

	p_mgrp = osm_get_mgrp_by_mgid(&p_osm->subn, &p_mcm_rec->mgid);
	if (p_mgrp) {
		if (p_mgrp->mlid == mlid) {
			OSM_LOG(&p_osm->log, OSM_LOG_DEBUG,
				"mgrp %04x is already here.", cl_ntoh16(mlid));
			goto _out;
		}
		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
			"mlid %04x is already used by another MC group. Will "
			"request clients reregistration.\n", cl_ntoh16(mlid));
		p_mgrp = NULL;
		goto _out;
	}

	comp_mask = IB_MCR_COMPMASK_MTU | IB_MCR_COMPMASK_MTU_SEL
	    | IB_MCR_COMPMASK_RATE | IB_MCR_COMPMASK_RATE_SEL;
	if (!(p_mgrp = osm_mcmr_rcv_find_or_create_new_mgrp(&p_osm->sa,
							    comp_mask,
							    p_mcm_rec)) ||
	    p_mgrp->mlid != mlid) {
		OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
			"cannot create MC group with mlid 0x%04x and mgid "
			"0x%016" PRIx64 ":0x%016" PRIx64 "\n", cl_ntoh16(mlid),
			cl_ntoh64(p_mcm_rec->mgid.unicast.prefix),
			cl_ntoh64(p_mcm_rec->mgid.unicast.interface_id));
		p_mgrp = NULL;
	} else if (well_known)
		p_mgrp->well_known = TRUE;

_out:
	cl_plock_release(&p_osm->lock);

	return p_mgrp;
}
Пример #8
0
perfmgr_db_err_t perfmgr_db_get_prev_dc(perfmgr_db_t * db, uint64_t guid,
					uint8_t port,
					perfmgr_db_data_cnt_reading_t * reading)
{
	db_node_t *node = NULL;
	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;

	cl_plock_acquire(&db->lock);

	node = get(db, guid);
	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
		goto Exit;

	*reading = node->ports[port].dc_previous;

Exit:
	cl_plock_release(&db->lock);
	return rc;
}
Пример #9
0
perfmgr_db_err_t
perfmgr_db_clear_prev_dc(perfmgr_db_t * db, uint64_t guid, uint8_t port)
{
	db_node_t *node = NULL;
	perfmgr_db_data_cnt_reading_t *previous = NULL;
	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;

	cl_plock_excl_acquire(&db->lock);
	node = get(db, guid);
	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
		goto Exit;

	previous = &node->ports[port].dc_previous;

	memset(previous, 0, sizeof(*previous));
	node->ports[port].dc_previous.time = time(NULL);

Exit:
	cl_plock_release(&db->lock);
	return rc;
}
Пример #10
0
static void sa_dump_all_sa(osm_opensm_t * p_osm, FILE * file)
{
	struct opensm_dump_context dump_context;
	osm_mgrp_t *p_mgrp;

	dump_context.p_osm = p_osm;
	dump_context.file = file;
	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump multicast\n");
	cl_plock_acquire(&p_osm->lock);
	for (p_mgrp = (osm_mgrp_t *) cl_fmap_head(&p_osm->subn.mgrp_mgid_tbl);
	     p_mgrp != (osm_mgrp_t *) cl_fmap_end(&p_osm->subn.mgrp_mgid_tbl);
	     p_mgrp = (osm_mgrp_t *) cl_fmap_next(&p_mgrp->map_item))
		sa_dump_one_mgrp(p_mgrp, &dump_context);
	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump inform\n");
	cl_qlist_apply_func(&p_osm->subn.sa_infr_list,
			    sa_dump_one_inform, &dump_context);
	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "Dump services\n");
	cl_qlist_apply_func(&p_osm->subn.sa_sr_list,
			    sa_dump_one_service, &dump_context);
	cl_plock_release(&p_osm->lock);
}
Пример #11
0
static int load_svcr(osm_opensm_t * p_osm, ib_service_record_t * sr,
		     uint32_t modified_time, uint32_t lease_period)
{
	osm_svcr_t *p_svcr;
	int ret = 0;

	cl_plock_excl_acquire(&p_osm->lock);

	if (osm_svcr_get_by_rid(&p_osm->subn, &p_osm->log, sr)) {
		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
			"ServiceRecord already exists\n");
		goto _out;
	}

	if (!(p_svcr = osm_svcr_new(sr))) {
		OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
			"cannot allocate new service struct\n");
		ret = -1;
		goto _out;
	}

	p_svcr->modified_time = modified_time;
	p_svcr->lease_period = lease_period;

	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding ServiceRecord...\n");

	osm_svcr_insert_to_db(&p_osm->subn, &p_osm->log, p_svcr);

	if (lease_period != 0xffffffff)
		cl_timer_trim(&p_osm->sa.sr_timer, 1000);

_out:
	cl_plock_release(&p_osm->lock);

	return ret;
}
Пример #12
0
/**********************************************************************
 * print node data to fp
 **********************************************************************/
void
perfmgr_db_print_by_name(perfmgr_db_t * db, char *nodename, FILE *fp,
			 char *port, int err_only)
{
	cl_map_item_t *item;
	db_node_t *node;

	cl_plock_acquire(&db->lock);

	/* find the node */
	item = cl_qmap_head(&db->pc_data);
	while (item != cl_qmap_end(&db->pc_data)) {
		node = (db_node_t *)item;
		if (strcmp(node->node_name, nodename) == 0) {
			dump_node_hr(node, fp, port, err_only);
			goto done;
		}
		item = cl_qmap_next(item);
	}

	fprintf(fp, "Node %s not found...\n", nodename);
done:
	cl_plock_release(&db->lock);
}
Пример #13
0
static int load_infr(osm_opensm_t * p_osm, ib_inform_info_record_t * iir,
		     osm_mad_addr_t * addr)
{
	osm_infr_t infr, *p_infr;
	int ret = 0;

	infr.h_bind = p_osm->sa.mad_ctrl.h_bind;
	infr.sa = &p_osm->sa;
	/* other possible way to restore mad_addr partially is
	   to extract qpn from InformInfo and to find lid by gid */
	infr.report_addr = *addr;
	infr.inform_record = *iir;

	cl_plock_excl_acquire(&p_osm->lock);
	if (osm_infr_get_by_rec(&p_osm->subn, &p_osm->log, &infr)) {
		OSM_LOG(&p_osm->log, OSM_LOG_VERBOSE,
			"InformInfo Record already exists\n");
		goto _out;
	}

	if (!(p_infr = osm_infr_new(&infr))) {
		OSM_LOG(&p_osm->log, OSM_LOG_ERROR,
			"cannot allocate new infr struct\n");
		ret = -1;
		goto _out;
	}

	OSM_LOG(&p_osm->log, OSM_LOG_DEBUG, "adding InformInfo Record...\n");

	osm_infr_insert_to_db(&p_osm->subn, &p_osm->log, p_infr);

_out:
	cl_plock_release(&p_osm->lock);

	return ret;
}
Пример #14
0
perfmgr_db_err_t
perfmgr_db_create_entry(perfmgr_db_t * db, uint64_t guid, boolean_t esp0,
			uint8_t num_ports, char *name)
{
	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;

	cl_plock_excl_acquire(&db->lock);
	if (!get(db, guid)) {
		db_node_t *pc_node = malloc_node(guid, esp0, num_ports,
						 name);
		if (!pc_node) {
			rc = PERFMGR_EVENT_DB_NOMEM;
			goto Exit;
		}
		if (insert(db, pc_node)) {
			free_node(pc_node);
			rc = PERFMGR_EVENT_DB_FAIL;
			goto Exit;
		}
	}
Exit:
	cl_plock_release(&db->lock);
	return rc;
}
Пример #15
0
/*********************************************************************
Received a Set(InformInfo) MAD
**********************************************************************/
static void
osm_infr_rcv_process_set_method(IN osm_sa_t * sa,
				IN osm_madw_t * const p_madw)
{
	ib_sa_mad_t *p_sa_mad;
	ib_inform_info_t *p_recvd_inform_info;
	osm_infr_t inform_info_rec;	/* actual inform record to be stored for reports */
	osm_infr_t *p_infr;
	ib_net32_t qpn;
	uint8_t resp_time_val;
	ib_api_status_t res;

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);

	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_recvd_inform_info =
	    (ib_inform_info_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);

#if 0
	if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG))
		osm_dump_inform_info(sa->p_log, p_recvd_inform_info,
				     OSM_LOG_DEBUG);
#endif

	/* Grab the lock */
	cl_plock_excl_acquire(sa->p_lock);

	/* define the inform record */
	inform_info_rec.inform_record.inform_info = *p_recvd_inform_info;

	/* following C13-32.1.2 Tbl 120: we only copy the source address vector */
	inform_info_rec.report_addr = p_madw->mad_addr;

	/* we will need to know the mad srvc to send back through */
	inform_info_rec.h_bind = p_madw->h_bind;
	inform_info_rec.sa = sa;

	/* update the subscriber GID according to mad address */
	res = osm_get_gid_by_mad_addr(sa->p_log, sa->p_subn, &p_madw->mad_addr,
				      &inform_info_rec.inform_record.
				      subscriber_gid);
	if (res != IB_SUCCESS) {
		cl_plock_release(sa->p_lock);

		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4308 "
			"Subscribe Request from unknown LID: %u\n",
			cl_ntoh16(p_madw->mad_addr.dest_lid));
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
		goto Exit;
	}

	/* HACK: enum is always 0 (currently) */
	inform_info_rec.inform_record.subscriber_enum = 0;

	/* Subscribe values above 1 are undefined */
	if (p_recvd_inform_info->subscribe > 1) {
		cl_plock_release(sa->p_lock);

		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4308 "
			"Invalid subscribe: %d\n",
			p_recvd_inform_info->subscribe);
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
		goto Exit;
	}

	/*
	 * MODIFICATIONS DONE ON INCOMING REQUEST:
	 *
	 * QPN:
	 * Internally we keep the QPN field of the InformInfo updated
	 * so we can simply compare it in the record - when finding such.
	 */
	if (p_recvd_inform_info->subscribe) {
		ib_inform_info_set_qpn(&inform_info_rec.inform_record.
				       inform_info,
				       inform_info_rec.report_addr.addr_type.
				       gsi.remote_qp);

		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Subscribe Request with QPN: 0x%06X\n",
			cl_ntoh32(inform_info_rec.report_addr.addr_type.gsi.
				  remote_qp));
	} else {
		ib_inform_info_get_qpn_resp_time(p_recvd_inform_info->g_or_v.
						 generic.qpn_resp_time_val,
						 &qpn, &resp_time_val);

		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"UnSubscribe Request with QPN: 0x%06X\n",
			cl_ntoh32(qpn));
	}

	/* If record exists with matching InformInfo */
	p_infr =
	    osm_infr_get_by_rec(sa->p_subn, sa->p_log, &inform_info_rec);

	/* check to see if the request was for subscribe */
	if (p_recvd_inform_info->subscribe) {
		/* validate the request for a new or update InformInfo */
		if (__validate_infr(sa, &inform_info_rec) != TRUE) {
			cl_plock_release(sa->p_lock);

			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4305: "
				"Failed to validate a new inform object\n");

			/* o13-13.1.1: we need to set the subscribe bit to 0 */
			p_recvd_inform_info->subscribe = 0;
			osm_sa_send_error(sa, p_madw,
					  IB_SA_MAD_STATUS_REQ_INVALID);
			goto Exit;
		}

		/* ok - we can try and create a new entry */
		if (p_infr == NULL) {
			/* Create the instance of the osm_infr_t object */
			p_infr = osm_infr_new(&inform_info_rec);
			if (p_infr == NULL) {
				cl_plock_release(sa->p_lock);

				OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4306: "
					"Failed to create a new inform object\n");

				/* o13-13.1.1: we need to set the subscribe bit to 0 */
				p_recvd_inform_info->subscribe = 0;
				osm_sa_send_error(sa, p_madw,
						  IB_SA_MAD_STATUS_NO_RESOURCES);
				goto Exit;
			}

			/* Add this new osm_infr_t object to subnet object */
			osm_infr_insert_to_db(sa->p_subn, sa->p_log, p_infr);
		} else
			/* Update the old instance of the osm_infr_t object */
			p_infr->inform_record = inform_info_rec.inform_record;
	/* We got an UnSubscribe request */
	} else if (p_infr == NULL) {
		cl_plock_release(sa->p_lock);

		/* No Such Item - So Error */
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4307: "
			"Failed to UnSubscribe to non existing inform object\n");

		/* o13-13.1.1: we need to set the subscribe bit to 0 */
		p_recvd_inform_info->subscribe = 0;
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
		goto Exit;
	} else
		/* Delete this object from the subnet list of informs */
		osm_infr_remove_from_db(sa->p_subn, sa->p_log, p_infr);

	cl_plock_release(sa->p_lock);

	/* send the success response */
	__osm_infr_rcv_respond(sa, p_madw);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #16
0
/**********************************************************************
Received a Get(InformInfoRecord) or GetTable(InformInfoRecord) MAD
**********************************************************************/
static void
osm_infr_rcv_process_get_method(IN osm_sa_t * sa,
				IN osm_madw_t * const p_madw)
{
	char gid_str[INET6_ADDRSTRLEN];
	ib_sa_mad_t *p_rcvd_mad;
	const ib_inform_info_record_t *p_rcvd_rec;
	cl_qlist_t rec_list;
	osm_iir_search_ctxt_t context;
	osm_physp_t *p_req_physp;
	osm_iir_item_t *item;

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);
	p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_rcvd_rec =
	    (ib_inform_info_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);

	/* update the requester physical port. */
	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
						osm_madw_get_mad_addr_ptr
						(p_madw));
	if (p_req_physp == NULL) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4309: "
			"Cannot find requester physical port\n");
		goto Exit;
	}

	if (osm_log_is_active(sa->p_log, OSM_LOG_DEBUG))
		osm_dump_inform_info_record(sa->p_log, p_rcvd_rec,
					    OSM_LOG_DEBUG);

	cl_qlist_init(&rec_list);

	context.p_rcvd_rec = p_rcvd_rec;
	context.p_list = &rec_list;
	context.comp_mask = p_rcvd_mad->comp_mask;
	context.subscriber_gid = p_rcvd_rec->subscriber_gid;
	context.subscriber_enum = p_rcvd_rec->subscriber_enum;
	context.sa = sa;
	context.p_req_physp = p_req_physp;

	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
		"Query Subscriber GID:%s(%02X) Enum:0x%X(%02X)\n",
		inet_ntop(AF_INET6, p_rcvd_rec->subscriber_gid.raw,
			gid_str, sizeof gid_str),
		(p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_SUBSCRIBERGID) != 0,
		cl_ntoh16(p_rcvd_rec->subscriber_enum),
		(p_rcvd_mad->comp_mask & IB_IIR_COMPMASK_ENUM) != 0);

	cl_plock_acquire(sa->p_lock);

	cl_qlist_apply_func(&sa->p_subn->sa_infr_list,
			    __osm_sa_inform_info_rec_by_comp_mask_cb, &context);

	cl_plock_release(sa->p_lock);

	/* clear reserved and pad fields in InformInfoRecord */
	for (item = (osm_iir_item_t *) cl_qlist_head(&rec_list);
	     item != (osm_iir_item_t *) cl_qlist_end(&rec_list);
	     item = (osm_iir_item_t *)cl_qlist_next(&item->list_item)) {
		memset(item->rec.reserved, 0, sizeof(item->rec.reserved));
		memset(item->rec.pad, 0, sizeof(item->rec.pad));
	}

	osm_sa_respond(sa, p_madw, sizeof(ib_inform_info_record_t), &rec_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #17
0
void osm_pkey_rec_rcv_process(IN void *ctx, IN void *data)
{
	osm_sa_t *sa = ctx;
	osm_madw_t *p_madw = data;
	const ib_sa_mad_t *p_rcvd_mad;
	const ib_pkey_table_record_t *p_rcvd_rec;
	const osm_port_t *p_port = NULL;
	const ib_pkey_table_t *p_pkey;
	cl_qlist_t rec_list;
	osm_pkey_search_ctxt_t context;
	ib_api_status_t status = IB_SUCCESS;
	ib_net64_t comp_mask;
	osm_physp_t *p_req_physp;

	CL_ASSERT(sa);

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);

	p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_rcvd_rec =
	    (ib_pkey_table_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);
	comp_mask = p_rcvd_mad->comp_mask;

	CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_PKEY_TBL_RECORD);

	/* we only support SubnAdmGet and SubnAdmGetTable methods */
	if (p_rcvd_mad->method != IB_MAD_METHOD_GET &&
	    p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4605: "
			"Unsupported Method (%s)\n",
			ib_get_sa_method_str(p_rcvd_mad->method));
		osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
		goto Exit;
	}

	/*
	   p922 - P_KeyTableRecords shall only be provided in response
	   to trusted requests.
	   Check that the requester is a trusted one.
	 */
	if (p_rcvd_mad->sm_key != sa->p_subn->opt.sa_key) {
		/* This is not a trusted requester! */
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4608: "
			"Request from non-trusted requester: "
			"Given SM_Key:0x%016" PRIx64 "\n",
			cl_ntoh64(p_rcvd_mad->sm_key));
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
		goto Exit;
	}

	/* update the requester physical port. */
	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
						osm_madw_get_mad_addr_ptr
						(p_madw));
	if (p_req_physp == NULL) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4604: "
			"Cannot find requester physical port\n");
		goto Exit;
	}

	p_pkey = (ib_pkey_table_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);

	cl_qlist_init(&rec_list);

	context.p_rcvd_rec = p_rcvd_rec;
	context.p_list = &rec_list;
	context.comp_mask = p_rcvd_mad->comp_mask;
	context.sa = sa;
	context.block_num = p_rcvd_rec->block_num;
	context.p_req_physp = p_req_physp;

	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
		"Got Query Lid:%u(%02X), Block:0x%02X(%02X), Port:0x%02X(%02X)\n",
		cl_ntoh16(p_rcvd_rec->lid),
		(comp_mask & IB_PKEY_COMPMASK_LID) != 0, p_rcvd_rec->port_num,
		(comp_mask & IB_PKEY_COMPMASK_PORT) != 0, p_rcvd_rec->block_num,
		(comp_mask & IB_PKEY_COMPMASK_BLOCK) != 0);

	cl_plock_acquire(sa->p_lock);

	/*
	   If the user specified a LID, it obviously narrows our
	   work load, since we don't have to search every port
	 */
	if (comp_mask & IB_PKEY_COMPMASK_LID) {
		status = osm_get_port_by_base_lid(sa->p_subn, p_rcvd_rec->lid,
						  &p_port);
		if (status != IB_SUCCESS || p_port == NULL) {
			status = IB_NOT_FOUND;
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 460B: "
				"No port found with LID %u\n",
				cl_ntoh16(p_rcvd_rec->lid));
		}
	}

	if (status == IB_SUCCESS) {
		/* if we got a unique port - no need for a port search */
		if (p_port)
			/* this does the loop on all the port phys ports */
			__osm_sa_pkey_by_comp_mask(sa, p_port, &context);
		else
			cl_qmap_apply_func(&sa->p_subn->port_guid_tbl,
					   __osm_sa_pkey_by_comp_mask_cb,
					   &context);
	}

	cl_plock_release(sa->p_lock);

	osm_sa_respond(sa, p_madw, sizeof(ib_pkey_table_record_t), &rec_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #18
0
osm_signal_t osm_qos_setup(osm_opensm_t * p_osm)
{
	struct qos_config ca_config, sw0_config, swe_config, rtr_config;
	struct qos_config *cfg;
	cl_qmap_t *p_tbl;
	cl_map_item_t *p_next;
	osm_port_t *p_port;
	uint32_t num_physp;
	osm_physp_t *p_physp;
	osm_node_t *p_node;
	ib_api_status_t status;
	unsigned force_update;
	uint8_t i;

	if (!p_osm->subn.opt.qos)
		return OSM_SIGNAL_DONE;

	OSM_LOG_ENTER(&p_osm->log);

	qos_build_config(&ca_config, &p_osm->subn.opt.qos_ca_options,
			 &p_osm->subn.opt.qos_options);
	qos_build_config(&sw0_config, &p_osm->subn.opt.qos_sw0_options,
			 &p_osm->subn.opt.qos_options);
	qos_build_config(&swe_config, &p_osm->subn.opt.qos_swe_options,
			 &p_osm->subn.opt.qos_options);
	qos_build_config(&rtr_config, &p_osm->subn.opt.qos_rtr_options,
			 &p_osm->subn.opt.qos_options);

	cl_plock_excl_acquire(&p_osm->lock);

	/* read QoS policy config file */
	osm_qos_parse_policy_file(&p_osm->subn);

	p_tbl = &p_osm->subn.port_guid_tbl;
	p_next = cl_qmap_head(p_tbl);
	while (p_next != cl_qmap_end(p_tbl)) {
		p_port = (osm_port_t *) p_next;
		p_next = cl_qmap_next(p_next);

		p_node = p_port->p_node;
		if (p_node->sw) {
			num_physp = osm_node_get_num_physp(p_node);
			for (i = 1; i < num_physp; i++) {
				p_physp = osm_node_get_physp_ptr(p_node, i);
				if (!p_physp)
					continue;
				force_update = p_physp->need_update ||
				    p_osm->subn.need_update;
				status =
				    qos_physp_setup(&p_osm->log, &p_osm->sm,
						    p_port, p_physp, i,
						    force_update, &swe_config);
			}
			/* skip base port 0 */
			if (!ib_switch_info_is_enhanced_port0
			    (&p_node->sw->switch_info))
				continue;

			cfg = &sw0_config;
		} else if (osm_node_get_type(p_node) == IB_NODE_TYPE_ROUTER)
			cfg = &rtr_config;
		else
			cfg = &ca_config;

		p_physp = p_port->p_physp;
		if (!p_physp)
			continue;

		force_update = p_physp->need_update || p_osm->subn.need_update;
		status = qos_physp_setup(&p_osm->log, &p_osm->sm,
					 p_port, p_physp, 0, force_update, cfg);
	}

	cl_plock_release(&p_osm->lock);
	OSM_LOG_EXIT(&p_osm->log);

	return OSM_SIGNAL_DONE;
}
Пример #19
0
void osm_lftr_rcv_process(IN void *ctx, IN void *data)
{
	osm_sa_t *sa = ctx;
	osm_madw_t *p_madw = data;
	const ib_sa_mad_t *p_rcvd_mad;
	const ib_lft_record_t *p_rcvd_rec;
	cl_qlist_t rec_list;
	osm_lftr_search_ctxt_t context;
	osm_physp_t *p_req_physp;

	CL_ASSERT(sa);

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);

	p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_rcvd_rec = (ib_lft_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);

	CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_LFT_RECORD);

	/* we only support SubnAdmGet and SubnAdmGetTable methods */
	if (p_rcvd_mad->method != IB_MAD_METHOD_GET &&
	    p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4408: "
			"Unsupported Method (%s)\n",
			ib_get_sa_method_str(p_rcvd_mad->method));
		osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
		goto Exit;
	}

	/* update the requester physical port */
	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
						osm_madw_get_mad_addr_ptr
						(p_madw));
	if (p_req_physp == NULL) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4407: "
			"Cannot find requester physical port\n");
		goto Exit;
	}

	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
		"Requester port GUID 0x%" PRIx64 "\n",
		cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));

	cl_qlist_init(&rec_list);

	context.p_rcvd_rec = p_rcvd_rec;
	context.p_list = &rec_list;
	context.comp_mask = p_rcvd_mad->comp_mask;
	context.sa = sa;
	context.p_req_physp = p_req_physp;

	cl_plock_acquire(sa->p_lock);

	/* Go over all switches */
	cl_qmap_apply_func(&sa->p_subn->sw_guid_tbl, lftr_rcv_by_comp_mask,
			   &context);

	cl_plock_release(sa->p_lock);

	osm_sa_respond(sa, p_madw, sizeof(ib_lft_record_t), &rec_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #20
0
void osm_smir_rcv_process(IN void *ctx, IN void *data)
{
	osm_sa_t *sa = ctx;
	osm_madw_t *p_madw = data;
	const ib_sa_mad_t *sad_mad;
	const ib_sminfo_record_t *p_rcvd_rec;
	const osm_port_t *p_port = NULL;
	const ib_sm_info_t *p_smi;
	cl_qlist_t rec_list;
	osm_smir_search_ctxt_t context;
	ib_api_status_t status = IB_SUCCESS;
	ib_net64_t comp_mask;
	ib_net64_t port_guid;
	osm_physp_t *p_req_physp;
	osm_port_t *local_port;
	osm_remote_sm_t *p_rem_sm;
	cl_qmap_t *p_sm_guid_tbl;
	uint8_t pri_state;

	CL_ASSERT(sa);

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);

	sad_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_rcvd_rec = (ib_sminfo_record_t *) ib_sa_mad_get_payload_ptr(sad_mad);
	comp_mask = sad_mad->comp_mask;

	CL_ASSERT(sad_mad->attr_id == IB_MAD_ATTR_SMINFO_RECORD);

	/* we only support SubnAdmGet and SubnAdmGetTable methods */
	if (sad_mad->method != IB_MAD_METHOD_GET &&
	    sad_mad->method != IB_MAD_METHOD_GETTABLE) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2804: "
			"Unsupported Method (%s)\n",
			ib_get_sa_method_str(sad_mad->method));
		osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
		goto Exit;
	}

	/* update the requester physical port */
	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
						osm_madw_get_mad_addr_ptr
						(p_madw));
	if (p_req_physp == NULL) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2803: "
			"Cannot find requester physical port\n");
		goto Exit;
	}

	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Requester port GUID 0x%" PRIx64 "\n",
			cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));
		osm_dump_sm_info_record_v2(sa->p_log, p_rcvd_rec, FILE_ID, OSM_LOG_DEBUG);
	}

	p_smi = &p_rcvd_rec->sm_info;

	cl_qlist_init(&rec_list);

	context.p_rcvd_rec = p_rcvd_rec;
	context.p_list = &rec_list;
	context.comp_mask = sad_mad->comp_mask;
	context.sa = sa;
	context.p_req_physp = p_req_physp;

	cl_plock_acquire(sa->p_lock);

	/*
	   If the user specified a LID, it obviously narrows our
	   work load, since we don't have to search every port
	 */
	if (comp_mask & IB_SMIR_COMPMASK_LID) {
		p_port = osm_get_port_by_lid(sa->p_subn, p_rcvd_rec->lid);
		if (!p_port) {
			status = IB_NOT_FOUND;
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2806: "
				"No port found with LID %u\n",
				cl_ntoh16(p_rcvd_rec->lid));
		}
	}

	if (status == IB_SUCCESS) {
		/* Handle our own SM first */
		local_port = osm_get_port_by_guid(sa->p_subn,
						  sa->p_subn->sm_port_guid);
		if (!local_port) {
			cl_plock_release(sa->p_lock);
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2809: "
				"No port found with GUID 0x%016" PRIx64 "\n",
				cl_ntoh64(sa->p_subn->sm_port_guid));
			goto Exit;
		}

		if (!p_port || local_port == p_port) {
			if (FALSE ==
			    osm_physp_share_pkey(sa->p_log, p_req_physp,
						 local_port->p_physp,
						 sa->p_subn->opt.allow_both_pkeys)) {
				cl_plock_release(sa->p_lock);
				OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2805: "
					"Cannot get SMInfo record due to pkey violation\n");
				goto Exit;
			}

			/* Check that other search components specified match */
			if ((comp_mask & IB_SMIR_COMPMASK_GUID) &&
			    sa->p_subn->sm_port_guid != p_smi->guid)
				goto Remotes;
			if ((comp_mask & IB_SMIR_COMPMASK_PRIORITY) &&
			    sa->p_subn->opt.sm_priority !=
			    ib_sminfo_get_priority(p_smi))
				goto Remotes;
			if ((comp_mask & IB_SMIR_COMPMASK_SMSTATE) &&
			    sa->p_subn->sm_state != ib_sminfo_get_state(p_smi))
				goto Remotes;

			/* Now, add local SMInfo to list */
			pri_state = sa->p_subn->sm_state & 0x0F;
			pri_state |= (sa->p_subn->opt.sm_priority & 0x0F) << 4;
			smir_rcv_new_smir(sa, local_port, context.p_list,
					  sa->p_subn->sm_port_guid,
					  cl_ntoh32(sa->p_subn->p_osm->stats.
						    qp0_mads_sent), pri_state,
					  p_req_physp);
		}

	      Remotes:
		if (p_port && p_port != local_port) {
			/* Find remote SM corresponding to p_port */
			port_guid = osm_port_get_guid(p_port);
			p_sm_guid_tbl = &sa->p_subn->sm_guid_tbl;
			p_rem_sm =
			    (osm_remote_sm_t *) cl_qmap_get(p_sm_guid_tbl,
							    port_guid);
			if (p_rem_sm !=
			    (osm_remote_sm_t *) cl_qmap_end(p_sm_guid_tbl))
				sa_smir_by_comp_mask(sa, p_rem_sm, &context);
			else
				OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 280A: "
					"No remote SM for GUID 0x%016" PRIx64
					"\n", cl_ntoh64(port_guid));
		} else {
			/* Go over all other known (remote) SMs */
			cl_qmap_apply_func(&sa->p_subn->sm_guid_tbl,
					   sa_smir_by_comp_mask_cb, &context);
		}
	}

	cl_plock_release(sa->p_lock);

	osm_sa_respond(sa, p_madw, sizeof(ib_sminfo_record_t), &rec_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #21
0
void osm_lr_rcv_process(IN void *context, IN void *data)
{
	osm_sa_t *sa = context;
	osm_madw_t *p_madw = data;
	const ib_link_record_t *p_lr;
	const ib_sa_mad_t *p_sa_mad;
	const osm_port_t *p_src_port;
	const osm_port_t *p_dest_port;
	cl_qlist_t lr_list;
	ib_net16_t status;
	osm_physp_t *p_req_physp;

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);

	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_lr = ib_sa_mad_get_payload_ptr(p_sa_mad);

	CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_LINK_RECORD);

	/* we only support SubnAdmGet and SubnAdmGetTable methods */
	if (p_sa_mad->method != IB_MAD_METHOD_GET &&
	    p_sa_mad->method != IB_MAD_METHOD_GETTABLE) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1804: "
			"Unsupported Method (%s)\n",
			ib_get_sa_method_str(p_sa_mad->method));
		osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
		goto Exit;
	}

	/* update the requester physical port */
	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
						osm_madw_get_mad_addr_ptr
						(p_madw));
	if (p_req_physp == NULL) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 1805: "
			"Cannot find requester physical port\n");
		goto Exit;
	}

	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Requester port GUID 0x%" PRIx64 "\n",
			cl_ntoh64(osm_physp_get_port_guid(p_req_physp)));
		osm_dump_link_record_v2(sa->p_log, p_lr, FILE_ID, OSM_LOG_DEBUG);
	}

	cl_qlist_init(&lr_list);

	/*
	   Most SA functions (including this one) are read-only on the
	   subnet object, so we grab the lock non-exclusively.
	 */
	cl_plock_acquire(sa->p_lock);

	status = lr_rcv_get_end_points(sa, p_madw, &p_src_port, &p_dest_port);

	if (status == IB_SA_MAD_STATUS_SUCCESS)
		lr_rcv_get_port_links(sa, p_lr, p_src_port, p_dest_port,
				      p_sa_mad->comp_mask, &lr_list,
				      p_req_physp);

	cl_plock_release(sa->p_lock);

	osm_sa_respond(sa, p_madw, sizeof(ib_link_record_t), &lr_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #22
0
void osm_slvl_rec_rcv_process(IN void *ctx, IN void *data)
{
	osm_sa_t *sa = ctx;
	osm_madw_t *p_madw = data;
	const ib_sa_mad_t *p_rcvd_mad;
	const ib_slvl_table_record_t *p_rcvd_rec;
	const osm_port_t *p_port = NULL;
	cl_qlist_t rec_list;
	osm_slvl_search_ctxt_t context;
	ib_api_status_t status = IB_SUCCESS;
	ib_net64_t comp_mask;
	osm_physp_t *p_req_physp;

	CL_ASSERT(sa);

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);

	p_rcvd_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_rcvd_rec =
	    (ib_slvl_table_record_t *) ib_sa_mad_get_payload_ptr(p_rcvd_mad);
	comp_mask = p_rcvd_mad->comp_mask;

	CL_ASSERT(p_rcvd_mad->attr_id == IB_MAD_ATTR_SLVL_RECORD);

	/* we only support SubnAdmGet and SubnAdmGetTable methods */
	if (p_rcvd_mad->method != IB_MAD_METHOD_GET &&
	    p_rcvd_mad->method != IB_MAD_METHOD_GETTABLE) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2604: "
			"Unsupported Method (%s)\n",
			ib_get_sa_method_str(p_rcvd_mad->method));
		osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
		goto Exit;
	}

	/* update the requester physical port. */
	p_req_physp = osm_get_physp_by_mad_addr(sa->p_log, sa->p_subn,
						osm_madw_get_mad_addr_ptr
						(p_madw));
	if (p_req_physp == NULL) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2603: "
			"Cannot find requester physical port\n");
		goto Exit;
	}

	cl_qlist_init(&rec_list);

	context.p_rcvd_rec = p_rcvd_rec;
	context.p_list = &rec_list;
	context.comp_mask = p_rcvd_mad->comp_mask;
	context.sa = sa;
	context.in_port_num = p_rcvd_rec->in_port_num;
	context.p_req_physp = p_req_physp;

	cl_plock_acquire(sa->p_lock);

	OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
		"Got Query Lid:%u(%02X), In-Port:0x%02X(%02X), Out-Port:0x%02X(%02X)\n",
		cl_ntoh16(p_rcvd_rec->lid),
		(comp_mask & IB_SLVL_COMPMASK_LID) != 0,
		p_rcvd_rec->in_port_num,
		(comp_mask & IB_SLVL_COMPMASK_IN_PORT) != 0,
		p_rcvd_rec->out_port_num,
		(comp_mask & IB_SLVL_COMPMASK_OUT_PORT) != 0);

	/*
	   If the user specified a LID, it obviously narrows our
	   work load, since we don't have to search every port
	 */
	if (comp_mask & IB_SLVL_COMPMASK_LID) {
		status =
		    osm_get_port_by_base_lid(sa->p_subn, p_rcvd_rec->lid,
					     &p_port);
		if ((status != IB_SUCCESS) || (p_port == NULL)) {
			status = IB_NOT_FOUND;
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 2608: "
				"No port found with LID %u\n",
				cl_ntoh16(p_rcvd_rec->lid));
		}
	}

	if (status == IB_SUCCESS) {
		/* if we have a unique port - no need for a port search */
		if (p_port)
			/*  this does the loop on all the port phys ports */
			__osm_sa_slvl_by_comp_mask(sa, p_port, &context);
		else
			cl_qmap_apply_func(&sa->p_subn->port_guid_tbl,
					   __osm_sa_slvl_by_comp_mask_cb,
					   &context);
	}

	cl_plock_release(sa->p_lock);

	osm_sa_respond(sa, p_madw, sizeof(ib_slvl_table_record_t), &rec_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #23
0
/**********************************************************************
 * perfmgr_db_data_cnt_reading_t functions
 **********************************************************************/
perfmgr_db_err_t
perfmgr_db_add_dc_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port,
			  perfmgr_db_data_cnt_reading_t * reading,
			  int ietf_sup)
{
	db_port_t *p_port = NULL;
	db_node_t *node = NULL;
	perfmgr_db_data_cnt_reading_t *previous = NULL;
	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
	osm_epi_dc_event_t epi_dc_data;

	cl_plock_excl_acquire(&db->lock);
	node = get(db, guid);
	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
		goto Exit;

	mark_port_valid(node, port);

	p_port = &node->ports[port];
	previous = &node->ports[port].dc_previous;

	debug_dump_dc_reading(db, guid, port, p_port, reading);

	epi_dc_data.time_diff_s = reading->time - previous->time;
	osm_epi_create_port_id(&epi_dc_data.port_id, guid, port,
			       node->node_name);

	/* calculate changes from previous reading */
	epi_dc_data.xmit_data = reading->xmit_data - previous->xmit_data;
	p_port->dc_total.xmit_data += epi_dc_data.xmit_data;
	epi_dc_data.rcv_data = reading->rcv_data - previous->rcv_data;
	p_port->dc_total.rcv_data += epi_dc_data.rcv_data;
	epi_dc_data.xmit_pkts = reading->xmit_pkts - previous->xmit_pkts;
	p_port->dc_total.xmit_pkts += epi_dc_data.xmit_pkts;
	epi_dc_data.rcv_pkts = reading->rcv_pkts - previous->rcv_pkts;
	p_port->dc_total.rcv_pkts += epi_dc_data.rcv_pkts;

	if (ietf_sup)
	{
		epi_dc_data.unicast_xmit_pkts =
		    reading->unicast_xmit_pkts - previous->unicast_xmit_pkts;
		p_port->dc_total.unicast_xmit_pkts += epi_dc_data.unicast_xmit_pkts;
		epi_dc_data.unicast_rcv_pkts =
		    reading->unicast_rcv_pkts - previous->unicast_rcv_pkts;
		p_port->dc_total.unicast_rcv_pkts += epi_dc_data.unicast_rcv_pkts;
		epi_dc_data.multicast_xmit_pkts =
		    reading->multicast_xmit_pkts - previous->multicast_xmit_pkts;
		p_port->dc_total.multicast_xmit_pkts += epi_dc_data.multicast_xmit_pkts;
		epi_dc_data.multicast_rcv_pkts =
		    reading->multicast_rcv_pkts - previous->multicast_rcv_pkts;
		p_port->dc_total.multicast_rcv_pkts += epi_dc_data.multicast_rcv_pkts;
	}

	p_port->dc_previous = *reading;

	/* mark the time this total was updated */
	p_port->dc_total.time = reading->time;

	osm_opensm_report_event(db->perfmgr->osm,
				OSM_EVENT_ID_PORT_DATA_COUNTERS, &epi_dc_data);

Exit:
	cl_plock_release(&db->lock);
	return rc;
}
Пример #24
0
/**********************************************************************
 * perfmgr_db_err_reading_t functions
 **********************************************************************/
perfmgr_db_err_t
perfmgr_db_add_err_reading(perfmgr_db_t * db, uint64_t guid, uint8_t port,
			   perfmgr_db_err_reading_t * reading)
{
	db_port_t *p_port = NULL;
	db_node_t *node = NULL;
	perfmgr_db_err_reading_t *previous = NULL;
	perfmgr_db_err_t rc = PERFMGR_EVENT_DB_SUCCESS;
	osm_epi_pe_event_t epi_pe_data;

	cl_plock_excl_acquire(&db->lock);
	node = get(db, guid);
	if ((rc = bad_node_port(node, port)) != PERFMGR_EVENT_DB_SUCCESS)
		goto Exit;

	mark_port_valid(node, port);

	p_port = &(node->ports[port]);
	previous = &(node->ports[port].err_previous);

	debug_dump_err_reading(db, guid, port, p_port, reading);

	epi_pe_data.time_diff_s = (reading->time - previous->time);
	osm_epi_create_port_id(&epi_pe_data.port_id, guid, port,
			       node->node_name);

	/* calculate changes from previous reading */
	epi_pe_data.symbol_err_cnt =
	    (reading->symbol_err_cnt - previous->symbol_err_cnt);
	p_port->err_total.symbol_err_cnt += epi_pe_data.symbol_err_cnt;
	epi_pe_data.link_err_recover =
	    (reading->link_err_recover - previous->link_err_recover);
	p_port->err_total.link_err_recover += epi_pe_data.link_err_recover;
	epi_pe_data.link_downed =
	    (reading->link_downed - previous->link_downed);
	p_port->err_total.link_downed += epi_pe_data.link_downed;
	epi_pe_data.rcv_err = (reading->rcv_err - previous->rcv_err);
	p_port->err_total.rcv_err += epi_pe_data.rcv_err;
	epi_pe_data.rcv_rem_phys_err =
	    (reading->rcv_rem_phys_err - previous->rcv_rem_phys_err);
	p_port->err_total.rcv_rem_phys_err += epi_pe_data.rcv_rem_phys_err;
	epi_pe_data.rcv_switch_relay_err =
	    (reading->rcv_switch_relay_err - previous->rcv_switch_relay_err);
	p_port->err_total.rcv_switch_relay_err +=
	    epi_pe_data.rcv_switch_relay_err;
	epi_pe_data.xmit_discards =
	    (reading->xmit_discards - previous->xmit_discards);
	p_port->err_total.xmit_discards += epi_pe_data.xmit_discards;
	epi_pe_data.xmit_constraint_err =
	    (reading->xmit_constraint_err - previous->xmit_constraint_err);
	p_port->err_total.xmit_constraint_err +=
	    epi_pe_data.xmit_constraint_err;
	epi_pe_data.rcv_constraint_err =
	    (reading->rcv_constraint_err - previous->rcv_constraint_err);
	p_port->err_total.rcv_constraint_err += epi_pe_data.rcv_constraint_err;
	epi_pe_data.link_integrity =
	    (reading->link_integrity - previous->link_integrity);
	p_port->err_total.link_integrity += epi_pe_data.link_integrity;
	epi_pe_data.buffer_overrun =
	    (reading->buffer_overrun - previous->buffer_overrun);
	p_port->err_total.buffer_overrun += epi_pe_data.buffer_overrun;
	epi_pe_data.vl15_dropped =
	    (reading->vl15_dropped - previous->vl15_dropped);
	p_port->err_total.vl15_dropped += epi_pe_data.vl15_dropped;
	epi_pe_data.xmit_wait =
	    (reading->xmit_wait - previous->xmit_wait);
	p_port->err_total.xmit_wait += epi_pe_data.xmit_wait;

	p_port->err_previous = *reading;

	/* mark the time this total was updated */
	p_port->err_total.time = reading->time;

	osm_opensm_report_event(db->perfmgr->osm, OSM_EVENT_ID_PORT_ERRORS,
				&epi_pe_data);

Exit:
	cl_plock_release(&db->lock);
	return rc;
}
Пример #25
0
void osm_mpr_rcv_process(IN void *context, IN void *data)
{
	osm_sa_t *sa = context;
	osm_madw_t *p_madw = data;
	const ib_multipath_rec_t *p_mpr;
	ib_sa_mad_t *p_sa_mad;
	osm_port_t *requester_port;
	osm_alias_guid_t *pp_alias_guids[IB_MULTIPATH_MAX_GIDS];
	cl_qlist_t pr_list;
	ib_net16_t sa_status;
	int nsrc, ndest;
	uint8_t rate, mtu;

	OSM_LOG_ENTER(sa->p_log);

	CL_ASSERT(p_madw);

	p_sa_mad = osm_madw_get_sa_mad_ptr(p_madw);
	p_mpr = (ib_multipath_rec_t *) ib_sa_mad_get_payload_ptr(p_sa_mad);

	CL_ASSERT(p_sa_mad->attr_id == IB_MAD_ATTR_MULTIPATH_RECORD);

	if ((p_sa_mad->rmpp_flags & IB_RMPP_FLAG_ACTIVE) != IB_RMPP_FLAG_ACTIVE) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4510: "
			"Invalid request since RMPP_FLAG_ACTIVE is not set\n");
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_REQ_INVALID);
		goto Exit;
	}

	/* we only support SubnAdmGetMulti method */
	if (p_sa_mad->method != IB_MAD_METHOD_GETMULTI) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4513: "
			"Unsupported Method (%s)\n",
			ib_get_sa_method_str(p_sa_mad->method));
		osm_sa_send_error(sa, p_madw, IB_MAD_STATUS_UNSUP_METHOD_ATTR);
		goto Exit;
	}

	/* update the requester physical port */
	requester_port = osm_get_port_by_mad_addr(sa->p_log, sa->p_subn,
						  osm_madw_get_mad_addr_ptr
						  (p_madw));
	if (requester_port == NULL) {
		OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4517: "
			"Cannot find requester physical port\n");
		goto Exit;
	}

	if (OSM_LOG_IS_ACTIVE_V2(sa->p_log, OSM_LOG_DEBUG)) {
		OSM_LOG(sa->p_log, OSM_LOG_DEBUG,
			"Requester port GUID 0x%" PRIx64 "\n",
			cl_ntoh64(osm_port_get_guid(requester_port)));
		osm_dump_multipath_record_v2(sa->p_log, p_mpr, FILE_ID, OSM_LOG_DEBUG);
	}

	/* Make sure required components (S/DGIDCount) are supplied */
	if (!(p_sa_mad->comp_mask & IB_MPR_COMPMASK_SGIDCOUNT) ||
	    !(p_sa_mad->comp_mask & IB_MPR_COMPMASK_DGIDCOUNT)) {
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_INSUF_COMPS);
		goto Exit;
	}

	/* Validate rate if supplied */
	if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_RATESELEC) &&
	    (p_sa_mad->comp_mask & IB_MPR_COMPMASK_RATE)) {
		rate = ib_multipath_rec_rate(p_mpr);
		if (!ib_rate_is_valid(rate)) {
			osm_sa_send_error(sa, p_madw,
					  IB_SA_MAD_STATUS_REQ_INVALID);
			goto Exit;
		}
	}
	/* Validate MTU if supplied */
	if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_MTUSELEC) &&
	    (p_sa_mad->comp_mask & IB_MPR_COMPMASK_MTU)) {
		mtu = ib_multipath_rec_mtu(p_mpr);
		if (!ib_mtu_is_valid(mtu)) {
			osm_sa_send_error(sa, p_madw,
					  IB_SA_MAD_STATUS_REQ_INVALID);
			goto Exit;
		}
	}

	/* Make sure either none or both ServiceID parameters are supplied */
	if ((p_sa_mad->comp_mask & IB_MPR_COMPMASK_SERVICEID) != 0 &&
	    (p_sa_mad->comp_mask & IB_MPR_COMPMASK_SERVICEID) !=
	     IB_MPR_COMPMASK_SERVICEID) {
		osm_sa_send_error(sa, p_madw, IB_SA_MAD_STATUS_INSUF_COMPS);
		goto Exit;
	}

	cl_qlist_init(&pr_list);

	/*
	   Most SA functions (including this one) are read-only on the
	   subnet object, so we grab the lock non-exclusively.
	 */
	cl_plock_acquire(sa->p_lock);

	sa_status = mpr_rcv_get_end_points(sa, p_madw, pp_alias_guids,
					   &nsrc, &ndest);

	if (sa_status != IB_SA_MAD_STATUS_SUCCESS || !nsrc || !ndest) {
		if (sa_status == IB_SA_MAD_STATUS_SUCCESS && (!nsrc || !ndest))
			OSM_LOG(sa->p_log, OSM_LOG_ERROR, "ERR 4512: "
				"mpr_rcv_get_end_points failed, # GIDs found; "
				"src %d; dest %d)\n", nsrc, ndest);
		cl_plock_release(sa->p_lock);
		if (sa_status == IB_SA_MAD_STATUS_SUCCESS)
			osm_sa_send_error(sa, p_madw,
					  IB_SA_MAD_STATUS_REQ_INVALID);
		else
			osm_sa_send_error(sa, p_madw, sa_status);
		goto Exit;
	}

	/* APM request */
	if (nsrc == 2 && ndest == 2 && (p_mpr->num_path & 0x7F) == 2)
		mpr_rcv_get_apm_paths(sa, p_mpr, requester_port, pp_alias_guids,
				      p_sa_mad->comp_mask, &pr_list);
	else
		mpr_rcv_process_pairs(sa, p_mpr, requester_port, pp_alias_guids,
				      nsrc, ndest, p_sa_mad->comp_mask,
				      &pr_list);

	cl_plock_release(sa->p_lock);

	/* o15-0.2.7: If MultiPath is supported, then SA shall respond to a
	   SubnAdmGetMulti() containing a valid MultiPathRecord attribute with
	   a set of zero or more PathRecords satisfying the constraints
	   indicated in the MultiPathRecord received. The PathRecord Attribute
	   ID shall be used in the response.
	 */
	p_sa_mad->attr_id = IB_MAD_ATTR_PATH_RECORD;
	osm_sa_respond(sa, p_madw, sizeof(ib_path_rec_t), &pr_list);

Exit:
	OSM_LOG_EXIT(sa->p_log);
}
Пример #26
0
int osm_qos_setup(osm_opensm_t * p_osm)
{
	struct qos_config ca_config, sw0_config, swe_config, rtr_config;
	struct qos_config *cfg;
	cl_qmap_t *p_tbl;
	cl_map_item_t *p_next;
	osm_port_t *p_port;
	osm_node_t *p_node;
	int ret = 0;
	int vlarb_only;
	qos_mad_list_t *p_list, *p_list_next;
	qos_mad_item_t *p_port_mad;
	cl_qlist_t qos_mad_list;

	if (!p_osm->subn.opt.qos)
		return 0;

	OSM_LOG_ENTER(&p_osm->log);

	qos_build_config(&ca_config, &p_osm->subn.opt.qos_ca_options,
			 &p_osm->subn.opt.qos_options);
	qos_build_config(&sw0_config, &p_osm->subn.opt.qos_sw0_options,
			 &p_osm->subn.opt.qos_options);
	qos_build_config(&swe_config, &p_osm->subn.opt.qos_swe_options,
			 &p_osm->subn.opt.qos_options);
	qos_build_config(&rtr_config, &p_osm->subn.opt.qos_rtr_options,
			 &p_osm->subn.opt.qos_options);

	cl_qlist_init(&qos_mad_list);

	cl_plock_excl_acquire(&p_osm->lock);

	/* read QoS policy config file */
	osm_qos_parse_policy_file(&p_osm->subn);
	p_tbl = &p_osm->subn.port_guid_tbl;
	p_next = cl_qmap_head(p_tbl);
	while (p_next != cl_qmap_end(p_tbl)) {
		vlarb_only = 0;
		p_port = (osm_port_t *) p_next;
		p_next = cl_qmap_next(p_next);

		p_list = (qos_mad_list_t *) malloc(sizeof(*p_list));
		if (!p_list)
			return -1;

		memset(p_list, 0, sizeof(*p_list));

		cl_qlist_init(&p_list->port_mad_list);

		p_node = p_port->p_node;
		if (p_node->sw) {
			if (qos_extports_setup(&p_osm->sm, p_node, &swe_config,
					       &p_list->port_mad_list))
				ret = -1;

			/* skip base port 0 */
			if (!ib_switch_info_is_enhanced_port0
			    (&p_node->sw->switch_info))
				goto Continue;

			if (ib_switch_info_get_opt_sl2vlmapping(&p_node->sw->switch_info) &&
			    p_osm->sm.p_subn->opt.use_optimized_slvl &&
			    !memcmp(&swe_config.sl2vl, &sw0_config.sl2vl,
				    sizeof(swe_config.sl2vl)))
				vlarb_only = 1;

			cfg = &sw0_config;
		} else if (osm_node_get_type(p_node) == IB_NODE_TYPE_ROUTER)
			cfg = &rtr_config;
		else
			cfg = &ca_config;

		if (qos_endport_setup(&p_osm->sm, p_port->p_physp, cfg,
				      vlarb_only, &p_list->port_mad_list))

			ret = -1;
Continue:
		/* if MAD list is not empty, add it to the global MAD list */
		if (cl_qlist_count(&p_list->port_mad_list)) {
			cl_qlist_insert_tail(&qos_mad_list, &p_list->list_item);
		} else {
			free(p_list);
		}
	}
	while (cl_qlist_count(&qos_mad_list)) {
		p_list_next = (qos_mad_list_t *) cl_qlist_head(&qos_mad_list);
		while (p_list_next !=
			(qos_mad_list_t *) cl_qlist_end(&qos_mad_list)) {
			p_list = p_list_next;
			p_list_next = (qos_mad_list_t *)
				      cl_qlist_next(&p_list->list_item);
			/* next MAD to send*/
			p_port_mad = (qos_mad_item_t *)
				     cl_qlist_remove_head(&p_list->port_mad_list);
			osm_send_req_mad(&p_osm->sm, p_port_mad->p_madw);
			osm_qos_mad_delete(&p_port_mad);
			/* remove the QoS MAD from global MAD list */
			if (cl_qlist_count(&p_list->port_mad_list) == 0) {
				cl_qlist_remove_item(&qos_mad_list, &p_list->list_item);
				free(p_list);
			}
		}
	}

	cl_plock_release(&p_osm->lock);
	OSM_LOG_EXIT(&p_osm->log);

	return ret;
}