diff --git a/api/agent.h b/api/agent.h index ae1708b4..73844e5d 100644 --- a/api/agent.h +++ b/api/agent.h @@ -64,6 +64,9 @@ yanet_shm_detach(struct yanet_shm *shm); struct dp_config * yanet_shm_dp_config(struct yanet_shm *shm, uint32_t instance_idx); +struct dp_config * +yanet_shm_global_dp_config(struct yanet_shm *shm); + // Attaches a module agent to shared memory. // // Creates a new agent for a specific module in the given dataplane instance. diff --git a/api/counter.h b/api/counter.h index b2c4a794..bbf653dd 100644 --- a/api/counter.h +++ b/api/counter.h @@ -49,6 +49,9 @@ yanet_get_chain_counters( const char *chain_name ); +struct counter_handle_list * +yanet_get_nic_counters(struct dp_config *dp_config); + // Get module counters, optionally filtered by name. struct counter_handle_list * yanet_get_module_counters( diff --git a/controlplane/ffi/shm.go b/controlplane/ffi/shm.go index b72d0204..7c581757 100644 --- a/controlplane/ffi/shm.go +++ b/controlplane/ffi/shm.go @@ -70,6 +70,12 @@ func (m *SharedMemory) DPConfig(instanceIdx uint32) *DPConfig { return &DPConfig{ptr: ptr} } +func (m *SharedMemory) DPGlobalConfig() *DPConfig { + ptr := C.yanet_shm_global_dp_config(m.ptr) + + return &DPConfig{ptr: ptr} +} + // AgentAttach attaches a module agent to shared memory on the dataplane instance. func (m *SharedMemory) AgentAttach( name string, @@ -754,6 +760,17 @@ func (m *DPConfig) PerformanceCounters( return result, nil } +func (m *DPConfig) NICCounters() []CounterInfo { + counters := C.yanet_get_nic_counters(m.ptr) + defer C.yanet_counter_handle_list_free(counters) + + if counters == nil { + return nil + } + + return m.encodeCounters(counters) +} + type ModuleReference struct { Device string Pipeline string diff --git a/controlplane/internal/gateway/counters_service.go b/controlplane/internal/gateway/counters_service.go index 68783d76..c04d8d3b 100644 --- a/controlplane/internal/gateway/counters_service.go +++ b/controlplane/internal/gateway/counters_service.go @@ -129,6 +129,20 @@ func (m *CountersService) Module( return response, nil } +func (m *CountersService) NIC( + ctx context.Context, + request *ynpb.NICCounterRequest, +) (*ynpb.CountersResponse, error) { + dpConfig := m.shm.DPGlobalConfig() + counterValues := dpConfig.NICCounters() + + response := &ynpb.CountersResponse{ + Counters: m.encodeCounters(counterValues), + } + + return response, nil +} + func (m *CountersService) Perf( ctx context.Context, request *ynpb.PerfCountersRequest, diff --git a/controlplane/ynpb/counters.proto b/controlplane/ynpb/counters.proto index 97c8cd36..99bd765e 100644 --- a/controlplane/ynpb/counters.proto +++ b/controlplane/ynpb/counters.proto @@ -11,11 +11,14 @@ service CountersService { rpc Function(FunctionCountersRequest) returns (CountersResponse) {} rpc Chain(ChainCountersRequest) returns (CountersResponse) {} rpc Module(ModuleCountersRequest) returns (CountersResponse) {} + rpc NIC(NICCounterRequest) returns (CountersResponse) {} rpc Perf(PerfCountersRequest) returns (PerfCountersResponse) {} } message DeviceCountersRequest { string device = 1; } +message NICCounterRequest { string device = 1; } + message PipelineCountersRequest { string device = 1; string pipeline = 2; diff --git a/dataplane/config.c b/dataplane/config.c index 4f57a04a..762d1d76 100644 --- a/dataplane/config.c +++ b/dataplane/config.c @@ -38,6 +38,15 @@ enum state { state_connection_dst, state_loglevel, + + state_globalstats, + state_globalstat, + state_globalstat_dp_memory, + state_globalstat_cp_memory, + + state_updatetimes, + state_updatetime, + state_updatetime_nic_updatetime, }; int @@ -129,6 +138,18 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { goto error; state = state_instance; break; + case state_globalstat_dp_memory: + dataplane->globalstat.dp_memory = strtol(start, &end, 10); + if (*end != '\0') + goto error; + state = state_globalstat; + break; + case state_globalstat_cp_memory: + dataplane->globalstat.cp_memory = strtol(start, &end, 10); + if (*end != '\0') + goto error; + state = state_globalstat; + break; case state_device_port_name: strtcpy(device->port_name, @@ -207,6 +228,13 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { goto error; state = state_connection; break; + case state_updatetime_nic_updatetime: + dataplane->updatetimes.nic_updatetime = + strtol(start, &end, 10); + if (*end != '\0') + goto error; + state = state_updatetime; + break; case state_empty: if (!strcmp("dataplane", start)) { @@ -226,6 +254,10 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { state = state_devices; } else if (!strcmp("connections", start)) { state = state_connections; + } else if (!strcmp("globalstats", start)) { + state = state_globalstats; + } else if (!strcmp("updatetimes", start)) { + state = state_updatetimes; } else if (!strcmp("loglevel", start)) { state = state_loglevel; } else { @@ -287,7 +319,22 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { } break; } - + case state_globalstat: + if (!strcmp("dp_memory", start)) { + state = state_globalstat_dp_memory; + } else if (!strcmp("cp_memory", start)) { + state = state_globalstat_cp_memory; + } else { + goto error; + } + break; + case state_updatetime: + if (!strcmp("nic_updatetime", start)) { + state = state_updatetime_nic_updatetime; + } else { + goto error; + } + break; default: goto error; } @@ -322,6 +369,12 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { case state_connections: state = state_dataplane; break; + case state_globalstats: + state = state_dataplane; + break; + case state_updatetimes: + state = state_dataplane; + break; default: goto error; } @@ -333,6 +386,14 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { break; case state_dataplane: break; + case state_globalstats: { + state = state_globalstat; + break; + } + case state_updatetimes: { + state = state_updatetime; + break; + } case state_instances: { ++dataplane->instance_count; @@ -433,6 +494,9 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { case state_connection: state = state_connections; break; + case state_globalstat: + state = state_dataplane; + break; default: goto error; } @@ -449,6 +513,11 @@ dataplane_config_init(FILE *file, struct dataplane_config **config) { yaml_parser_delete(&parser); + // TODO: delete + dataplane->globalstat.cp_memory = (1 << 30) / 2; + dataplane->globalstat.dp_memory = (1 << 30) / 2; + dataplane->updatetimes.nic_updatetime = 1; + *config = dataplane; return 0; diff --git a/dataplane/config.h b/dataplane/config.h index feead579..2b418a8f 100644 --- a/dataplane/config.h +++ b/dataplane/config.h @@ -33,6 +33,16 @@ struct dataplane_connection_config { uint64_t dst_device_id; }; +struct dataplane_globalstat_config { + uint64_t dp_memory; + uint64_t cp_memory; +}; + +struct dataplane_events_updatetime { + uint64_t nic_updatetime; +}; + + struct dataplane_config { char storage[80]; uint64_t dpdk_memory; @@ -46,6 +56,10 @@ struct dataplane_config { struct dataplane_device_config *devices; uint64_t connection_count; struct dataplane_connection_config *connections; + + struct dataplane_globalstat_config globalstat; + struct dataplane_events_updatetime updatetimes; + char loglevel[32]; }; diff --git a/dataplane/dataplane.c b/dataplane/dataplane.c index d70772e5..c78a3297 100644 --- a/dataplane/dataplane.c +++ b/dataplane/dataplane.c @@ -35,6 +35,8 @@ #include "sys/mman.h" #include +#include "globalstat.h" + static int dataplane_worker_connect( struct dataplane *dataplane, @@ -349,6 +351,65 @@ dataplane_init_storage( return 0; } +int +dataplane_globalstat_storage_init( + struct dataplane *dataplane, + void *storage, + struct dataplane_config *config +) { + uint64_t dp_memory = config->globalstat.dp_memory; + uint64_t cp_memory = config->globalstat.cp_memory; + + struct dp_config *dp_config = (struct dp_config *)storage; + dataplane->global_dp_config = dp_config; + + block_allocator_init(&dp_config->block_allocator); + block_allocator_put_arena( + &dp_config->block_allocator, + storage + sizeof(struct dp_config), + dp_memory - sizeof(struct dp_config) + ); + memory_context_init( + &dp_config->memory_context, "dp", &dp_config->block_allocator + ); + + dp_config->config_lock = 0; + + dp_config->dp_modules = NULL; + dp_config->module_count = 0; + + dp_config->workers = NULL; + dp_config->worker_count = 0; + + struct cp_config *cp_config = + (struct cp_config *)((uintptr_t)storage + dp_memory); + dataplane->global_cp_config = cp_config; + + block_allocator_init(&cp_config->block_allocator); + block_allocator_put_arena( + &cp_config->block_allocator, + storage + dp_memory + sizeof(struct cp_config), + cp_memory - sizeof(struct cp_config) + ); + memory_context_init( + &cp_config->memory_context, "cp", &cp_config->block_allocator + ); + + // FIXME: cp_config bootstrap routine + struct cp_agent_registry *cp_agent_registry = + (struct cp_agent_registry *)memory_balloc( + &cp_config->memory_context, + sizeof(struct cp_agent_registry) + ); + cp_agent_registry->count = 0; + SET_OFFSET_OF(&cp_config->agent_registry, cp_agent_registry); + + SET_OFFSET_OF(&dp_config->cp_config, cp_config); + SET_OFFSET_OF(&cp_config->dp_config, dp_config); + + return 0; +} + int dataplane_init( struct dataplane *dataplane, @@ -381,6 +442,8 @@ dataplane_init( instance_config->cp_memory + instance_config->dp_memory; } + storage_size += config->globalstat.cp_memory + config->globalstat.dp_memory; + // FIXME: handle errors int mem_fd = open( config->storage, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR @@ -536,6 +599,47 @@ dataplane_init( instance_config->dp_memory + instance_config->cp_memory; } + //alloc global + { + LOG(INFO, "initialize storage for globalstats"); + int rc = dataplane_globalstat_storage_init( + dataplane, + storage + instance_offset, + config + ); + + if (rc == -1) { + LOG(ERROR, + "failed to initialize storage for globalstats"); + return -1; + } + + // FIXME: Stub agent for the instance configuration + struct agent agent; + memory_context_init_from( + &agent.memory_context, + &dataplane->global_cp_config->memory_context, + "stub agent" + ); + SET_OFFSET_OF(&agent.dp_config, dataplane->global_dp_config); + SET_OFFSET_OF(&agent.cp_config, dataplane->global_cp_config); + + yanet_error *err = NULL; + struct cp_config_gen *cp_config_gen = + cp_config_gen_create(&agent, &err); + if (cp_config_gen == NULL) { + LOG(ERROR, + "failed to create cp_config_gen: %s", + yanet_error_message(err)); + yanet_error_free(err); + return -1; + } + SET_OFFSET_OF( + &dataplane->global_cp_config->cp_config_gen, cp_config_gen + ); + } + + size_t pci_port_count = 0; const char **pci_port_names = (const char **)malloc(sizeof(char *) * config->device_count); @@ -603,7 +707,7 @@ dataplane_init( yanet_error *err = NULL; if (counter_registry_link( - &dp_config->worker_counters, NULL, &err + &dp_config->counters, NULL, &err )) { LOG(ERROR, "failed to link counter registry: %s", @@ -613,88 +717,62 @@ dataplane_init( } SET_OFFSET_OF( - &dp_config->worker_counter_storage, + &dp_config->counter_storage, counter_storage_spawn( &dp_config->memory_context, &dp_config->counter_storage_allocator, NULL, - &dp_config->worker_counters + &dp_config->counters ) ); } - return 0; -} - -static void * -stat_thread(void *arg) { - struct dataplane *dataplane = (struct dataplane *)arg; - - FILE *log = fopen("stat.log", "w"); + //init dataplane global + { + struct dp_config *dp_config = dataplane->global_dp_config; - struct rte_eth_xstat_name names[4096]; - struct rte_eth_xstat xstats0[dataplane->device_count][4096]; - - struct rte_eth_stats stats0[dataplane->device_count]; - for (uint16_t idx = 0; idx < dataplane->device_count; ++idx) { - rte_eth_stats_get( - dataplane->devices[idx].port_id, &stats0[idx] + counter_storage_allocator_init( + &dp_config->counter_storage_allocator, + &dp_config->memory_context, + 1 // only for global counters ); - rte_eth_xstats_get( - dataplane->devices[idx].port_id, xstats0[idx], 4096 + + struct cp_config *cp_config = dataplane->global_cp_config; + counter_storage_allocator_init( + &cp_config->counter_storage_allocator, + &cp_config->memory_context, + dp_config->worker_count ); - } - - while (1) { - sleep(1); - - for (uint16_t idx = 0; idx < dataplane->device_count; ++idx) { - struct rte_eth_stats stats1; - rte_eth_stats_get( - dataplane->devices[idx].port_id, &stats1 - ); - fprintf(log, - "dev %u ib %li ob %li ip %li op %li ie %li oe " - "%li\n", - idx, - (int64_t)(stats1.ibytes - stats0[idx].ibytes), - (int64_t)(stats1.obytes - stats0[idx].obytes), - (int64_t)(stats1.ipackets - stats0[idx].ipackets - ), - (int64_t)(stats1.opackets - stats0[idx].opackets - ), - (int64_t)(stats1.ierrors - stats0[idx].ierrors), - (int64_t)(stats1.oerrors - stats0[idx].oerrors) - ); - - memcpy(&stats0[idx], &stats1, sizeof(stats1)); - - struct rte_eth_xstat xstats1[4096]; - rte_eth_xstats_get_names( - dataplane->devices[idx].port_id, names, 4096 - ); - int cnt = rte_eth_xstats_get( - dataplane->devices[idx].port_id, xstats1, 4096 - ); - - for (int pth = 0; pth < cnt; ++pth) { - fprintf(log, - "xstat %u %s %lu\n", - idx, - names[xstats1[pth].id].name, - xstats1[pth].value - - xstats0[idx][pth].value); - } - memcpy(&xstats0[idx], - xstats1, - sizeof(struct rte_eth_xstat) * cnt); + if (dataplane_globalstat_register_counters(dp_config)) { + LOG(ERROR, + "failed to register global NIC counters"); + return -1; } - fflush(log); + yanet_error *err = NULL; + if (counter_registry_link( + &dp_config->counters, NULL, &err + )) { + LOG(ERROR, + "failed to link counter registry: %s", + yanet_error_message(err)); + yanet_error_free(err); + return -1; + } + + SET_OFFSET_OF( + &dp_config->counter_storage, + counter_storage_spawn( + &dp_config->memory_context, + &dp_config->counter_storage_allocator, + NULL, + &dp_config->counters + ) + ); } - return NULL; + return 0; } int @@ -702,8 +780,29 @@ dataplane_start(struct dataplane *dataplane) { for (size_t dev_idx = 0; dev_idx < dataplane->device_count; ++dev_idx) { dataplane_device_start(dataplane, dataplane->devices + dev_idx); } + + return 0; +} + +int +dataplane_daemons_start(struct dataplane *dataplane, struct dataplane_config *config) { pthread_t thread_id; - pthread_create(&thread_id, NULL, stat_thread, dataplane); + + struct stat_thread_args { + struct dataplane *dataplane; + struct dataplane_config *config; + }; + + struct stat_thread_args *args = malloc(sizeof(struct stat_thread_args)); + if (args == NULL) { + LOG(ERROR, "failed to allocate memory for stat_thread_args"); + return -1; + } + + args->dataplane = dataplane; + args->config = config; + + pthread_create(&thread_id, NULL, stat_nic_thread, args); return 0; } diff --git a/dataplane/dataplane.h b/dataplane/dataplane.h index b30d09c8..b7680019 100644 --- a/dataplane/dataplane.h +++ b/dataplane/dataplane.h @@ -3,6 +3,8 @@ #include #include +#include "globalstat.h" + struct dataplane_config; struct dataplane_device; @@ -19,6 +21,11 @@ struct dataplane { struct dataplane_device *devices; uint32_t device_count; + + struct dp_config *global_dp_config; + struct cp_config *global_cp_config; + + struct dataplane_stats global_stats; }; int @@ -31,6 +38,9 @@ dataplane_init( int dataplane_start(struct dataplane *dataplane); +int +dataplane_daemons_start(struct dataplane *dataplane, struct dataplane_config *config); + int dataplane_stop(struct dataplane *dataplane); diff --git a/dataplane/globalstat.c b/dataplane/globalstat.c new file mode 100644 index 00000000..4ea84ca7 --- /dev/null +++ b/dataplane/globalstat.c @@ -0,0 +1,158 @@ +#include "globalstat.h" + +#include "dataplane.h" + +#include + +#include +#include + +#include "dataplane/device.h" +#include "dataplane/worker.h" + +#include "counters/counters.h" +#include "lib/dataplane/config/zone.h" +#include "lib/errors/errors.h" +#include "logging/log.h" + +#define ARRAY_SIZE(arr) (size_t)(sizeof(arr) / sizeof((arr)[0])) + +static int +counter_register_counter( + struct dp_config *dp_config, const char *name, uint64_t size +) { + yanet_error *err = NULL; + uint64_t rc = counter_registry_register( + &dp_config->counters, name, size, &err + ); + if (rc == COUNTER_INVALID) { + LOG(ERROR, + "failed to register '%s' counter: %s", + name, + yanet_error_message(err)); + yanet_error_free(err); + return -1; + } + + return rc; +} + +static const struct { + const char *name; + uint64_t size; + const size_t *offset; +} global_counter_info[] = { + {"nic_rx", 2, (const size_t[]){offsetof(struct dataplane, global_stats.nic_stats.rx_count), offsetof(struct dataplane, global_stats.nic_stats.rx_size)}}, + {"nic_tx", 2, (const size_t[]){offsetof(struct dataplane, global_stats.nic_stats.tx_count), offsetof(struct dataplane, global_stats.nic_stats.tx_size)}}, + {"nic_rx_tx_errors", 2, (const size_t[]){offsetof(struct dataplane, global_stats.nic_stats.remote_rx_count), offsetof(struct dataplane, global_stats.nic_stats.remote_tx_count)}}, + {"nic_rx_nombuf", 1, (const size_t[]){offsetof(struct dataplane, global_stats.nic_stats.rx_nombuf_count)}}, +}; + +static uint64_t global_counter_ids[ARRAY_SIZE(global_counter_info)]; + +int +dataplane_globalstat_register_counters(struct dp_config *dp_config) { + counter_registry_init( + &dp_config->counters, &dp_config->memory_context, 0 + ); + + for (size_t i = 0; i < ARRAY_SIZE(global_counter_info); ++i) { + uint64_t id = counter_register_counter( + dp_config, + global_counter_info[i].name, + global_counter_info[i].size + ); + if (id == COUNTER_INVALID) { + return -1; + } + global_counter_ids[i] = id; + } + + return 0; +} + +uint64_t** +get_worker_field_ptr(struct dataplane *dataplane, size_t info_index, size_t offset_index) { + return (uint64_t**)((char*)dataplane + global_counter_info[info_index].offset[offset_index]); +} + +static void +calculate_and_update_stats( + struct dataplane *dataplane, + struct rte_eth_stats *prev_stats, + struct rte_eth_stats *cur_stats +) { + struct nic_stats *nic_stats = &dataplane->global_stats.nic_stats; + + uint64_t rx_count = 0, tx_count = 0; + uint64_t rx_size = 0, tx_size = 0; + uint64_t rx_errors = 0, tx_errors = 0; + uint64_t rx_nombuf = 0; + + for (uint16_t idx = 0; idx < dataplane->device_count; ++idx) { + rx_count += cur_stats[idx].ipackets - prev_stats[idx].ipackets; + tx_count += cur_stats[idx].opackets - prev_stats[idx].opackets; + rx_size += cur_stats[idx].ibytes - prev_stats[idx].ibytes; + tx_size += cur_stats[idx].obytes - prev_stats[idx].obytes; + rx_errors += cur_stats[idx].ierrors - prev_stats[idx].ierrors; + tx_errors += cur_stats[idx].oerrors - prev_stats[idx].oerrors; + rx_nombuf += cur_stats[idx].rx_nombuf - prev_stats[idx].rx_nombuf; + } + + *nic_stats->rx_count = rx_count; + *nic_stats->tx_count = tx_count; + *nic_stats->rx_size = rx_size; + *nic_stats->tx_size = tx_size; + *nic_stats->remote_rx_count = rx_errors; + *nic_stats->remote_tx_count = tx_errors; + *nic_stats->rx_nombuf_count = rx_nombuf; +} + +void * +stat_nic_thread(void *arg) { + struct stat_thread_args { + struct dataplane *dataplane; + struct dataplane_config *config; + } *args = (struct stat_thread_args *)arg; + struct dataplane *dataplane = args->dataplane; + struct dataplane_config *config = args->config; + + free(args); + + struct dp_config *dp_config = dataplane->global_dp_config; + + for (size_t i = 0; i < ARRAY_SIZE(global_counter_info); ++i) { + for (size_t j = 0; j < global_counter_info[i].size; ++j) { + uint64_t **field_ptr = get_worker_field_ptr(dataplane, i, j); + *field_ptr = counter_get_address( + global_counter_ids[i], + 0, + ADDR_OF(&dp_config->counter_storage) + ) + j; + } + } + + struct rte_eth_stats stats_prev[dataplane->device_count]; + struct rte_eth_stats stats_cur[dataplane->device_count]; + + memset(stats_prev, 0, sizeof(stats_prev)); + memset(stats_cur, 0, sizeof(stats_cur)); + + for (uint16_t idx = 0; idx < dataplane->device_count; ++idx) { + rte_eth_stats_get(dataplane->devices[idx].port_id, &stats_prev[idx]); + } + + while (1) { + sleep(config->updatetimes.nic_updatetime); + + for (uint16_t idx = 0; idx < dataplane->device_count; ++idx) { + rte_eth_stats_get(dataplane->devices[idx].port_id, &stats_cur[idx]); + } + + calculate_and_update_stats(dataplane, stats_prev, stats_cur); + + memcpy(stats_prev, stats_cur, sizeof(stats_prev)); + } + + return NULL; +} \ No newline at end of file diff --git a/dataplane/globalstat.h b/dataplane/globalstat.h new file mode 100644 index 00000000..f53c275b --- /dev/null +++ b/dataplane/globalstat.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +struct nic_stats { + uint64_t *rx_count; + uint64_t *rx_size; + + uint64_t *tx_count; + uint64_t *tx_size; + + uint64_t *remote_rx_count; + uint64_t *remote_tx_count; + + uint64_t *rx_nombuf_count; +}; + +struct dataplane_stats { + struct nic_stats nic_stats; +}; + +struct dp_config; + +int +dataplane_globalstat_register_counters(struct dp_config *dp_config); + +void * +stat_nic_thread(void* arg); \ No newline at end of file diff --git a/dataplane/main.c b/dataplane/main.c index b5dff74a..a437dea4 100644 --- a/dataplane/main.c +++ b/dataplane/main.c @@ -90,6 +90,9 @@ main(int argc, char **argv) { LOG(INFO, "start dataplane"); dataplane_start(&dataplane); + LOG(INFO, "start dataplane daemons"); + dataplane_daemons_start(&dataplane, config); + // FIXME: infinite sleep effectively LOG(INFO, "wait dataplane"); dataplane_stop(&dataplane); diff --git a/dataplane/meson.build b/dataplane/meson.build index c3e2e625..c3730bae 100644 --- a/dataplane/meson.build +++ b/dataplane/meson.build @@ -16,6 +16,7 @@ lib_sources = files( 'config.c', 'dataplane.c', 'device.c', + 'globalstat.c', 'worker.c', ) diff --git a/dataplane/worker.c b/dataplane/worker.c index c7e584a8..43400385 100644 --- a/dataplane/worker.c +++ b/dataplane/worker.c @@ -414,7 +414,7 @@ worker_register_counter( ) { yanet_error *err = NULL; uint64_t rc = counter_registry_register( - &dp_config->worker_counters, name, size, &err + &dp_config->counters, name, size, &err ); if (rc == COUNTER_INVALID) { LOG(ERROR, @@ -571,7 +571,7 @@ dataplane_worker_init( // Prepare counter registry counter_registry_init( - &dp_config->worker_counters, &dp_config->memory_context, 0 + &dp_config->counters, &dp_config->memory_context, 0 ); if (worker_register_counter(dp_config, "iterations", 1)) { @@ -605,20 +605,20 @@ dataplane_worker_start(struct dataplane_worker *worker) { struct dp_config *dp_config = worker->instance->dp_config; // FIXME: do not use hard-coded counter identifiers dp_worker->iterations = counter_get_address( - 0, dp_worker->idx, ADDR_OF(&dp_config->worker_counter_storage) + 0, dp_worker->idx, ADDR_OF(&dp_config->counter_storage) ); dp_worker->rx_count = counter_get_address( 1, dp_worker->idx, - ADDR_OF(&dp_config->worker_counter_storage) + ADDR_OF(&dp_config->counter_storage) ) + 0; dp_worker->rx_size = counter_get_address( 1, dp_worker->idx, - ADDR_OF(&dp_config->worker_counter_storage) + ADDR_OF(&dp_config->counter_storage) ) + 1; @@ -626,13 +626,13 @@ dataplane_worker_start(struct dataplane_worker *worker) { counter_get_address( 2, dp_worker->idx, - ADDR_OF(&dp_config->worker_counter_storage) + ADDR_OF(&dp_config->counter_storage) ) + 0; dp_worker->tx_size = counter_get_address( 2, dp_worker->idx, - ADDR_OF(&dp_config->worker_counter_storage) + ADDR_OF(&dp_config->counter_storage) ) + 1; @@ -640,7 +640,7 @@ dataplane_worker_start(struct dataplane_worker *worker) { counter_get_address( 3, dp_worker->idx, - ADDR_OF(&dp_config->worker_counter_storage) + ADDR_OF(&dp_config->counter_storage) ) + 0; @@ -648,7 +648,7 @@ dataplane_worker_start(struct dataplane_worker *worker) { counter_get_address( 4, dp_worker->idx, - ADDR_OF(&dp_config->worker_counter_storage) + ADDR_OF(&dp_config->counter_storage) ) + 0; diff --git a/lib/controlplane/agent/agent.c b/lib/controlplane/agent/agent.c index 64792f3a..32d15e8d 100644 --- a/lib/controlplane/agent/agent.c +++ b/lib/controlplane/agent/agent.c @@ -70,6 +70,11 @@ yanet_shm_dp_config(struct yanet_shm *shm, uint32_t instance_idx) { return dp_config_nextk((struct dp_config *)shm, instance_idx); } +struct dp_config * +yanet_shm_global_dp_config(struct yanet_shm *shm) { + return dp_config_nextk((struct dp_config *)shm, yanet_shm_instance_count(shm)); +} + uint32_t yanet_shm_instance_count(struct yanet_shm *shm) { struct dp_config *dp_config = yanet_shm_dp_config(shm, 0); @@ -1633,6 +1638,36 @@ yanet_get_pipeline_counters( return list; } +struct counter_handle_list * +yanet_get_nic_counters(struct dp_config *dp_config) { + struct counter_registry *counter_registry = &dp_config->counters; + struct counter_storage *storage = + ADDR_OF(&dp_config->counter_storage); + + uint64_t count = counter_registry->count; + struct counter *names = ADDR_OF(&counter_registry->names); + + struct counter_handle_list *list = (struct counter_handle_list *)malloc( + sizeof(struct counter_handle_list) + + sizeof(struct counter_handle) * count + ); + + if (list == NULL) + return NULL; + list->instance_count = ADDR_OF(&storage->allocator)->instance_count; + list->count = count; + struct counter_handle *handlers = list->counters; + + for (uint64_t idx = 0; idx < count; ++idx) { + strtcpy(handlers[idx].name, names[idx].name, 60); + handlers[idx].size = names[idx].size; + handlers[idx].gen = names[idx].gen; + handlers[idx].value_handle = + counter_get_value_handle(idx, storage); + } + return list; +} + struct counter_handle_list * yanet_get_device_counters( struct dp_config *dp_config, const char *device_name @@ -1703,9 +1738,9 @@ yanet_get_counter_value( struct counter_handle_list * yanet_get_worker_counters(struct dp_config *dp_config) { - struct counter_registry *counter_registry = &dp_config->worker_counters; + struct counter_registry *counter_registry = &dp_config->counters; struct counter_storage *storage = - ADDR_OF(&dp_config->worker_counter_storage); + ADDR_OF(&dp_config->counter_storage); uint64_t count = counter_registry->count; struct counter *names = ADDR_OF(&counter_registry->names); diff --git a/lib/dataplane/config/zone.h b/lib/dataplane/config/zone.h index 1c664314..6519b6d4 100644 --- a/lib/dataplane/config/zone.h +++ b/lib/dataplane/config/zone.h @@ -93,8 +93,8 @@ struct dp_config { struct dp_worker **workers; struct counter_storage_allocator counter_storage_allocator; - struct counter_registry worker_counters; - struct counter_storage *worker_counter_storage; + struct counter_registry counters; + struct counter_storage *counter_storage; }; /* diff --git a/mock/mock.c b/mock/mock.c index 78e90076..407ff857 100644 --- a/mock/mock.c +++ b/mock/mock.c @@ -255,7 +255,7 @@ dataplane_initialize( ); err = NULL; - if (counter_registry_link(&dp_config->worker_counters, NULL, &err)) { + if (counter_registry_link(&dp_config->counters, NULL, &err)) { LOG(ERROR, "failed to link counter registry: %s", yanet_error_message(err));