예제 #1
0
void dont_advertise_dcbx_all(char *ifname, bool ad)
{
	int i, is_pfc;
	pfc_attribs pfc_data;
	pg_attribs pg_data;
	app_attribs app_data;
	llink_attribs llink_data;
	u32 event_flag = 0;

	is_pfc = get_pfc(ifname, &pfc_data);

	if (get_pg(ifname, &pg_data) == cmd_success) {
		pg_data.protocol.Advertise = ad;
		put_pg(ifname, &pg_data, &pfc_data);
		event_flag |= DCB_LOCAL_CHANGE_PG;
	}

	if (is_pfc == cmd_success) {
		pfc_data.protocol.Advertise = ad;
		put_pfc(ifname, &pfc_data);
		event_flag |= DCB_LOCAL_CHANGE_PFC;
	}

	for (i = 0; i < DCB_MAX_APPTLV ; i++) {
		if (get_app(ifname, (u32)i, &app_data) == cmd_success) {
			app_data.protocol.Advertise = ad;
			put_app(ifname, (u32)i, &app_data);
			event_flag |= DCB_LOCAL_CHANGE_APPTLV(i);
		}
	}

	for (i = 0; i < DCB_MAX_LLKTLV ; i++) {
		if (get_llink(ifname, (u32)i, &llink_data) == cmd_success) {
			llink_data.protocol.Advertise = ad;
			put_llink(ifname, (u32)i, &llink_data);
			event_flag |= DCB_LOCAL_CHANGE_LLINK;
		}
	}
}
예제 #2
0
// Called by validator when canonical result has been selected.
// Compute credit for valid instances.
// This is called exactly once for each valid result.
//
int assign_credit_set(
    WORKUNIT& wu, vector<RESULT>& results,
    DB_APP& app,
    vector<DB_APP_VERSION>& app_versions,
    vector<DB_HOST_APP_VERSION>& host_app_versions,
    double max_granted_credit, double& credit
) {
    unsigned int i;
    int mode, retval;
    double pfc;
    vector<double> normal;
    vector<double> approx;

    for (i=0; i<results.size(); i++) {
        RESULT& r = results[i];
        if (r.validate_state != VALIDATE_STATE_VALID) continue;
        DB_HOST_APP_VERSION& hav = host_app_versions[i];
        retval = get_pfc(r, wu, app, app_versions, hav, pfc, mode);
        if (retval) {
            log_messages.printf(MSG_CRITICAL,
                "get_pfc() error: %s\n", boincerror(retval)
            );
            continue;
        } else {
            if (config.debug_credit) {
                log_messages.printf(MSG_NORMAL,
                    "[credit] [RESULT#%d] get_pfc() returns credit %g mode %s\n",
                    r.id, pfc*COBBLESTONE_SCALE, (mode==PFC_MODE_NORMAL)?"normal":"approx"
                );
            }
        }
        if (pfc > wu.rsc_fpops_bound) {
            log_messages.printf(MSG_NORMAL,
                "[credit] PFC too high: %f\n", pfc*COBBLESTONE_SCALE
            );
            pfc = wu_estimated_pfc(wu, app);
        }

        // max_granted_credit trumps rsc_fpops_bound;
        // the latter may be set absurdly high
        //
        if (max_granted_credit && pfc*COBBLESTONE_SCALE > max_granted_credit) {
            log_messages.printf(MSG_NORMAL,
                "[credit] Credit too high: %f\n", pfc*COBBLESTONE_SCALE
            );
            pfc = max_granted_credit/COBBLESTONE_SCALE;
        }
        if (mode == PFC_MODE_NORMAL) {
            normal.push_back(pfc);
        } else {
            approx.push_back(pfc);
        }
    }

    // averaging policy: if there is least one normal result,
    // use the "low average" of normal results.
    // Otherwise use the min of all results
    //
    double x;
    if (normal.size()) {
        x = low_average(normal);
    } else if (approx.size()) {
        x = vec_min(approx);
    } else {
        x = 0;
    }

    x *= COBBLESTONE_SCALE;
    if (config.debug_credit) {
        log_messages.printf(MSG_NORMAL,
            "[credit] [WU#%d] assign_credit_set: credit %g\n",
            wu.id, x
        );
    }
    credit = x;
    return 0;
}
예제 #3
0
static int set_pg_config(pg_attribs *pg_data, char *port_id, char *ibuf,
	int ilen)
{
	pfc_attribs pfc_data;
	full_dcb_attrib_ptrs dcb_data;
	u8 flag;
	cmd_status status = cmd_success;
	int i, is_pfc;
	int plen;
	int off;
	bool used[MAX_BANDWIDTH_GROUPS];
	bool uppcts_changed = false;

	plen=strlen(port_id);
	off = DCB_PORT_OFF + plen + CFG_LEN;

	if (ilen == (off + CFG_PG_DLEN)) {
		for (i = 0; i < MAX_USER_PRIORITIES; i++) {
			flag = *(ibuf+off+PG_UP2TC(i));
			if (flag == CLIF_NOT_SUPPLIED)
				continue;

			if ((flag & 0x07) >= pg_data->num_tcs)
				return cmd_bad_params;

			pg_data->tx.up[i].pgid = flag & 0x07;
			pg_data->rx.up[i].pgid = flag & 0x07;
		}
		memset(used, false, sizeof(used));
		for (i = 0; i < MAX_BANDWIDTH_GROUPS; i++) {
			if (*(ibuf+off+PG_PG_PCNT(i)) == CLIF_NOT_SUPPLIED)
				continue;
			if (hexstr2bin(ibuf+off+PG_PG_PCNT(i),
				&flag, sizeof(flag)))
				return cmd_bad_params;
			pg_data->tx.pg_percent[i] = flag;
			pg_data->rx.pg_percent[i] = flag;
		}
		for (i = 0; i < MAX_USER_PRIORITIES; i++) {
			flag = *(ibuf+off+PG_UP_PGID(i));
			if (flag == CLIF_NOT_SUPPLIED) {
				if (pg_data->tx.up[i].strict_priority ==
					DCB_LINK)
					flag = LINK_STRICT_PGID;
				else
					flag = pg_data->tx.up[i].pgid;
			} else {
				if (flag == hexlist[LINK_STRICT_PGID] ||
					flag == hexlistcaps[LINK_STRICT_PGID])
					flag = LINK_STRICT_PGID;
				else
					flag = flag & 0x0f;
				pg_data->tx.up[i].pgid = flag;
				pg_data->rx.up[i].pgid = flag;
			}

			/* keep track of which PGID's in the range of
			 * 0-7 are being used (not counting pre-existing
			 * link strict PGID).
			*/
			if (flag < MAX_BANDWIDTH_GROUPS)
				used[flag] = true;
		}
		for (i = 0; i < MAX_USER_PRIORITIES; i++) {
			if (*(ibuf+off+PG_UP_PCNT(i)) == CLIF_NOT_SUPPLIED)
				continue;
			uppcts_changed = true;
			if (hexstr2bin(ibuf+off+PG_UP_PCNT(i),
				&flag, sizeof(flag)))
				return cmd_bad_params;
			pg_data->tx.up[i].percent_of_pg_cap = flag;
			pg_data->rx.up[i].percent_of_pg_cap = flag;
		}
		for (i = 0; i < MAX_USER_PRIORITIES; i++) {
			flag = *(ibuf+off+PG_UP_STRICT(i));
			if (flag == CLIF_NOT_SUPPLIED)
				continue;
			/* only set or clear the group strict bit.
			 * the link strict bit will be handled later.
			*/
			flag = flag & 0x01;
			if (flag) {
				pg_data->tx.up[i].strict_priority |= flag;
				pg_data->rx.up[i].strict_priority |= flag;
			} else {
				pg_data->tx.up[i].strict_priority &= ~DCB_GROUP;
				pg_data->rx.up[i].strict_priority &= ~DCB_GROUP;
			}
		}

		/* find the first unused PGID in range 0-7 */
		for (i = 0; i < MAX_BANDWIDTH_GROUPS; i++)
			if (!used[i])
				break;

		/* The end goal here is to have all of the user priorities
		 * assigned to the link strict PGID to use the lowest
		 * unused value in the range 0-7.  The strict_priority field
		 * is set to 'dcb_link' as well for the link strict PGID.
		 */
		flag = i;
		for (i = 0; i < MAX_USER_PRIORITIES; i++) {
			if (pg_data->tx.up[i].pgid == LINK_STRICT_PGID ||
				(!used[pg_data->tx.up[i].pgid] &&
				pg_data->tx.up[i].strict_priority & DCB_LINK)) {
				pg_data->tx.up[i].pgid = flag;
				pg_data->rx.up[i].pgid = flag;
				pg_data->tx.up[i].strict_priority = DCB_LINK;
				pg_data->rx.up[i].strict_priority = DCB_LINK;
			} else {
				pg_data->tx.up[i].strict_priority &= ~DCB_LINK;
				pg_data->rx.up[i].strict_priority &= ~DCB_LINK;
			}
		}
	} else if (ilen != off) {
		printf("error - setcommand has invalid argument length\n");
		return cmd_bad_params;
	}

	memset((void *)&dcb_data, 0, sizeof(dcb_data));
	dcb_data.pg = pg_data;
	status = dcb_check_config(&dcb_data);

	/* if the rule checking fails and client did not supply
	 * user priority percentages, then compute new percentages
	 * and try one more time.
	*/
	if (status == cmd_bad_params && !uppcts_changed) {
		rebalance_uppcts(pg_data);
		status = dcb_check_config(&dcb_data);
	}

	if (status != cmd_success) {
		printf("invalid DCB settings\n");
		return status;
	}

	is_pfc = get_pfc(port_id, &pfc_data);
	if (is_pfc == cmd_success)
		status = put_pg(port_id, pg_data, &pfc_data);
	else
		status = put_pg(port_id, pg_data, NULL);

	if (status != cmd_success)
		printf("error[%d] setting PG data for %s\n", status, port_id);
	

	return status;
}
예제 #4
0
int dcbx_clif_cmd(UNUSED void *data,
		  UNUSED struct sockaddr_un *from,
		  UNUSED socklen_t fromlen,
		  char *ibuf, int ilen,
		  char *rbuf, int rlen)
{
	u8 status = cmd_success;
	u8 cmd;
	u8 feature;
	u8 subtype;
	u8 plen;
	char port_id[MAX_U8_BUF];
	pg_attribs pg_data;
	pfc_attribs pfc_data;
	app_attribs app_data;
	llink_attribs llink_data;
	struct dcbx_tlvs *dcbx;
	int dcb_enable;

	if (hexstr2bin(ibuf+DCB_CMD_OFF, &cmd, sizeof(cmd)) ||
		hexstr2bin(ibuf+DCB_FEATURE_OFF, &feature, sizeof(feature)))
		return cmd_invalid;

	if (feature == FEATURE_DCBX)
		return handle_dcbx_cmd(cmd, feature, ibuf, ilen, rbuf);

	if (hexstr2bin(ibuf+DCB_SUBTYPE_OFF, &subtype, sizeof(subtype)) ||
		hexstr2bin(ibuf+DCB_PORTLEN_OFF, &plen, sizeof(plen)))
		return cmd_invalid;

	if (ilen < DCB_PORT_OFF)
		return cmd_invalid;
	
	if (ibuf[DCB_VER_OFF] < (CLIF_DCBMSG_VERSION | 0x30)) {
		printf("unsupported client interface message version %x %x\n",
			ibuf[DCB_VER_OFF], CLIF_DCBMSG_VERSION | 0x30);
		return cmd_ctrl_vers_not_compatible;
	}

	if (ilen < DCB_PORT_OFF+plen) {
		printf("command too short\n");
		return cmd_invalid;
	}

	/* append standard dcb command response content */
	snprintf(rbuf , rlen, "%*.*s",
		 DCB_PORT_OFF+plen, DCB_PORT_OFF+plen, ibuf);

	memcpy(port_id, ibuf+DCB_PORT_OFF, plen);
	port_id[plen] = '\0';

	if (get_hw_state(port_id, &dcb_enable) < 0)
		return cmd_not_capable;

	dcbx = dcbx_data(port_id);
	/* OPER and PEER cmd not applicable while in IEEE-DCBX modes */
	if ((!dcbx || dcbx->active == 0) &&
	    (cmd == CMD_GET_PEER || cmd == CMD_GET_OPER))
		return cmd_not_applicable;

	switch(feature) {
	case FEATURE_DCB:
		if (cmd == CMD_SET_CONFIG)
			status = set_dcb_state(port_id, ibuf, ilen);
		else if (cmd == CMD_GET_CONFIG)
			status = get_dcb_state(port_id, rbuf+strlen(rbuf));
		else
			status = cmd_invalid;
		break;

	case FEATURE_PG:
		if (cmd == CMD_GET_PEER) {
			status = get_peer_pg(port_id, &pg_data);
		} else {
			status = get_pg(port_id, &pg_data);
		}

		if (status != cmd_success) {
			printf("error[%d] getting PG data for %s\n",
				status, port_id);
			return status;
		}

		if (cmd == CMD_SET_CONFIG) {
			if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) {
				printf("set command too short\n");
				status = cmd_invalid;
			} else {
				set_protocol_data(&pg_data.protocol, port_id,
						  ibuf, plen, NEAREST_BRIDGE);
				status = set_pg_config(&pg_data, port_id, ibuf,
					ilen);
			}
		} else {
			status = get_cmd_protocol_data(&pg_data.protocol, cmd,
					rbuf+strlen(rbuf));
			if (status == cmd_success)
				status = get_pg_data(&pg_data, cmd, port_id,
					pg_data.protocol.dcbx_st,
					rbuf+strlen(rbuf));
		}
		break;

	case FEATURE_PFC:
		if (cmd == CMD_GET_PEER) {
			status = get_peer_pfc(port_id, &pfc_data);
		} else {
			status = get_pfc(port_id, &pfc_data);
		}

		if (status != cmd_success) {
			printf("error[%d] getting PFC data for %s\n",
					status, port_id);
			return status;
		}

		if (cmd == CMD_SET_CONFIG) {
			if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) {
				printf("set command too short\n");
				status = cmd_failed;
			} else {
				set_protocol_data(&pfc_data.protocol, port_id,
						  ibuf, plen, NEAREST_BRIDGE);
				status = set_pfc_config(&pfc_data, port_id,
					ibuf, ilen);
			}
		} else {
			status = get_cmd_protocol_data(&pfc_data.protocol,
				cmd, rbuf+strlen(rbuf));
			if (status == cmd_success)
				status = get_pfc_data(&pfc_data, cmd,
					port_id, pfc_data.protocol.dcbx_st,
					rbuf+strlen(rbuf));
		}
		break;


	case FEATURE_APP:
		if (cmd == CMD_GET_PEER) {
			status = get_peer_app(port_id, (u32)subtype, &app_data);
		} else {
			status = get_app(port_id, (u32)subtype, &app_data);
		}

		if (status != cmd_success) {
			printf("error[%d] getting APP data for %s\n", status,
				port_id);
			return status;
		}

		if (cmd == CMD_SET_CONFIG) {
			if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) {
				printf("set command too short\n");
				status = cmd_failed;
			} else {
				set_app_protocol_data(port_id, ibuf, plen, ilen,
						      subtype, NEAREST_BRIDGE);
			}
		} else {
			status = get_cmd_protocol_data(&app_data.protocol, cmd,
				rbuf+strlen(rbuf));
			if (status == cmd_success)
				status = get_app_data(&app_data, cmd, port_id,
					subtype, rbuf + strlen(rbuf));
		}
		break;

	case FEATURE_LLINK:
		if (cmd == CMD_GET_PEER) {
			status = get_peer_llink(port_id, (u32)subtype,
				&llink_data);
		} else {
			status = get_llink(port_id, (u32)subtype, &llink_data);
		}

		if (status != cmd_success) {
			printf("error[%d] getting APP data for %s\n", status,
				port_id);
			return status;
		}

		if (cmd == CMD_SET_CONFIG) {
			if (ilen < (DCB_PORT_OFF + plen + CFG_LEN)) {
				printf("set command too short\n");
				status = cmd_failed;
			} else {
				set_protocol_data(&llink_data.protocol, port_id,
						  ibuf, plen, NEAREST_BRIDGE);
				status = set_llink_config(&llink_data, port_id,
					(u32)subtype, ibuf, ilen);
			}
		} else {
			status = get_cmd_protocol_data(&llink_data.protocol,
				cmd, rbuf+strlen(rbuf));
			if (status == cmd_success)
				status = get_llink_data(&llink_data, cmd,
					port_id, subtype, rbuf + strlen(rbuf));
		}
		break;

	case FEATURE_PG_DESC:
		if (cmd == CMD_GET_CONFIG) {
			status = get_bwg_desc(port_id, ibuf, ilen,
					      rbuf+strlen(rbuf));

			if (status != cmd_success) {
				printf("error[%d] getting BWG desc for %s\n",
					status, port_id);
				return status;
			}
		} else if (cmd == CMD_SET_CONFIG) {
			status = set_bwg_desc(port_id, ibuf, ilen);
		}

		break;
	default:
		break;
	}

	return status;
}
예제 #5
0
파일: credit.cpp 프로젝트: UweBeckert/boinc
// Called by validator when canonical result has been selected.
// For each valid result in the list:
// - calculate a peak FLOP count (PFC) and a "mode" that indicates
//   our confidence in the PFC
// - upate the statistics of PFC in host_app_version and app_version
// - Compute a credit value based on a weighted average of
//   the PFCs of valid results
//   (this value can be used or ignored by the caller)
//
// This must be called exactly once for each valid result.
//
int assign_credit_set(
    WORKUNIT &wu,
    vector<RESULT>& results,
    DB_APP &app,
    vector<DB_APP_VERSION_VAL>& app_versions,
    vector<DB_HOST_APP_VERSION>& host_app_versions,
    double max_granted_credit,
    double &credit
) {
    unsigned int i;
    int mode, retval;
    double pfc;
    vector<double> normal;
    vector<double> approx;

    for (i=0; i<results.size(); i++) {
        RESULT &r = results[i];
        if (r.validate_state != VALIDATE_STATE_VALID) {
            continue;
        }
        DB_HOST_APP_VERSION &hav = host_app_versions[i];
        retval = get_pfc(r, wu, app, app_versions, hav, pfc, mode);
        if (retval) {
            log_messages.printf(MSG_CRITICAL,
                "get_pfc() error: %s\n", boincerror(retval)
            );
            continue;
        } else {
            if (config.debug_credit) {
                log_messages.printf(MSG_NORMAL,
                    "[credit] [RESULT#%lu] get_pfc() returns credit %g mode %s\n",
                    r.id, pfc *COBBLESTONE_SCALE, (mode==PFC_MODE_NORMAL)?"normal":"approx"
                );
            }
        }
        if (pfc > wu.rsc_fpops_bound) {
            if (config.debug_credit) {
                log_messages.printf(MSG_NORMAL,
                    "[credit] PFC too high: %f\n", pfc*COBBLESTONE_SCALE
                );
            }
            pfc = wu_estimated_pfc(wu, app);
        }

        // max_granted_credit trumps rsc_fpops_bound;
        // the latter may be set absurdly high
        //
        if (max_granted_credit && pfc*COBBLESTONE_SCALE > max_granted_credit) {
            log_messages.printf(MSG_CRITICAL,
                "[credit] Credit too high: %f\n", pfc*COBBLESTONE_SCALE
            );
            pfc = max_granted_credit/COBBLESTONE_SCALE;
            mode = PFC_MODE_INVALID;
        }
        switch (mode) {
        case PFC_MODE_NORMAL:
            normal.push_back(pfc);
            break;
        case PFC_MODE_INVALID:
            break;
        default:
            approx.push_back(pfc);
            break;
        }
    }

    // averaging policy: if there is more than one normal result,
    // use the "pegged average" of normal results.
    // Otherwise use the pegged_average of all results
    //
    double x;
    switch (normal.size()) {
    case 1:
        // normal has double the weight of approx
        approx.push_back(normal[0]);
        approx.push_back(normal[0]);
        // fall through
    case 0:
        if (approx.size()) {
            x = pegged_average(approx, wu_estimated_pfc(wu, app));
        } else {
            // there were only PFC_MODE_INVALID results, so we guess
            x = wu_estimated_pfc(wu, app);
        }
        break;
    default:
        x = pegged_average(normal, wu_estimated_pfc(wu, app));
        break;
    }

    x *= COBBLESTONE_SCALE;
    if (config.debug_credit) {
        log_messages.printf(MSG_NORMAL,
            "[credit] [WU#%lu] assign_credit_set: credit %g\n",
            wu.id, x
        );
    }
    credit = x;
    return 0;
}