X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_eal%2Fcommon%2Frte_service.c;h=79235c03f8a9aacb438df8afed12708a6a8eeb25;hb=e0ab8020ac2a5b379bb91fbe882ac3b08d333586;hp=bcd644a8a4c649d0042e76f423bf674e4f76cb8c;hpb=da23f0aa87d83e481295ceb5283a34232c336f36;p=dpdk.git diff --git a/lib/librte_eal/common/rte_service.c b/lib/librte_eal/common/rte_service.c index bcd644a8a4..79235c03f8 100644 --- a/lib/librte_eal/common/rte_service.c +++ b/lib/librte_eal/common/rte_service.c @@ -7,8 +7,8 @@ #include #include #include -#include +#include #include #include "include/rte_service_component.h" @@ -21,6 +21,8 @@ #include #include +#include "eal_private.h" + #define RTE_SERVICE_NUM_MAX 64 #define SERVICE_F_REGISTERED (1 << 0) @@ -59,8 +61,8 @@ struct core_state { uint64_t service_mask; uint8_t runstate; /* running or stopped */ uint8_t is_service_core; /* set if core is currently a service core */ - - /* extreme statistics */ + uint8_t service_active_on_lcore[RTE_SERVICE_NUM_MAX]; + uint64_t loops; uint64_t calls_per_service[RTE_SERVICE_NUM_MAX]; } __rte_cache_aligned; @@ -69,10 +71,12 @@ static struct rte_service_spec_impl *rte_services; static struct core_state *lcore_states; static uint32_t rte_service_library_initialized; -int32_t rte_service_init(void) +int32_t +rte_service_init(void) { if (rte_service_library_initialized) { - printf("service library init() called, init flag %d\n", + RTE_LOG(NOTICE, EAL, + "service library init() called, init flag %d\n", rte_service_library_initialized); return -EALREADY; } @@ -81,14 +85,14 @@ int32_t rte_service_init(void) sizeof(struct rte_service_spec_impl), RTE_CACHE_LINE_SIZE); if (!rte_services) { - printf("error allocating rte services array\n"); + RTE_LOG(ERR, EAL, "error allocating rte services array\n"); goto fail_mem; } lcore_states = rte_calloc("rte_service_core_states", RTE_MAX_LCORE, sizeof(struct core_state), RTE_CACHE_LINE_SIZE); if (!lcore_states) { - printf("error allocating core states array\n"); + RTE_LOG(ERR, EAL, "error allocating core states array\n"); goto fail_mem; } @@ -107,23 +111,19 @@ int32_t rte_service_init(void) rte_service_library_initialized = 1; return 0; fail_mem: - if (rte_services) - rte_free(rte_services); - if (lcore_states) - rte_free(lcore_states); + rte_free(rte_services); + rte_free(lcore_states); return -ENOMEM; } -void rte_service_finalize(void) +void +rte_service_finalize(void) { if (!rte_service_library_initialized) return; - if (rte_services) - rte_free(rte_services); - - if (lcore_states) - rte_free(lcore_states); + rte_free(rte_services); + rte_free(lcore_states); rte_service_library_initialized = 0; } @@ -159,7 +159,8 @@ service_mt_safe(struct rte_service_spec_impl *s) return !!(s->spec.capabilities & RTE_SERVICE_CAP_MT_SAFE); } -int32_t rte_service_set_stats_enable(uint32_t id, int32_t enabled) +int32_t +rte_service_set_stats_enable(uint32_t id, int32_t enabled) { struct rte_service_spec_impl *s; SERVICE_VALID_GET_OR_ERR_RET(id, s, 0); @@ -172,7 +173,8 @@ int32_t rte_service_set_stats_enable(uint32_t id, int32_t enabled) return 0; } -int32_t rte_service_set_runstate_mapped_check(uint32_t id, int32_t enabled) +int32_t +rte_service_set_runstate_mapped_check(uint32_t id, int32_t enabled) { struct rte_service_spec_impl *s; SERVICE_VALID_GET_OR_ERR_RET(id, s, 0); @@ -191,7 +193,8 @@ rte_service_get_count(void) return rte_service_count; } -int32_t rte_service_get_by_name(const char *name, uint32_t *service_id) +int32_t +rte_service_get_by_name(const char *name, uint32_t *service_id) { if (!service_id) return -EINVAL; @@ -349,8 +352,12 @@ service_run(uint32_t i, struct core_state *cs, uint64_t service_mask) struct rte_service_spec_impl *s = &rte_services[i]; if (s->comp_runstate != RUNSTATE_RUNNING || s->app_runstate != RUNSTATE_RUNNING || - !(service_mask & (UINT64_C(1) << i))) + !(service_mask & (UINT64_C(1) << i))) { + cs->service_active_on_lcore[i] = 0; return -ENOEXEC; + } + + cs->service_active_on_lcore[i] = 1; /* check do we need cmpset, if MT safe or <= 1 core * mapped, atomic ops are not required. @@ -369,8 +376,26 @@ service_run(uint32_t i, struct core_state *cs, uint64_t service_mask) return 0; } -int32_t rte_service_run_iter_on_app_lcore(uint32_t id, - uint32_t serialize_mt_unsafe) +int32_t +rte_service_may_be_active(uint32_t id) +{ + uint32_t ids[RTE_MAX_LCORE] = {0}; + int32_t lcore_count = rte_service_lcore_list(ids, RTE_MAX_LCORE); + int i; + + if (!service_valid(id)) + return -EINVAL; + + for (i = 0; i < lcore_count; i++) { + if (lcore_states[i].service_active_on_lcore[id]) + return 1; + } + + return 0; +} + +int32_t +rte_service_run_iter_on_app_lcore(uint32_t id, uint32_t serialize_mt_unsafe) { /* run service on calling core, using all-ones as the service mask */ if (!service_valid(id)) @@ -417,6 +442,8 @@ rte_service_runner_func(void *arg) service_run(i, cs, service_mask); } + cs->loops++; + rte_smp_rmb(); } @@ -592,7 +619,8 @@ set_lcore_state(uint32_t lcore, int32_t state) lcore_states[lcore].is_service_core = (state == ROLE_SERVICE); } -int32_t rte_service_lcore_reset_all(void) +int32_t +rte_service_lcore_reset_all(void) { /* loop over cores, reset all to mask 0 */ uint32_t i; @@ -703,7 +731,7 @@ rte_service_lcore_stop(uint32_t lcore) } int32_t -rte_service_attr_get(uint32_t id, uint32_t attr_id, uint32_t *attr_value) +rte_service_attr_get(uint32_t id, uint32_t attr_id, uint64_t *attr_value) { struct rte_service_spec_impl *s; SERVICE_VALID_GET_OR_ERR_RET(id, s, -EINVAL); @@ -723,6 +751,28 @@ rte_service_attr_get(uint32_t id, uint32_t attr_id, uint32_t *attr_value) } } +int32_t +rte_service_lcore_attr_get(uint32_t lcore, uint32_t attr_id, + uint64_t *attr_value) +{ + struct core_state *cs; + + if (lcore >= RTE_MAX_LCORE || !attr_value) + return -EINVAL; + + cs = &lcore_states[lcore]; + if (!cs->is_service_core) + return -ENOTSUP; + + switch (attr_id) { + case RTE_SERVICE_LCORE_ATTR_LOOPS: + *attr_value = cs->loops; + return 0; + default: + return -EINVAL; + } +} + static void rte_service_dump_one(FILE *f, struct rte_service_spec_impl *s, uint64_t all_cycles, uint32_t reset) @@ -741,6 +791,9 @@ rte_service_dump_one(FILE *f, struct rte_service_spec_impl *s, return; } + if (f == NULL) + return; + fprintf(f, " %s: stats %d\tcalls %"PRIu64"\tcycles %" PRIu64"\tavg: %"PRIu64"\n", s->spec.name, service_stats_enabled(s), s->calls, @@ -758,6 +811,23 @@ rte_service_attr_reset_all(uint32_t id) return 0; } +int32_t +rte_service_lcore_attr_reset_all(uint32_t lcore) +{ + struct core_state *cs; + + if (lcore >= RTE_MAX_LCORE) + return -EINVAL; + + cs = &lcore_states[lcore]; + if (!cs->is_service_core) + return -ENOTSUP; + + cs->loops = 0; + + return 0; +} + static void service_dump_calls_per_lcore(FILE *f, uint32_t lcore, uint32_t reset) { @@ -775,7 +845,8 @@ service_dump_calls_per_lcore(FILE *f, uint32_t lcore, uint32_t reset) fprintf(f, "\n"); } -int32_t rte_service_dump(FILE *f, uint32_t id) +int32_t +rte_service_dump(FILE *f, uint32_t id) { uint32_t i; int print_one = (id != UINT32_MAX);