X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fdpdkstat.c;h=c95ba0c6c3d66423c2dad2eba63da239df857272;hp=4c73eab917770d7527cf1587dc34a45fd9855398;hb=7111bb6df7628edce3a8e538b386fbe27633a191;hpb=fb0cc621d4357bbe4a9dc36c7f055f46257ce57c diff --git a/src/dpdkstat.c b/src/dpdkstat.c index 4c73eab9..c95ba0c6 100644 --- a/src/dpdkstat.c +++ b/src/dpdkstat.c @@ -91,10 +91,17 @@ struct dpdk_stats_ctx_s { }; typedef struct dpdk_stats_ctx_s dpdk_stats_ctx_t; +typedef enum { + DPDK_STAT_STATE_OKAY = 0, + DPDK_STAT_STATE_CFG_ERR, +} dpdk_stat_cfg_status; + #define DPDK_STATS_CTX_GET(a) ((dpdk_stats_ctx_t *)dpdk_helper_priv_get(a)) dpdk_helper_ctx_t *g_hc = NULL; static char g_shm_name[DATA_MAX_NAME_LEN] = DPDK_STATS_NAME; +static dpdk_stat_cfg_status g_state = DPDK_STAT_STATE_OKAY; + static int dpdk_stats_reinit_helper(); static void dpdk_stats_default_config(void) { dpdk_stats_ctx_t *ec = DPDK_STATS_CTX_GET(g_hc); @@ -103,6 +110,8 @@ static void dpdk_stats_default_config(void) { for (int i = 0; i < RTE_MAX_ETHPORTS; i++) { ec->config.port_name[i][0] = 0; } + /* Enable all ports by default */ + ec->config.enabled_port_mask = ~0; } static int dpdk_stats_preinit(void) { @@ -118,7 +127,7 @@ static int dpdk_stats_preinit(void) { if (ret != 0) { char errbuf[ERR_BUF_SIZE]; ERROR("%s: failed to initialize %s helper(error: %s)", DPDK_STATS_PLUGIN, - g_shm_name, sstrerror(errno, errbuf, sizeof(errbuf))); + g_shm_name, sstrerror(errno, errbuf, sizeof(errbuf))); return ret; } @@ -130,32 +139,40 @@ static int dpdk_stats_config(oconfig_item_t *ci) { DPDK_STATS_TRACE(); int ret = dpdk_stats_preinit(); - if (ret) - return ret; + if (ret) { + g_state = DPDK_STAT_STATE_CFG_ERR; + return 0; + } dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(g_hc); for (int i = 0; i < ci->children_num; i++) { oconfig_item_t *child = ci->children + i; - if ((strcasecmp("EnabledPortMask", child->key) == 0) && - (child->values[0].type == OCONFIG_TYPE_NUMBER)) { - ctx->config.enabled_port_mask = child->values[0].value.number; - DEBUG("%s: Enabled Port Mask 0x%X", DPDK_STATS_PLUGIN, - ctx->config.enabled_port_mask); - } else if (strcasecmp("SharedMemObj", child->key) == 0) { - cf_util_get_string_buffer(child, g_shm_name, - sizeof(g_shm_name)); - DEBUG("%s: Shared memory object %s", DPDK_STATS_PLUGIN, - g_shm_name); - dpdk_stats_reinit_helper(); - } else if (strcasecmp("EAL", child->key) == 0) { + if (strcasecmp("EnabledPortMask", child->key) == 0) + ret = cf_util_get_int(child, (int *)&ctx->config.enabled_port_mask); + else if (strcasecmp("SharedMemObj", child->key) == 0) { + ret = cf_util_get_string_buffer(child, g_shm_name, sizeof(g_shm_name)); + if (ret == 0) + ret = dpdk_stats_reinit_helper(); + } else if (strcasecmp("EAL", child->key) == 0) ret = dpdk_helper_eal_config_parse(g_hc, child); - if (ret) - return ret; + else if (strcasecmp("PortName", child->key) != 0) { + ERROR(DPDK_STATS_PLUGIN ": unrecognized configuration option %s", + child->key); + ret = -1; + } + + if (ret != 0) { + g_state = DPDK_STAT_STATE_CFG_ERR; + return 0; } } + DEBUG(DPDK_STATS_PLUGIN ": Enabled Port Mask 0x%X", + ctx->config.enabled_port_mask); + DEBUG(DPDK_STATS_PLUGIN ": Shared memory object %s", g_shm_name); + int port_num = 0; /* parse port names after EnabledPortMask was parsed */ @@ -167,86 +184,73 @@ static int dpdk_stats_config(oconfig_item_t *ci) { while (!(ctx->config.enabled_port_mask & (1 << port_num))) port_num++; - cf_util_get_string_buffer(child, ctx->config.port_name[port_num], - sizeof(ctx->config.port_name[port_num])); - DEBUG("%s: Port %d Name: %s", DPDK_STATS_PLUGIN, port_num, + if (cf_util_get_string_buffer(child, ctx->config.port_name[port_num], + sizeof(ctx->config.port_name[port_num]))) { + g_state = DPDK_STAT_STATE_CFG_ERR; + return 0; + } + + DEBUG(DPDK_STATS_PLUGIN ": Port %d Name: %s", port_num, ctx->config.port_name[port_num]); port_num++; } } - return ret; + return 0; } static int dpdk_helper_stats_get(dpdk_helper_ctx_t *phc) { - dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); - - /* get stats from DPDK */ - - uint8_t ports_count = rte_eth_dev_count(); - if (ports_count == 0) { - DPDK_CHILD_LOG("%s: No DPDK ports available. " - "Check bound devices to DPDK driver.\n", - DPDK_STATS_PLUGIN); - return -ENODEV; - } - - if (ports_count > RTE_MAX_ETHPORTS) - ports_count = RTE_MAX_ETHPORTS; - - ctx->ports_count = ports_count; - int len = 0; int ret = 0; int stats = 0; + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); - for (uint8_t i = 0; i < ports_count; i++) { + /* get stats from DPDK */ + for (uint8_t i = 0; i < ctx->ports_count; i++) { if (!(ctx->config.enabled_port_mask & (1 << i))) continue; + ctx->port_read_time[i] = cdtime(); + /* Store available stats array length for port */ len = ctx->port_stats_count[i]; + ret = rte_eth_xstats_get(i, &ctx->xstats[stats], len); - if (ret < 0 || ret != len) { - DPDK_CHILD_LOG("%s: Error reading stats (port=%d; len=%d)\n", - DPDK_STATS_PLUGIN, i, len); + if (ret < 0 || ret > len) { + DPDK_CHILD_LOG(DPDK_STATS_PLUGIN + ": Error reading stats (port=%d; len=%d, ret=%d)\n", + i, len, ret); + ctx->port_stats_count[i] = 0; return -1; } #if RTE_VERSION >= RTE_VERSION_16_07 ret = rte_eth_xstats_get_names(i, &ctx->xnames[stats], len); - if (ret < 0 || ret != len) { - DPDK_CHILD_LOG("%s: Error reading stat names (port=%d; len=%d)\n", - DPDK_STATS_PLUGIN, i, len); + if (ret < 0 || ret > len) { + DPDK_CHILD_LOG(DPDK_STATS_PLUGIN + ": Error reading stat names (port=%d; len=%d ret=%d)\n", + i, len, ret); + ctx->port_stats_count[i] = 0; return -1; } #endif - stats += len; + ctx->port_stats_count[i] = ret; + stats += ctx->port_stats_count[i]; } - assert(stats == ctx->stats_count); - + assert(stats <= ctx->stats_count); return 0; } static int dpdk_helper_stats_count_get(dpdk_helper_ctx_t *phc) { - dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); - - uint8_t ports = rte_eth_dev_count(); - if (ports == 0) { - DPDK_CHILD_LOG("%s: No DPDK ports available. " - "Check bound devices to DPDK driver.\n", - DPDK_STATS_PLUGIN); + uint8_t ports = dpdk_helper_eth_dev_count(); + if (ports == 0) return -ENODEV; - } - - if (ports > RTE_MAX_ETHPORTS) - ports = RTE_MAX_ETHPORTS; + dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); ctx->ports_count = ports; int len = 0; int stats_count = 0; - for (int i = 0; i < ports; i++) { if (!(ctx->config.enabled_port_mask & (1 << i))) continue; @@ -269,9 +273,12 @@ static int dpdk_helper_stats_count_get(dpdk_helper_ctx_t *phc) { return stats_count; } +static int dpdk_stats_get_size(dpdk_helper_ctx_t *phc) { + return dpdk_helper_data_size_get(phc) - sizeof(dpdk_stats_ctx_t); +} + int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd) { /* this function is called from helper context */ - int ret = 0; if (phc == NULL) { DPDK_CHILD_LOG("%s: Invalid argument(phc)\n", DPDK_STATS_PLUGIN); @@ -283,34 +290,23 @@ int dpdk_helper_command_handler(dpdk_helper_ctx_t *phc, enum DPDK_CMD cmd) { return -EINVAL; } - dpdk_stats_ctx_t *ctx = DPDK_STATS_CTX_GET(phc); - - if (ctx->stats_count == 0) { + int stats_count = dpdk_helper_stats_count_get(phc); + if (stats_count < 0) { + return stats_count; + } - int stats_count = dpdk_helper_stats_count_get(phc); + DPDK_STATS_CTX_GET(phc)->stats_count = stats_count; + int stats_size = stats_count * DPDK_STATS_CTX_GET_XSTAT_SIZE; - if (stats_count < 0) { - return stats_count; - } - - int stats_size = stats_count * DPDK_STATS_CTX_GET_XSTAT_SIZE; - ctx->stats_count = stats_count; - - if ((dpdk_helper_data_size_get(phc) - sizeof(dpdk_stats_ctx_t)) < - stats_size) { - DPDK_CHILD_LOG( - "%s:%s:%d not enough space for stats (available=%d, " - "needed=%d)\n", - DPDK_STATS_PLUGIN, __FUNCTION__, __LINE__, - (int)(dpdk_helper_data_size_get(phc) - sizeof(dpdk_stats_ctx_t)), - stats_size); - return -ENOBUFS; - } + if (dpdk_stats_get_size(phc) < stats_size) { + DPDK_CHILD_LOG( + DPDK_STATS_PLUGIN + ":%s:%d not enough space for stats (available=%d, needed=%d)\n", + __FUNCTION__, __LINE__, (int)dpdk_stats_get_size(phc), stats_size); + return -ENOBUFS; } - ret = dpdk_helper_stats_get(phc); - - return ret; + return dpdk_helper_stats_get(phc); } static void dpdk_stats_resolve_cnt_type(char *cnt_type, size_t cnt_type_len, @@ -377,7 +373,6 @@ static void dpdk_stats_counter_submit(const char *plugin_instance, vl.values = &(value_t){.derive = value}; vl.values_len = 1; vl.time = port_read_time; - sstrncpy(vl.host, hostname_g, sizeof(vl.host)); sstrncpy(vl.plugin, DPDK_STATS_PLUGIN, sizeof(vl.plugin)); sstrncpy(vl.plugin_instance, plugin_instance, sizeof(vl.plugin_instance)); dpdk_stats_resolve_cnt_type(vl.type, sizeof(vl.type), cnt_name); @@ -401,9 +396,9 @@ static int dpdk_stats_counters_dispatch(dpdk_helper_ctx_t *phc) { char dev_name[64]; if (ctx->config.port_name[i][0] != 0) { - ssnprintf(dev_name, sizeof(dev_name), "%s", ctx->config.port_name[i]); + snprintf(dev_name, sizeof(dev_name), "%s", ctx->config.port_name[i]); } else { - ssnprintf(dev_name, sizeof(dev_name), "port.%d", i); + snprintf(dev_name, sizeof(dev_name), "port.%d", i); } DEBUG(" === Dispatch stats for port %d (name=%s; stats_count=%d)", i, @@ -495,32 +490,30 @@ static int dpdk_stats_read(user_data_t *ud) { return 0; } -static int dpdk_stats_init(void) { +static int dpdk_stats_shutdown(void) { DPDK_STATS_TRACE(); - int ret = 0; - ret = dpdk_stats_preinit(); - if (ret != 0) { - return ret; - } + dpdk_helper_shutdown(g_hc); + g_hc = NULL; return 0; } -static int dpdk_stats_shutdown(void) { +static int dpdk_stats_init(void) { DPDK_STATS_TRACE(); - int ret = 0; - ret = dpdk_helper_shutdown(g_hc); - g_hc = NULL; + if (g_state != DPDK_STAT_STATE_OKAY) { + dpdk_stats_shutdown(); + return -1; + } + + ret = dpdk_stats_preinit(); if (ret != 0) { - ERROR("%s: failed to cleanup %s helper", DPDK_STATS_PLUGIN, - g_shm_name); return ret; } - return ret; + return 0; } void module_register(void) {