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; } } }
// 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; }
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; }
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; }
// 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; }