wrsm_barrier.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2001 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* This file implements RSMPI barriers in the Wildcat RSM driver.
*/
#include <sys/wrsm_barrier.h>
#include <sys/wrsm_common.h>
#include <sys/wrsm_session.h>
#include <sys/wrsm_memseg_impl.h>
#include <sys/wci_regs.h>
/*
* The following macros define a DPRINTF macro which can be used to enable
* or disable various levels of logging for this module.
*/
#ifdef DEBUG
#define BARDBG 0x1
#define BARWARN 0x2
#define BARERR 0x4
#define BARTRACE 0x8
#else /* DEBUG */
#define DPRINTF(a, b) { }
#define PRINT_BAR(a, b) { }
#endif /* DEBUG */
/*
* Local types
*/
#define BARRIER_TIME_REGION 0
#define BARRIER_TIME_REGIONS 1
#define BARRIER_TIME_NODE 2
#define BARRIER_TIME_CONTROLLER 3
#define BARRIER_THREAD_REGION 4
#define BARRIER_THREAD_REGIONS 5
#define BARRIER_THREAD_NODE 6
#define BARRIER_THREAD_CONTROLLER 7
typedef unsigned char wrsm_barrier_scope_t;
#ifdef DEBUG
/* The following array is used in wrsm_print_barrier, for debug only */
static const char *scope_txt[] = {
"BARRIER_TIME_REGION",
"BARRIER_TIME_REGIONS",
"BARRIER_TIME_NODE",
"BARRIER_TIME_CONTROLLER",
"BARRIER_THREAD_REGION",
"BARRIER_THREAD_REGIONS",
"BARRIER_THREAD_NODE",
"BARRIER_THREAD_CONTROLLER"};
#endif /* DEBUG */
/* Define state flags to help ensure that barrier is really initialized */
typedef unsigned char wrsm_barrier_state_t;
/* This struct is an overlay for rsm_barrier_t */
typedef struct {
void *parent; /* network, importseg or array of importsegs */
int num_regions; /* if multiple importsegs */
/*
* Local Functions
*/
/*
* This function sums the wci_cluster_error_count register for all WCIs
* routing to the given ncslice (i.e., remote node). It does this by
* reading the wci_cluster_error_count mapped into the stripes of page 0
* of the nslice.
*/
static uint64_t
{
int stripes;
if (stripes & 1) {
/* Sum in errors for this stripe */
}
}
return (total);
}
/* Sums wci_cluster_error_counts for all nodes in nodes bitmask */
static int
{
int i;
/* If we're in the process of rerouting, return MAX INT */
if (*net->reroutingp) {
*sum = UINT64_MAX;
return (RSM_SUCCESS);
}
*sum = 0;
/* Loop for each node in the set. Exit early once set is empty */
if (WRSM_IN_SET(cnodes, i)) {
return (RSMERR_CONN_ABORTED);
}
*node->link_stripesp);
}
/* Remove this node from the list, hoping for early exit */
WRSMSET_DEL(cnodes, i);
}
return (RSM_SUCCESS);
}
/*
* RSMPI Functions
*/
/* ARGSUSED */
int
{
DTRC("wrsm_open_barrier_ctrl");
/* LINTED: E_TRUE_LOGICAL_EXPR */
return (RSMERR_UNSUPPORTED_OPERATION);
}
int
{
/* LINTED: E_TRUE_LOGICAL_EXPR */
return (RSMERR_BAD_BARRIER_PTR);
}
return (RSMERR_BAD_CTLR_HNDL);
}
if (addr >= WRSM_MAX_CNODES) {
return (RSMERR_UNKNOWN_RSM_ADDR);
}
if (!node) {
return (RSMERR_UNKNOWN_RSM_ADDR);
}
/* Read route counter */
*node->link_stripesp);
/* Make sure a session is established with the remote node */
return (RSM_SUCCESS);
}
int
{
int err;
DTRC("wrsm_open_barrier_region");
/* LINTED: E_TRUE_LOGICAL_EXPR */
return (RSMERR_BAD_SEG_HNDL);
}
return (RSMERR_BAD_BARRIER_PTR);
}
/* we assume importseg will not be removed during barrier */
return (err);
}
int
{
uint_t i;
int err;
DTRC("wrsm_open_barrier_regions");
/* LINTED: E_TRUE_LOGICAL_EXPR */
return (RSMERR_BAD_BARRIER_PTR);
}
if (num_regions == 0) {
return (RSMERR_BAD_SEG_HNDL);
}
for (i = 0; i < num_regions; i++) {
return (RSMERR_BAD_SEG_HNDL);
}
}
/* we assume importsegs will not be removed during barrier */
if (!err) {
(num_regions * sizeof (importseg_t *)));
bar->transfer_errors = 0;
for (i = 0; i < num_regions; i++) {
bar->transfer_errors +=
}
}
return (err);
}
int
{
DTRC("wrsm_open_barrier_ctrl_thr");
}
int
{
DTRC("wrsm_open_barrier_node_thr");
}
int
{
DTRC("wrsm_open_barrier_region_thr");
}
int
{
DTRC("wrsm_open_barrier_regions_thr");
}
static int
{
DTRC("close_barrier_time_node");
/* Check to see if there were any errors */
WARN("Barrier failed: error reading wci cluster error count");
return (RSMERR_BARRIER_FAILURE);
}
WARN("Barrier failed: wci errors detected");
return (RSMERR_BARRIER_FAILURE);
}
/* Make sure route hasn't changed */
WARN("Barrier failed: route changed");
return (RSMERR_BARRIER_FAILURE);
}
return (RSM_SUCCESS);
}
static int
{
int err;
DTRC("close_barrier_time_nodes");
/* Check to see if there were any errors */
WARN("Barrier failed: error reading wci cluster error count");
return (RSMERR_BARRIER_FAILURE);
}
/* Sum errors for those remote nodes */
if (err) {
return (err);
}
WARN("Barrier failed: wci errors detected");
return (RSMERR_BARRIER_FAILURE);
}
/* Make sure route hasn't changed */
WARN("Barrier failed: route changed");
return (RSMERR_BARRIER_FAILURE);
}
return (RSM_SUCCESS);
}
int
{
int i;
int err = 0;
int retval = 0;
DTRC("wrsm_close_barrier");
WARN("Barrier failed: barrier pointer is NULL");
return (RSMERR_BAD_BARRIER_PTR);
}
WARN("Barrier failed: Barrier not open");
return (RSMERR_BARRIER_NOT_OPENED);
}
case BARRIER_TIME_REGION:
if (importseg->unpublished) {
WARN("Barrier failed: importseg was unpublished");
return (RSMERR_CONN_ABORTED);
}
if (bar->transfer_errors !=
"Barrier failed: transfer errors; last err %d",
}
WARN("Barrier failed: unknown node");
} else {
/* Flush links to remote node */
*node->link_stripesp);
}
if (retval == RSM_SUCCESS) {
}
break;
case BARRIER_TIME_REGIONS:
/* get net from first importseg */
for (i = 0; i < bar->num_regions; i++) {
importseg = importseg_list[i];
if (importseg->unpublished) {
sizeof (importseg_t *)));
WARN("Barrier failed: importseg unpublished");
return (RSMERR_CONN_ABORTED);
}
/* Remember the first error encountered */
if (err == 0) {
}
if (retval == RSM_SUCCESS) {
WARN("Barrier failed: unknown node");
} else {
/* Flush links to remote node */
*node->link_stripesp);
}
}
}
"Barrier failed: transfer errors, last error %d",
err));
return (err);
}
if (retval == RSM_SUCCESS) {
}
break;
case BARRIER_TIME_NODE:
if (!node) {
WARN("Barrier failed: node doesn't exist");
return (RSMERR_CONN_ABORTED);
}
SESS_ID_INVALID)) {
WARN("Barrier failed: no session to remote node");
return (RSMERR_CONN_ABORTED);
}
"Barrier failed: transfer error; last err %d",
err));
return (err);
}
/* Flush links to remote node */
*node->link_stripesp);
if (retval == RSM_SUCCESS) {
}
break;
case BARRIER_TIME_CONTROLLER:
break;
default:
ERR("Invalid barrier data");
}
#ifdef DEBUG
if (retval) {
}
#endif
return (retval);
}
int
{
int retval;
DTRC("wrsm_reopen_barrier");
WARN("Barrier failed: barrier pointer is NULL");
return (RSMERR_BAD_BARRIER_PTR);
}
case BARRIER_TIME_NODE:
break;
case BARRIER_TIME_REGION:
break;
case BARRIER_TIME_REGIONS:
sizeof (rsm_memseg_import_handle_t *), KM_SLEEP);
num_regions * sizeof (rsm_memseg_import_handle_t *));
barrier);
num_regions * sizeof (rsm_memseg_import_handle_t *));
break;
default:
}
return (retval);
}
int
{
int i;
int retval = 0;
DTRC("wrsm_order_barrier");
WARN("Barrier failed: barrier pointer is NULL");
return (RSMERR_BAD_BARRIER_PTR);
}
WARN("Barrier failed: Barrier not open");
return (RSMERR_BARRIER_NOT_OPENED);
}
/* Figure out which remote cnode(s) we need to flush */
case BARRIER_TIME_REGION:
if (node) {
*node->link_stripesp);
} else {
}
break;
case BARRIER_TIME_REGIONS:
/* get net from first importseg */
for (i = 0; i < bar->num_regions; i++) {
if (node) {
*node->link_stripesp);
} else {
}
}
break;
case BARRIER_TIME_NODE:
if (node) {
*node->link_stripesp);
} else {
}
break;
case BARRIER_TIME_CONTROLLER:
break;
default:
ERR("Invalid barrier data");
}
return (retval);
}
int
{
DTRC("wrsm_thread_init");
return (RSMERR_BAD_CTLR_HNDL);
}
/* Thread Barriers not yet implemented, so nothing to do */
return (RSM_SUCCESS);
}
int
{
DTRC("wrsm_thread_fini");
return (RSMERR_BAD_CTLR_HNDL);
}
/* Thread Barriers not yet implemented, so nothing to do */
return (RSM_SUCCESS);
}
int
{
int err;
DTRC("wrsm_get_barrier_mode");
return (err);
}
return (RSM_SUCCESS);
}
int
{
int err;
"wrsm_set_barrier_mode: importseg 0x%p mode %d",
if ((mode != RSM_BARRIER_MODE_EXPLICIT) &&
return (RSMERR_BAD_MODE);
}
return (err);
}
return (RSM_SUCCESS);
}
#ifdef DEBUG
void
{
}
}
}
#endif /* DEBUG */