diff --git a/src/urma/examples/urma_sample.c b/src/urma/examples/urma_sample.c index 0f2459420cea60a52e6f46ffffcd80fbfb1ed68c..460c378be20bed635ff0e69bf4f14ef97f150c91 100644 --- a/src/urma/examples/urma_sample.c +++ b/src/urma/examples/urma_sample.c @@ -635,7 +635,7 @@ static void *server_jetty_thread_main(void *arg) fprintf(stderr, "Failed to recv in server jetty thread\n"); return NULL; } - if (server_reply_to_client(ctx, &cr) != 0) { + if (cr.flag.bs.s_r == 1 && server_reply_to_client(ctx, &cr) != 0) { break; } } else { diff --git a/src/urma/lib/urma/bond/bondp_api.c b/src/urma/lib/urma/bond/bondp_api.c index 465417c6c44e2152f856790037de92377a93c524..001c129caa83f6542cc71254d6150ec05f5fedb8 100644 --- a/src/urma/lib/urma/bond/bondp_api.c +++ b/src/urma/lib/urma/bond/bondp_api.c @@ -18,6 +18,7 @@ #include "urma_ubagg.h" #include "bondp_jetty_ctx.h" #include "bondp_context_table.h" +#include "bondp_provider_ops.h" #include "ubagg_ioctl.h" #include "urma_provider.h" #include "bondp_api.h" @@ -227,8 +228,7 @@ urma_jfs_t *bondp_create_jfs(urma_context_t *ctx, urma_jfs_cfg_t *cfg) bondp_context_t *bdp_ctx = CONTAINER_OF_FIELD(ctx, bondp_context_t, v_ctx); if (is_in_matrix_server(bdp_ctx)) { if (cfg->flag.bs.multi_path == false) { - URMA_LOG_ERR("CONSTRAINT: JFS only support multi_path mode in matrix server," - " but try to create single_path JFS.\n"); + URMA_LOG_ERR("In matrix server, JFS don't support single-path mode.\n"); return NULL; } } @@ -530,13 +530,13 @@ urma_status_t bondp_modify_jfr(urma_jfr_t *jfr, urma_jfr_attr_t *attr) @param[out]attr->state:When both values returned by urma_query_jfr are identical, they are returned directly. If the two values differ and a single ready event exists, the ready event is returned. The scenario involving one reset and one error event is not considered at this stage. - + @param[out]attr->rx_threshold:urma_query_jfr returns the smaller value if two are returned; returns the value directly if only one is returned; returns zero if neither is returned. - + @param[out]attr->mask:Use bits to indicate whether the aforementioned two values are valid. The state remains valid at all times, whereas rx_threshold requires processing based on the return value of urma_query_jfr. - + @param[out]cfg:Directly assign jfr_cfg to v_jfr */ urma_status_t bondp_query_jfr(urma_jfr_t *jfr, urma_jfr_cfg_t *cfg, urma_jfr_attr_t *attr) @@ -684,33 +684,35 @@ static void bondp_del_jetty_p_vjetty_info(bondp_comp_t *bdp_jetty) urma_jetty_t *bondp_create_jetty(urma_context_t *ctx, urma_jetty_cfg_t *jetty_cfg) { + bondp_context_t *bdp_ctx = CONTAINER_OF_FIELD(ctx, bondp_context_t, v_ctx); + if (jetty_cfg->flag.bs.share_jfr != true || jetty_cfg->shared.jfr == NULL) { - URMA_LOG_ERR("UB device must use jetty share_jfr mode and shared.jfr should be valid.\n"); + URMA_LOG_ERR("UB device must use shared jfr when create jetty.\n"); errno = EINVAL; return NULL; } - bondp_context_t *bdp_ctx = CONTAINER_OF_FIELD(ctx, bondp_context_t, v_ctx); - if (!is_valid_ctx(bdp_ctx)) { - URMA_LOG_ERR("Invalid param ctx\n"); - return NULL; - } if (jetty_cfg->id >= BONDP_MAX_WELL_KNOWN_JETTY_ID) { URMA_LOG_ERR("Invalid well known jetty id: %d, should be in (0, 1024)\n", jetty_cfg->id); return NULL; } if (is_in_matrix_server(bdp_ctx)) { - if (jetty_cfg->jfs_cfg.flag.bs.multi_path == false && - (jetty_cfg->jfs_cfg.trans_mode == URMA_TM_RM || jetty_cfg->jfs_cfg.trans_mode == URMA_TM_UM)) { - URMA_LOG_ERR("CONSTRAINT: Jettys in Single-path mode only support trans_mode URMA_TM_RC, " - "try to create a jetty with trans_mode: %d\n", jetty_cfg->jfs_cfg.trans_mode); - errno = EINVAL; - return NULL; - } - if (jetty_cfg->id != 0 && jetty_cfg->jfs_cfg.flag.bs.multi_path == false) { - URMA_LOG_WARN("Wellknown jetty in matrix server mode must use multi-path mode, " - "set to multi_path mode forcely\n"); - jetty_cfg->jfs_cfg.flag.bs.multi_path = true; + if (jetty_cfg->jfs_cfg.flag.bs.multi_path == false) { + if (jetty_cfg->jfs_cfg.trans_mode != URMA_TM_RC) { + URMA_LOG_ERR("In matrix server, jetty only supports single-path mode with RC.\n"); + errno = EINVAL; + return NULL; + } + if (is_single_dev_mode(ctx)) { + URMA_LOG_ERR("In matrix server, multi-device mode don't support single path currently.\n"); + errno = EINVAL; + return NULL; + } + if (jetty_cfg->id != 0) { + URMA_LOG_WARN("In matrix server, wellknown jetty must use multi-path mode, " + "set to multi-path mode forcely\n"); + jetty_cfg->jfs_cfg.flag.bs.multi_path = true; + } } } @@ -907,11 +909,6 @@ urma_status_t bondp_modify_jetty(urma_jetty_t *jetty, urma_jetty_attr_t *attr) int bondp_user_ctl(urma_context_t *ctx, urma_user_ctl_in_t *in, urma_user_ctl_out_t *out) { - bondp_context_t *bond_ctx = CONTAINER_OF_FIELD(ctx, bondp_context_t, v_ctx); - if (!is_valid_ctx(bond_ctx)) { - URMA_LOG_ERR("bonding context is invalid in user ctl"); - return -1; - } switch (in->opcode) { case URMA_USER_CTL_BOND_GET_ID_INFO: case URMA_USER_CTL_BOND_ADD_RJFR_ID_INFO: @@ -919,9 +916,15 @@ int bondp_user_ctl(urma_context_t *ctx, urma_user_ctl_in_t *in, urma_user_ctl_ou case URMA_USER_CTL_BOND_GET_SEG_INFO: case URMA_USER_CTL_BOND_ADD_REMOTE_SEG_INFO: break; + case URMA_USER_CTL_BOND_SET_AGGR_MODE: + if (in->len != sizeof(urma_context_aggr_mode_t)) { + URMA_LOG_ERR("Invalid len"); + return -EINVAL; + } + return bondp_set_aggr_mode(ctx, *(urma_context_aggr_mode_t *)in->addr); default: { URMA_LOG_ERR("Unsupported opcode, opcode:%d\n", in->opcode); - return -1; + return -EINVAL; } } return 0; @@ -1159,7 +1162,7 @@ static int bondp_import_pjetty(bondp_context_t *bdp_ctx, bondp_target_jetty_t *b ret = import_loopback_matrix_jetty(bdp_ctx, bdp_tjetty, udata_out, rjetty, rjetty_token); } else { if (is_well_known_jetty_id(rjetty->jetty_id.id)) { - int iodie_num = g_bondp_global_ctx->use_single_die ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; + int iodie_num = is_single_dev_mode(&bdp_ctx->v_ctx) ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; bdp_tjetty->local_dev_num = iodie_num; bdp_tjetty->target_dev_num = iodie_num; bdp_tjetty->is_multipath = true; @@ -1167,7 +1170,7 @@ static int bondp_import_pjetty(bondp_context_t *bdp_ctx, bondp_target_jetty_t *b } else { bdp_tjetty->is_multipath = udata_out->is_multipath; if (bdp_tjetty->is_multipath) { - int iodie_num = g_bondp_global_ctx->use_single_die ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; + int iodie_num = is_single_dev_mode(&bdp_ctx->v_ctx) ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; bdp_tjetty->local_dev_num = iodie_num; bdp_tjetty->target_dev_num = iodie_num; ret = import_primary_ports(bdp_ctx, bdp_tjetty, udata_out, rjetty, rjetty_token); @@ -1543,6 +1546,7 @@ static int import_primary_ports_jfr(bondp_context_t *bdp_ctx, bondp_target_jetty URMA_LOG_WARN("Primary dev has NULL rjetty eid\n"); continue; } + bdp_tjetty->target_valid[i] = true; p_rjfr.jfr_id = ex_info->slave_id[i]; bdp_tjetty->p_tjetty[i][i] = urma_import_jfr(bdp_ctx->p_ctxs[i], &p_rjfr, rjfr_token); if (bdp_tjetty->p_tjetty[i][i] == NULL) { @@ -1582,7 +1586,7 @@ static int bondp_import_pjfr(bondp_context_t *bdp_ctx, bondp_target_jetty_t *bdp bdp_tjetty->is_multipath = true; /* JFR currently only support multipath mode */ if (bdp_tjetty->is_multipath) { - int iodie_num = g_bondp_global_ctx->use_single_die ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; + int iodie_num = is_single_dev_mode(&bdp_ctx->v_ctx) ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; bdp_tjetty->local_dev_num = iodie_num; bdp_tjetty->target_dev_num = iodie_num; ret = import_primary_ports_jfr(bdp_ctx, bdp_tjetty, udata_out, rjfr, token_value); @@ -1797,7 +1801,7 @@ static void *get_jetty_and_ret(uint64_t addr, int *ret) static int init_elment_vjetty(urma_async_event_t *v_event, urma_async_event_t *p_event) { int ret = 0; - + switch (p_event->event_type) { case URMA_EVENT_JFC_ERR: v_event->element.jfc = (urma_jfc_t *)get_jetty_and_ret( @@ -1840,7 +1844,7 @@ urma_status_t bondp_get_async_event(urma_context_t *ctx, urma_async_event_t *v_e struct epoll_event event; urma_async_event_t *p_event; urma_status_t status; - + int nfds = epoll_wait(ctx->async_fd, &event, 1, 0); if (nfds == -1) { URMA_LOG_ERR("epoll_wait no event or err.\n"); @@ -1887,4 +1891,4 @@ void bondp_ack_async_event(urma_async_event_t *event) URMA_LOG_INFO("ack v_event: %p, p_event: %p\n", event, p_event); event->priv = NULL; free(p_event); -} \ No newline at end of file +} diff --git a/src/urma/lib/urma/bond/bondp_comp.c b/src/urma/lib/urma/bond/bondp_comp.c index 23f506530c2a49c1e8b6fa447a4feaa3daaf736b..899ab1a1e4725d545e915184b9c90b595eb9c384 100644 --- a/src/urma/lib/urma/bond/bondp_comp.c +++ b/src/urma/lib/urma/bond/bondp_comp.c @@ -276,7 +276,7 @@ static urma_jfs_cfg_t *bondp_jfs_get_args_list(bondp_context_t *bdp_ctx, urma_jf } if (cfg->flag.bs.multi_path) { - if (g_bondp_global_ctx->use_single_die) { + if (is_single_dev_mode(&bdp_ctx->v_ctx)) { dev_num = SINGLE_DIE_IODIE_NUM; } else { dev_num = PRIMARY_EID_NUM; @@ -363,7 +363,7 @@ static urma_jetty_cfg_t *bondp_jetty_get_args_list(bondp_context_t *bdp_ctx, urm } if (cfg->jfs_cfg.flag.bs.multi_path) { - if (g_bondp_global_ctx->use_single_die) { + if (is_single_dev_mode(&bdp_ctx->v_ctx)) { dev_num = SINGLE_DIE_IODIE_NUM; } else { dev_num = PRIMARY_EID_NUM; diff --git a/src/urma/lib/urma/bond/bondp_datapath.c b/src/urma/lib/urma/bond/bondp_datapath.c index d149ff322497a91a57a22ea86ff0b64f2caae9ae..3ebd3e6bbdb5de57c688d61ee68b89dfb8fe59bd 100644 --- a/src/urma/lib/urma/bond/bondp_datapath.c +++ b/src/urma/lib/urma/bond/bondp_datapath.c @@ -212,7 +212,7 @@ static int schedule_next_route_in_matrix_server_multipath(const urma_jfs_wr_t *w bdp_v_conn_t *v_conn, int *send_idx, int *target_idx) { - if (g_bondp_global_ctx->use_single_die) { + if (is_single_dev_mode(bdp_tjetty->v_tjetty.urma_ctx)) { *send_idx = 0; *target_idx = 0; return 0; @@ -1017,10 +1017,11 @@ urma_status_t bondp_post_jetty_send_wr(urma_jetty_t *jetty, urma_jfs_wr_t *wr, u return ret; } bjetty_ctx_t *bjetty_ctx = bdp_jetty->comp_ctx; - if (g_bondp_global_ctx->disable_recovery) { + if (is_single_dev_mode(jetty->urma_ctx)) { return bondp_post_send_wr_no_store(bjetty_ctx, wr, bad_wr); + } else { + return bondp_post_send_wr_and_store(bjetty_ctx, wr, bad_wr); } - return bondp_post_send_wr_and_store(bjetty_ctx, wr, bad_wr); } /** Select recv pjetty in post_jetty_recv_wr */ @@ -1145,7 +1146,7 @@ static urma_status_t set_jfr_wr_ptjetty_ptseg_without_hdr(urma_jfr_wr_t *recv_wr static urma_status_t schedule_next_recv_port_matrix_multipath(bjetty_ctx_t *bjetty_ctx, int *recv_idx) { - if (g_bondp_global_ctx->use_single_die) { + if (is_single_dev_mode(&bjetty_ctx->bond_ctx->v_ctx)) { *recv_idx = 0; return URMA_SUCCESS; } @@ -1273,10 +1274,11 @@ urma_status_t bondp_post_jetty_recv_wr(urma_jetty_t *jetty, urma_jfr_wr_t *wr, u } /* non-null bjetty_ctx value because post_recv_check_valid performed validation. */ bjetty_ctx_t *bjetty_ctx = bdp_jetty->comp_ctx; - if (g_bondp_global_ctx->disable_recovery) { + if (is_single_dev_mode(jetty->urma_ctx)) { return bondp_post_recv_wr_no_store(bjetty_ctx, wr, bad_wr); + } else { + return bondp_post_recv_wr_and_store(bjetty_ctx, wr, bad_wr); } - return bondp_post_recv_wr_and_store(bjetty_ctx, wr, bad_wr); } static inline bool is_device_error(urma_cr_status_t status) @@ -1320,6 +1322,7 @@ static int resend_wr_in_error_device_buf(wr_buf_node_t *node, void *args) return CALLBACK_SKIP; } node->value.send_idx = migrate_idx; + node->value.target_idx = migrate_idx; /* get_comp_urma_jetty_id(bjetty_ctx->bdp_comp) always returns non-null value. */ /* Because resend funciton access stored bjetty_ctx pointer which has been validated in post_send_check_valid */ ret = send_and_store_jfs_wr(bjetty_ctx, get_comp_urma_jetty_id(bjetty_ctx->bdp_comp)->id, @@ -1524,7 +1527,14 @@ static bondp_cr_handler_ret_t handle_send(bjetty_ctx_t *bjetty_ctx, urma_cr_t *c Migrate all WRs from the current jetty to the next valid jetty ! Migration may fail, but considering it transparent to user, so we return 1 to ignore CR */ - migrate_idx = find_next_valid_jetty_idx(bjetty_ctx->pjettys_valid, bjetty_ctx->dev_num, send_idx); + if (is_in_matrix_server(bjetty_ctx->bond_ctx)) { + migrate_idx = (send_idx + 1) % PRIMARY_EID_NUM; + if (!bjetty_ctx->pjettys_valid[migrate_idx]) { + migrate_idx = -1; + } + } else { + migrate_idx = find_next_valid_jetty_idx(bjetty_ctx->pjettys_valid, bjetty_ctx->dev_num, send_idx); + } ret = resend_error_device(bjetty_ctx, send_idx, migrate_idx, &bad_wr); URMA_LOG_DEBUG("Migrate send from %d to %d, ret %d\n", send_idx, migrate_idx, ret); return CR_HANDLER_SUCCESS_AND_SKIP; @@ -1859,7 +1869,7 @@ static inline bool is_cr_user_ctx_valid(urma_cr_t *cr) */ static urma_status_t update_device_valid_state(bondp_context_t *bdp_ctx, int dev_id, int cqe_cnt, urma_cr_t *cr_buf) { - if (g_bondp_global_ctx->disable_recovery) { + if (is_single_dev_mode(&bdp_ctx->v_ctx)) { return URMA_SUCCESS; } for (int cr_id = 0; cr_id < cqe_cnt; ++cr_id) { @@ -2149,7 +2159,7 @@ int bondp_poll_jfc(urma_jfc_t *jfc, int cr_cnt, urma_cr_t *cr_output_array) } for (int cr_id = 0; cr_id < cqe_cnt[dev_id]; ++cr_id) { int ret = 0; - if (g_bondp_global_ctx->disable_recovery) { + if (is_single_dev_mode(&bdp_ctx->v_ctx)) { ret = bondp_handle_cr_no_store(bdp_ctx, dev_id, &bdp_cr_buf[dev_id][cr_id], cr_output_array, &total_cnt); } else { @@ -2184,10 +2194,11 @@ urma_status_t bondp_post_jfs_wr(urma_jfs_t *jfs, urma_jfs_wr_t *wr, urma_jfs_wr_ if (ret != URMA_SUCCESS) { return ret; } - if (g_bondp_global_ctx->disable_recovery) { + if (is_single_dev_mode(jfs->urma_ctx)) { return bondp_post_send_wr_no_store(bjetty_ctx, wr, bad_wr); + } else { + return bondp_post_send_wr_and_store(bjetty_ctx, wr, bad_wr); } - return bondp_post_send_wr_and_store(bjetty_ctx, wr, bad_wr); } urma_status_t bondp_post_jfr_wr(urma_jfr_t *jfr, urma_jfr_wr_t *wr, urma_jfr_wr_t **bad_wr) @@ -2202,8 +2213,9 @@ urma_status_t bondp_post_jfr_wr(urma_jfr_t *jfr, urma_jfr_wr_t *wr, urma_jfr_wr_ bjetty_ctx_t *bjetty_ctx = bdp_jfr->comp_ctx; // workaround, at this point,jfr only support multipath bdp_jfr->is_multipath = true; - if (g_bondp_global_ctx->disable_recovery) { + if (is_single_dev_mode(jfr->urma_ctx)) { return bondp_post_recv_wr_no_store(bjetty_ctx, wr, bad_wr); + } else { + return bondp_post_recv_wr_and_store(bjetty_ctx, wr, bad_wr); } - return bondp_post_recv_wr_and_store(bjetty_ctx, wr, bad_wr); -} \ No newline at end of file +} diff --git a/src/urma/lib/urma/bond/bondp_provider_ops.c b/src/urma/lib/urma/bond/bondp_provider_ops.c index 05e69115912cc7e4ceaa2b5eff3863a900fb0f44..d68a548033573f8802c9734088136c6cff945372 100644 --- a/src/urma/lib/urma/bond/bondp_provider_ops.c +++ b/src/urma/lib/urma/bond/bondp_provider_ops.c @@ -31,7 +31,6 @@ #include "bondp_context_table.h" #include "bondp_provider_ops.h" -#define UBAGG_DISABLE_SINGLE_DIE "UBAGG_DISABLE_SINGLE_DIE" #define UBAGG_MAX_EVENT 1 #define UBAGG_ENABLE_RECOVERY "UBAGG_ENABLE_RECOVERY" @@ -114,15 +113,6 @@ static int bondp_global_ctx_init(bondp_global_context_t **bondp_global_ctx) } ctx->pid = (uint32_t)getpid(); - - const char *env_value = getenv(UBAGG_DISABLE_SINGLE_DIE); - if (env_value == NULL || *env_value == '\0') { - URMA_LOG_INFO("There is no env_value about UBAGG_DISABLE_SINGLE_DIE"); - } - ctx->use_single_die = !(env_value != NULL && *env_value); - env_value = getenv(UBAGG_ENABLE_RECOVERY); - ctx->disable_recovery = !(env_value != NULL && *env_value); - *bondp_global_ctx = ctx; return 0; } @@ -428,10 +418,10 @@ static int init_general_slave_devices(bondp_context_t *bond_ctx) return -1; } - bond_ctx->dev_num = dev_info.slave_dev_num; - - if (g_bondp_global_ctx->use_single_die) { + if (is_single_dev_mode(&bond_ctx->v_ctx)) { bond_ctx->dev_num = SINGLE_DIE_IODIE_NUM; + } else { + bond_ctx->dev_num = dev_info.slave_dev_num; } for (i = 0; i < bond_ctx->dev_num; ++i) { @@ -449,7 +439,7 @@ DELETE_SLAVE_CTX: return -1; } -static int init_matrix_slave_devices(bondp_context_t *bond_ctx) +static int init_matrix_slave_devices(bondp_context_t *bond_ctx, urma_context_aggr_mode_t aggr_mode) { bond_ctx->topo_map = g_bondp_global_ctx->topo_map; topo_info_t *topo_info = get_topo_info_by_bonding_eid(bond_ctx->topo_map, &bond_ctx->v_ctx.eid); @@ -457,64 +447,65 @@ static int init_matrix_slave_devices(bondp_context_t *bond_ctx) URMA_LOG_ERR("Failed to get topo info by bonding eid\n"); return -1; } - int ret = 0; - int i = 0; - int j = 0; - int iodie_num = g_bondp_global_ctx->use_single_die ? SINGLE_DIE_IODIE_NUM : PRIMARY_EID_NUM; - /* The second iodie is empty and is set to valid in single-die mode */ - bool iodie_valid[IODIE_NUM] = {false, g_bondp_global_ctx->use_single_die}; - for (i = 0; i < iodie_num; ++i) { - /* Primary EID must be valid */ - if (is_empty_eid((urma_eid_t *)(topo_info->io_die_info[i].primary_eid))) { + + int iodie_num = aggr_mode == URMA_AGGR_MODE_STANDALONE + ? SINGLE_DIE_IODIE_NUM + : PRIMARY_EID_NUM; + + urma_eid_t *eid_list[URMA_UBAGG_DEV_MAX_NUM] = {0}; + for (int i = 0; i < iodie_num; ++i) { + eid_list[i] = (urma_eid_t *)(topo_info->io_die_info[i].primary_eid); + if (is_empty_eid(eid_list[i])) { URMA_LOG_ERR("Primary eid %d is NULL\n", i); - goto DELETE_CTX; + return -1; } - ret = get_dev_and_ctx_by_eid((urma_eid_t *)topo_info->io_die_info[i].primary_eid, - &bond_ctx->primary_devs[i], &bond_ctx->primary_ctxs[i]); - if (ret) { - URMA_LOG_ERR("Failed to create ctx for primary eid[%d]\n", i); - goto DELETE_CTX; - } - /* There should be at least one valid port eid */ + bool port_eid_valid = false; - for (j = 0; j < PORT_EID_MAX_NUM_PER_DEV; ++j) { - if (is_empty_eid((urma_eid_t *)(topo_info->io_die_info[i].port_eid[j]))) { + for (int j = 0; j < PORT_EID_MAX_NUM_PER_DEV; ++j) { + int idx = PRIMARY_EID_NUM + i * PORT_EID_MAX_NUM_PER_DEV + j; + eid_list[idx] = (urma_eid_t *)(topo_info->io_die_info[i].port_eid[j]); + if (is_empty_eid(eid_list[idx])) { + eid_list[idx] = NULL; URMA_LOG_INFO("Skip port ctx [%d, %d], eid is empty", i, j); continue; } - int port_idx = get_matrix_port_ctx_idx(i, j); - ret = get_dev_and_ctx_by_eid((urma_eid_t *)(topo_info->io_die_info[i].port_eid[j]), - &bond_ctx->port_devs[port_idx], &bond_ctx->port_ctxs[port_idx]); - if (ret) { - URMA_LOG_ERR("Failed to create port ctx[%d, %d]\n", i, j); - goto DELETE_CTX; - } port_eid_valid = true; } - iodie_valid[i] = port_eid_valid; + + if (!port_eid_valid) { + URMA_LOG_ERR("No port eid valid\n"); + return -1; + } } - if (!iodie_valid[0] || !iodie_valid[1]) { - i = iodie_num - 1; - URMA_LOG_ERR("Either iodie is invalid: %d %d\n", iodie_valid[0], iodie_valid[1]); - goto DELETE_CTX; + + urma_context_t *p_ctxs[URMA_UBAGG_DEV_MAX_NUM] = {0}; + for (int i = 0; i < URMA_UBAGG_DEV_MAX_NUM; i++) { + if (eid_list[i] == NULL) { + continue; + } + int ret = get_dev_and_ctx_by_eid(eid_list[i], &bond_ctx->p_devs[i], &p_ctxs[i]); + if (ret != 0) { + URMA_LOG_ERR("Failed to create ctx for primary eid[%d]\n", i); + goto DELETE_CTX; + } + } + + for (int i = 0; i < URMA_UBAGG_DEV_MAX_NUM; i++) { + if (bond_ctx->p_ctxs[i] != NULL) { + urma_delete_context(bond_ctx->p_ctxs[i]); + } + bond_ctx->p_ctxs[i] = p_ctxs[i]; } - bond_ctx->dev_num = g_bondp_global_ctx->use_single_die ? SINGLE_DIE_DEVNUM : PRIMARY_EID_NUM + PORT_EID_MAX_NUM; + + bond_ctx->dev_num = aggr_mode == URMA_AGGR_MODE_STANDALONE + ? SINGLE_DIE_DEVNUM + : PRIMARY_EID_NUM + PORT_EID_MAX_NUM; return init_slave_context_fd(bond_ctx); + DELETE_CTX: - /* - This branch is only entered in error cases, - and at this time, the value of i is at most PRIMARY_EID_NUM - 1, - so there is no array out of bounds situation. - */ - for (int p = 0; p <= i; ++p) { - for (int q = 0; q < PORT_EID_MAX_NUM_PER_DEV; ++q) { - int port_idx = get_matrix_port_ctx_idx(p, q); - if (bond_ctx->port_ctxs[port_idx]) { - urma_delete_context(bond_ctx->port_ctxs[port_idx]); - } - } - if (bond_ctx->primary_ctxs[p]) { - urma_delete_context(bond_ctx->primary_ctxs[p]); + for (int i = 0; i p_ctxs[i]); } } return -1; @@ -559,9 +550,10 @@ urma_context_t *bondp_create_context(urma_device_t *dev, uint32_t eid_index, int URMA_LOG_ERR("Failed to create epoll %s\n", ub_strerror(errno)); goto UNINIT_V_CTX; } + bond_ctx->v_ctx.aggr_mode = URMA_AGGR_MODE_STANDALONE; if (!g_bondp_global_ctx->skip_load_topo && get_topo_info_from_ko(bond_ctx) == 0) { - ret = init_matrix_slave_devices(bond_ctx); + ret = init_matrix_slave_devices(bond_ctx, bond_ctx->v_ctx.aggr_mode); } else { ret = init_general_slave_devices(bond_ctx); } @@ -600,4 +592,18 @@ urma_status_t bondp_delete_context(urma_context_t *ctx) bondp_uninit_v_ctx(bond_ctx); bondp_delete_ctx(bond_ctx); return ret; +} + +int bondp_set_aggr_mode(urma_context_t *ctx, urma_context_aggr_mode_t aggr_mode) { + bondp_context_t *bond_ctx = CONTAINER_OF_FIELD(ctx, bondp_context_t, v_ctx); + if (!is_valid_ctx(bond_ctx)) { + URMA_LOG_ERR("bonding context is invalid in user ctl"); + return -1; + } + + int ret = init_matrix_slave_devices(bond_ctx, aggr_mode); + if (ret == 0) { + ctx->aggr_mode = aggr_mode; + } + return ret; } \ No newline at end of file diff --git a/src/urma/lib/urma/bond/bondp_provider_ops.h b/src/urma/lib/urma/bond/bondp_provider_ops.h index 6e39de3c597f1e11d96ada9a7e3fc6b84ff19076..7b2713761feae59a634dd53249aa2ed583e7dc43 100644 --- a/src/urma/lib/urma/bond/bondp_provider_ops.h +++ b/src/urma/lib/urma/bond/bondp_provider_ops.h @@ -16,6 +16,8 @@ urma_context_t *bondp_create_context(urma_device_t *dev, uint32_t eid_index, int urma_status_t bondp_delete_context(urma_context_t *ctx); +int bondp_set_aggr_mode(urma_context_t *ctx, urma_context_aggr_mode_t aggr_mode); + urma_status_t bondp_init(urma_init_attr_t *conf); urma_status_t bondp_uninit(void); diff --git a/src/urma/lib/urma/bond/bondp_segment.c b/src/urma/lib/urma/bond/bondp_segment.c index 6987399b208dfad933b7ea6d015b2a25febcb374..90b2cdbea19fd11fd28f6a8870174708610e1fb3 100644 --- a/src/urma/lib/urma/bond/bondp_segment.c +++ b/src/urma/lib/urma/bond/bondp_segment.c @@ -220,7 +220,7 @@ static bondp_ret_t import_p_tseg(bondp_context_t *bdp_ctx, bondp_seg_cfg_t *seg_ static bondp_ret_t import_matrix_primary_seg(bondp_context_t *bdp_ctx, bondp_seg_cfg_t *seg_cfg) { bool has_success = false; - int iodie_num = g_bondp_global_ctx->use_single_die ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; + int iodie_num = is_single_dev_mode(&bdp_ctx->v_ctx) ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; for (int iodie_idx = 0; iodie_idx < iodie_num; ++iodie_idx) { bondp_ret_t ret = import_p_tseg(bdp_ctx, seg_cfg, iodie_idx, iodie_idx); if (ret == BONDP_SKIP) { @@ -325,7 +325,7 @@ static bondp_ret_t import_matrix_port_seg(bondp_context_t *bdp_ctx, urma_seg_t * if (is_empty_eid(&eid)) { URMA_LOG_WARN("Can't get direct route by seg->ubva.eid, it is empty. Import segment to all port eid.\n"); // fullmush import - int iodie_num = g_bondp_global_ctx->use_single_die ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; + int iodie_num = is_single_dev_mode(&bdp_ctx->v_ctx) ? SINGLE_DIE_IODIE_NUM : IODIE_NUM; for (int iodie_idx = 0; iodie_idx < iodie_num; ++iodie_idx) { ret = import_matrix_port_seg_on_iodie(bdp_ctx, bondp_seg_cfg, iodie_idx); if (ret != BONDP_SUCCESS) { @@ -495,4 +495,4 @@ urma_status_t bondp_unimport_seg(urma_target_seg_t *target_seg) } free(bdp_imprt_tseg); return ret; -} \ No newline at end of file +} diff --git a/src/urma/lib/urma/bond/bondp_types.h b/src/urma/lib/urma/bond/bondp_types.h index 2839432e58cc134b4268d0de3352284256e2145d..45902a35669e48608d361f3a0c8506eacc0dd247 100644 --- a/src/urma/lib/urma/bond/bondp_types.h +++ b/src/urma/lib/urma/bond/bondp_types.h @@ -39,8 +39,6 @@ typedef struct bondp_global_context { uint32_t pid; topo_map_t *topo_map; bool skip_load_topo; - bool use_single_die; - bool disable_recovery; } bondp_global_context_t; extern bondp_global_context_t *g_bondp_global_ctx; @@ -170,12 +168,6 @@ bool is_valid_bdp_tjetty(bondp_target_jetty_t *bdp_tjetty); bool is_valid_import_tseg(bondp_import_tseg_t *rtseg); -/* Get index of matrix server port in bondp_context_t->port_ctxs[X] */ -static inline int get_matrix_port_ctx_idx(int primary_idx, int port_idx) -{ - return primary_idx * PORT_EID_MAX_NUM_PER_DEV + port_idx; -} - /* Get index of matrix server port in p_ctx, p_jetty, etc. */ static inline int get_matrix_port_p_idx(int primary_idx, int port_idx) { @@ -196,4 +188,9 @@ static inline bool is_multipath_comp(bondp_comp_t *bdp_comp) { return bdp_comp->is_multipath; } + +static inline bool is_single_dev_mode(urma_context_t *ctx) +{ + return ctx->aggr_mode == URMA_AGGR_MODE_STANDALONE; +} #endif // BONDP_TYPES_H diff --git a/src/urma/lib/urma/bond/include/urma_ubagg.h b/src/urma/lib/urma/bond/include/urma_ubagg.h index cea306de6734e2143cb6cd158e3ee594ebd9f4ca..9c4139d5c5d73fcfc57fa1b127db05b2d79ae49c 100644 --- a/src/urma/lib/urma/bond/include/urma_ubagg.h +++ b/src/urma/lib/urma/bond/include/urma_ubagg.h @@ -28,7 +28,8 @@ typedef enum urma_bond_user_ctl_opcode { URMA_USER_CTL_BOND_ADD_RJFR_ID_INFO, URMA_USER_CTL_BOND_ADD_RJETTY_ID_INFO, URMA_USER_CTL_BOND_GET_SEG_INFO, - URMA_USER_CTL_BOND_ADD_REMOTE_SEG_INFO + URMA_USER_CTL_BOND_ADD_REMOTE_SEG_INFO, + URMA_USER_CTL_BOND_SET_AGGR_MODE, } urma_bond_user_ctl_opcode_t; typedef struct urma_bond_id_info_in { diff --git a/src/urma/lib/urma/core/include/urma_api.h b/src/urma/lib/urma/core/include/urma_api.h index 25c6e994e131fc94555090da1e7229f3aedc2364..6de26ec81d3b2ecd19593e21d78edeaf59ca0bcc 100644 --- a/src/urma/lib/urma/core/include/urma_api.h +++ b/src/urma/lib/urma/core/include/urma_api.h @@ -103,6 +103,14 @@ urma_context_t *urma_create_context(urma_device_t *dev, uint32_t eid_index); */ urma_status_t urma_delete_context(urma_context_t *ctx); +/** + * Set option of urma context. + * @param[in] [Required] ctx: handle of the created context. + * Return: 0 on success, other value on error. + */ +urma_status_t urma_set_context_opt(urma_context_t *ctx, urma_opt_name_t opt_name, + const void *opt_value, size_t opt_len); + /** * Create a jetty for completion (jfc). * @param[in] [Required] ctx: the urma context created before; diff --git a/src/urma/lib/urma/core/include/urma_types.h b/src/urma/lib/urma/core/include/urma_types.h index 81b2423b1eb14b72eeaefda9354a96dec3cd3257..ecbf5176e1533ce569527a9d6ac304b40273a820 100644 --- a/src/urma/lib/urma/core/include/urma_types.h +++ b/src/urma/lib/urma/core/include/urma_types.h @@ -329,6 +329,16 @@ typedef struct urma_device { struct urma_sysfs_dev *sysfs_dev; /* [Private] internal device corresponding to the urma device */ } urma_device_t; +typedef enum urma_context_opt_name { + URMA_OPT_AGGR_MODE, +} urma_opt_name_t; + +typedef enum urma_context_aggr_mode { + URMA_AGGR_MODE_STANDALONE, + URMA_AGGR_MODE_ACTIVE_BACKUP, + URMA_AGGR_MODE_BALANCE, +} urma_context_aggr_mode_t; + typedef struct urma_context { struct urma_device *dev; /* [Private] point to the corresponding urma device. */ struct urma_ops *ops; /* [Private] operation of urma device. */ @@ -339,6 +349,7 @@ typedef struct urma_context { uint32_t eid_index; uint32_t uasid; /* [Public] uasid of current process. */ struct urma_ref ref; /* [Private] reference count of urma context. */ + urma_context_aggr_mode_t aggr_mode; /* [Public] aggregated mode of urma context */ } urma_context_t; typedef struct urma_eid_info { diff --git a/src/urma/lib/urma/core/urma_main.c b/src/urma/lib/urma/core/urma_main.c index baafe0da5dc4ababf26bf3d6cbb39a42992a7a22..39f18c38edff9165b029cee48d7999ca94ce138f 100644 --- a/src/urma/lib/urma/core/urma_main.c +++ b/src/urma/lib/urma/core/urma_main.c @@ -549,6 +549,38 @@ urma_status_t urma_delete_context(urma_context_t *ctx) return ret; } +urma_status_t urma_set_context_opt(urma_context_t *ctx, urma_opt_name_t opt_name, + const void *opt_value, size_t opt_len) +{ + if (ctx == NULL || ctx->dev == NULL || ctx->dev->ops == NULL) { + URMA_LOG_ERR("Invalid parameter.\n"); + return URMA_EINVAL; + } + + switch (opt_name) { + case URMA_OPT_AGGR_MODE: + if (opt_len != sizeof(urma_context_aggr_mode_t)) { + URMA_LOG_ERR("Invalid option value len.\n"); + return URMA_EINVAL; + } + if (strcmp(ctx->dev->ops->name, "ubagg") != 0) { + URMA_LOG_ERR("Cannot set aggragated mode for non-aggragated device.\n"); + return URMA_EINVAL; + } + const uint32_t URMA_USER_CTL_BOND_SET_AGGR_MODE = 5; + urma_user_ctl_in_t in = { + .opcode = URMA_USER_CTL_BOND_SET_AGGR_MODE, + .addr = (uint64_t) opt_value, + .len = opt_len, + }; + urma_user_ctl_out_t out = {0}; + return urma_user_ctl(ctx, &in, &out); + default: + URMA_LOG_ERR("Invalid option name.\n"); + return URMA_EINVAL; + } +} + /* Temporarily use uasid allocated by provider */ urma_status_t urma_get_uasid(uint32_t *uasid) {