diff --git a/include/monitoring/dp_graphtrace_shared.h b/include/monitoring/dp_graphtrace_shared.h index 375fb3ea9..ce3a39cac 100644 --- a/include/monitoring/dp_graphtrace_shared.h +++ b/include/monitoring/dp_graphtrace_shared.h @@ -21,15 +21,16 @@ extern "C" { #endif enum dp_graphtrace_action { - DP_GRAPHTRACE_ACTION_NULL, DP_GRAPHTRACE_ACTION_START, DP_GRAPHTRACE_ACTION_STOP, - DP_GRAPHTRACE_ACTION_ENABLE_HW_CAPTURE, - DP_GRAPHTRACE_ACTION_DISABLE_HW_CAPTURE, +}; + +enum dp_graphtrace_op_type { + DP_GRAPHTRACE_OP_TYPE_SOFTWARE, + DP_GRAPHTRACE_OP_TYPE_OFFLOAD, }; enum dp_graphtrace_pkt_type { - DP_GRAPHTRACE_PKT_TYPE_UNKNOWN = 0, DP_GRAPHTRACE_PKT_TYPE_SOFTWARE, DP_GRAPHTRACE_PKT_TYPE_OFFLOAD, }; @@ -48,6 +49,9 @@ struct dp_graphtrace_pktinfo { struct dp_graphtrace_mp_request { uint8_t action; + union { + enum dp_graphtrace_op_type op_type; + } action_params; }; struct dp_graphtrace_mp_reply { diff --git a/src/dp_cntrack.c b/src/dp_cntrack.c index bd303a438..8b0e81fe3 100644 --- a/src/dp_cntrack.c +++ b/src/dp_cntrack.c @@ -262,7 +262,7 @@ static __rte_always_inline int dp_get_flow_val(struct rte_mbuf *m, struct dp_flo // flow is the same as it was for the previous packet *p_flow_val = cached_flow_val; if (dp_capture_offloaded_pkts(m, *p_flow_val, df)) - return DP_IS_CAPTURED_HW_PKT; // it is not really an error, but we need to stop processing this pkt + return DP_IS_CAPTURED_HW_PKT; dp_set_pkt_flow_direction(curr_key, cached_flow_val, df); dp_set_flow_offload_flag(m, cached_flow_val, df); return DP_OK; @@ -286,7 +286,7 @@ static __rte_always_inline int dp_get_flow_val(struct rte_mbuf *m, struct dp_flo } if (dp_capture_offloaded_pkts(m, *p_flow_val, df)) - return DP_IS_CAPTURED_HW_PKT; // it is not really an error, but we need to stop processing this pkt + return DP_IS_CAPTURED_HW_PKT; // already established flow found dp_set_pkt_flow_direction(curr_key, *p_flow_val, df); @@ -306,7 +306,7 @@ int dp_cntrack_handle(__rte_unused struct rte_node *node, struct rte_mbuf *m, st DPNODE_LOG_WARNING(node, "Cannot establish flow value", DP_LOG_RET(ret)); return ret; } else if (ret == DP_IS_CAPTURED_HW_PKT) - return ret; + return ret; // it is not really an error, but we need to stop processing this pkt flow_val->timestamp = rte_rdtsc(); diff --git a/src/dp_port.c b/src/dp_port.c index baa772ae8..eac2e74aa 100644 --- a/src/dp_port.c +++ b/src/dp_port.c @@ -448,11 +448,40 @@ static int dp_port_fill_info(struct dp_port *port) return DP_OK; } +static int dp_install_vf_init_rte_rules(uint32_t port_id) +{ + bool graphtrace_enabled = dp_graphtrace_is_enabled(); + int ret; + + if (graphtrace_enabled) + ret = dp_install_jump_rule_in_default_group(port_id, DP_RTE_FLOW_MONITORING_GROUP); + else + ret = dp_install_jump_rule_in_default_group(port_id, DP_RTE_FLOW_VNET_GROUP); + + if (DP_FAILED(ret)) { + DPS_LOG_ERR("Cannot install default jump rule", DP_LOG_PORTID(port_id), DP_LOG_RET(ret)); + return DP_ERROR; + } + + ret = dp_install_default_rule_in_monitoring_group(port_id); + if (DP_FAILED(ret)) { + DPS_LOG_ERR("Cannot install default rule in monitoring group", DP_LOG_PORTID(port_id), DP_LOG_RET(ret)); + return DP_ERROR; + } + + ret = dp_install_default_capture_rule_in_vnet_group(port_id); + if (DP_FAILED(ret)) { + DPS_LOG_ERR("Cannot install default capture rule in vnet group", DP_LOG_PORTID(port_id), DP_LOG_RET(ret)); + return DP_ERROR; + } + + return DP_OK; +} + int dp_port_start(uint16_t port_id) { struct dp_port *port; int ret; - bool graphtrace_enabled = dp_graphtrace_is_enabled(); port = dp_port_get(port_id); if (!port) @@ -486,27 +515,9 @@ int dp_port_start(uint16_t port_id) if (port->port_type == DP_PORT_VF) { - if (graphtrace_enabled) - ret = dp_install_jump_rule_in_default_group(port_id, DP_RTE_FLOW_MONITORING_GROUP); - else - ret = dp_install_jump_rule_in_default_group(port_id, DP_RTE_FLOW_VNET_GROUP); - - if (DP_FAILED(ret)) { - DPS_LOG_ERR("Cannot install default jump rule", DP_LOG_PORTID(port_id), DP_LOG_RET(ret)); - return DP_ERROR; - } - - ret = dp_install_default_rule_in_monitoring_group(port_id); - if (DP_FAILED(ret)) { - DPS_LOG_ERR("Cannot install default rule in monitoring group", DP_LOG_PORTID(port_id), DP_LOG_RET(ret)); - return DP_ERROR; - } - - ret = dp_install_default_capture_rule_in_vnet_group(port_id); - if (DP_FAILED(ret)) { - DPS_LOG_ERR("Cannot install default capture rule in vnet group", DP_LOG_PORTID(port_id), DP_LOG_RET(ret)); - return DP_ERROR; - } + ret = dp_install_vf_init_rte_rules(port_id); + if (DP_FAILED(ret)) + assert(0); // if any flow rule failed, stop process running due to possible hw/driver failure } } diff --git a/src/monitoring/dp_graphtrace.c b/src/monitoring/dp_graphtrace.c index efc937a17..99737a67e 100644 --- a/src/monitoring/dp_graphtrace.c +++ b/src/monitoring/dp_graphtrace.c @@ -17,6 +17,7 @@ static enum dp_graphtrace_loglevel graphtrace_loglevel; static struct dp_graphtrace graphtrace; bool _dp_graphtrace_enabled = false; +bool _dp_graphtrace_hw_enabled = false; static bool offload_enabled; static int dp_graphtrace_init_memzone(void) @@ -54,6 +55,67 @@ static void dp_graphtrace_free_memzone(void) graphtrace.mempool = NULL; } +static void dp_graphtrace_set_hw_enabled(bool enabled) +{ + _dp_graphtrace_hw_enabled = enabled; +} + +static int dp_handle_graphtrace_start(const struct dp_graphtrace_mp_request *request) +{ + int ret; + + switch ((enum dp_graphtrace_op_type)request->action_params.op_type) { + case DP_GRAPHTRACE_OP_TYPE_SOFTWARE: + dp_graphtrace_enable(); + DPS_LOG_INFO("Graphtrace enabled only for software path"); + return DP_OK; + case DP_GRAPHTRACE_OP_TYPE_OFFLOAD: + if (!offload_enabled) { + DPS_LOG_WARNING("Cannot start hardware capture, offload is not enabled"); + return -EPERM; + } + ret = dp_send_event_hardware_capture_start_msg(); + if (DP_FAILED(ret)) { + DPS_LOG_ERR("Cannot send hardware capture start message"); + return ret; + } + dp_graphtrace_enable(); + dp_graphtrace_set_hw_enabled(true); + DPS_LOG_INFO("Graphtrace enabled for software and offload paths"); + return DP_OK; + default: + DPS_LOG_ERR("Unknown graphtrace op type", DP_LOG_VALUE(request->action_params.op_type)); + return -EINVAL; + } + +} + +static int dp_handle_graphtrace_stop(const struct dp_graphtrace_mp_request *request) +{ + int ret; + + switch ((enum dp_graphtrace_op_type)request->action_params.op_type) { + case DP_GRAPHTRACE_OP_TYPE_SOFTWARE: + dp_graphtrace_disable(); + DPS_LOG_INFO("Graphtrace disabled only for software path"); + return DP_OK; + case DP_GRAPHTRACE_OP_TYPE_OFFLOAD: + if (_dp_graphtrace_hw_enabled) { + dp_graphtrace_disable(); + ret = dp_send_event_hardware_capture_stop_msg(); + if (DP_FAILED(ret)) { + DPS_LOG_ERR("Cannot send hardware capture stop message"); + return ret; + } + dp_graphtrace_set_hw_enabled(false); + DPS_LOG_INFO("Graphtrace disabled for software and offload paths"); + return DP_OK; + } else { + DPS_LOG_WARNING("Cannot stop hardware capture, offload is not enabled"); + return -EPERM; + } + } +} static __rte_always_inline void dp_handle_graphtrace_request(const struct rte_mp_msg *mp_msg, struct dp_graphtrace_mp_reply *reply) @@ -69,39 +131,13 @@ void dp_handle_graphtrace_request(const struct rte_mp_msg *mp_msg, struct dp_gra switch ((enum dp_graphtrace_action)request->action) { case DP_GRAPHTRACE_ACTION_START: - dp_graphtrace_enable(); - reply->error_code = DP_OK; - DPS_LOG_INFO("Graphtrace enabled"); + ret = dp_handle_graphtrace_start(request); + reply->error_code = ret; return; case DP_GRAPHTRACE_ACTION_STOP: - dp_graphtrace_disable(); - reply->error_code = DP_OK; - DPS_LOG_INFO("Graphtrace disabled"); - return; - case DP_GRAPHTRACE_ACTION_ENABLE_HW_CAPTURE: - if (offload_enabled) { - if (DP_FAILED(dp_send_event_hardware_capture_start_msg())) { - DPS_LOG_ERR("Cannot send hardware capture start message"); - dp_graphtrace_disable(); // roll back if failed on this side, and error code cannot be sent back - reply->error_code = DP_ERROR; - return; - } - } - reply->error_code = DP_OK; - DPS_LOG_INFO("Hardware capture enabled"); - return; - case DP_GRAPHTRACE_ACTION_DISABLE_HW_CAPTURE: - if (offload_enabled) { - if (DP_FAILED(dp_send_event_hardware_capture_stop_msg())) { - DPS_LOG_ERR("Cannot send hardware capture stop message"); - reply->error_code = DP_ERROR; - return; - } - } - reply->error_code = DP_OK; - DPS_LOG_INFO("Hardware capture disabled"); + ret = dp_handle_graphtrace_stop(request); + reply->error_code = ret; return; - case DP_GRAPHTRACE_ACTION_NULL: default: DPS_LOG_WARNING("Unknown graphtrace request action", DP_LOG_VALUE(request->action)); reply->error_code = -EINVAL; diff --git a/src/rte_flow/dp_rte_flow_init.c b/src/rte_flow/dp_rte_flow_init.c index 51b6e6b08..f3e5ccf67 100644 --- a/src/rte_flow/dp_rte_flow_init.c +++ b/src/rte_flow/dp_rte_flow_init.c @@ -170,10 +170,10 @@ int dp_install_default_capture_rule_in_vnet_group(uint16_t port_id) static int dp_change_all_vf_default_jump_rte_flow_group(uint32_t dst_group) { struct dp_ports *ports = get_dp_ports(); - struct dp_port *port; struct rte_flow_error error; int ret; + DP_FOREACH_PORT(ports, port) { if (port->port_type == DP_PORT_VF && port->allocated) { if (port->default_flow) diff --git a/tools/dp_graphtrace.c b/tools/dp_graphtrace.c index d2e8bb116..e9d15aec0 100644 --- a/tools/dp_graphtrace.c +++ b/tools/dp_graphtrace.c @@ -34,7 +34,7 @@ static const char *eal_arg_strings[] = { }; enum { - DP_GRAPHTRACE_OPT_NONE, + DP_GRAPHTRACE_OPT_MIN = 256, DP_GRAPHTRACE_OPT_HELP, DP_GRAPHTRACE_OPT_CAPTURE_HW_PKT, } cmd_opt_type; @@ -47,6 +47,7 @@ static bool capture_hw_pkt = false; static const struct option longopts[] = { { "help", 0, 0, DP_GRAPHTRACE_OPT_HELP }, { "hw-packet", 0, 0, DP_GRAPHTRACE_OPT_CAPTURE_HW_PKT }, + { NULL, 0, 0, 0 }, }; @@ -90,6 +91,15 @@ static int dp_graphtrace_connect(struct dp_graphtrace *graphtrace) return DP_OK; } +static void dp_graphtrace_config_start_stop_parameters(struct dp_graphtrace_mp_request *graphtrace_request) +{ + if (capture_hw_pkt) + graphtrace_request->action_params.op_type = DP_GRAPHTRACE_OP_TYPE_OFFLOAD; + else + graphtrace_request->action_params.op_type = DP_GRAPHTRACE_OP_TYPE_SOFTWARE; +} + + static int dp_graphtrace_send_request(enum dp_graphtrace_action action, struct dp_graphtrace_mp_reply *reply) { struct rte_mp_msg mp_request; @@ -104,6 +114,15 @@ static int dp_graphtrace_send_request(enum dp_graphtrace_action action, struct d graphtrace_request = (struct dp_graphtrace_mp_request *)mp_request.param; graphtrace_request->action = action; + switch (action) { + case DP_GRAPHTRACE_ACTION_START: + dp_graphtrace_config_start_stop_parameters(graphtrace_request); + break; + case DP_GRAPHTRACE_ACTION_STOP: + dp_graphtrace_config_start_stop_parameters(graphtrace_request); + break; + } + if (DP_FAILED(rte_mp_request_sync(&mp_request, &mp_reply, &connect_timeout))) { fprintf(stderr, "Cannot request graphtrace action %s\n", dp_strerror_verbose(rte_errno)); return -rte_errno; @@ -122,8 +141,6 @@ static void print_packet(struct rte_mbuf *pkt) char printbuf[512]; struct dp_graphtrace_pktinfo *pktinfo = dp_get_graphtrace_pktinfo(pkt); - dp_graphtrace_sprint(pkt, printbuf, sizeof(printbuf)); - switch (pktinfo->pkt_type) { case DP_GRAPHTRACE_PKT_TYPE_SOFTWARE: dp_graphtrace_sprint(pkt, printbuf, sizeof(printbuf)); @@ -135,16 +152,11 @@ static void print_packet(struct rte_mbuf *pkt) printbuf); break; case DP_GRAPHTRACE_PKT_TYPE_OFFLOAD: - printf("%u: captured offload packet : %s\n", + printf("%u: " NODENAME_FMT " " NODENAME_FMT ": %s\n", pktinfo->pktid, + "Offloaded", "", printbuf); break; - default: - printf("%u: " NODENAME_FMT ": unknown packet type %u\n", - pktinfo->pktid, - pktinfo->node->name, - pktinfo->pkt_type); - break; } } @@ -179,12 +191,12 @@ static int dp_graphtrace_request(enum dp_graphtrace_action action, struct dp_gra ret = dp_graphtrace_send_request(action, reply); if (DP_FAILED(ret)) { - fprintf(stderr, "Cannot send graphtrace request %s\n", dp_strerror_verbose(ret)); - return DP_ERROR; - } + fprintf(stderr, "Cannot send graphtrace action request %d %s\n", action, dp_strerror_verbose(ret)); + return ret; + } if (DP_FAILED(reply->error_code)) { - fprintf(stderr, "Graphtrace request failed %s\n", dp_strerror_verbose(reply->error_code)); + fprintf(stderr, "Graphtrace action request %d failed %s\n", action, dp_strerror_verbose(reply->error_code)); return DP_ERROR; } @@ -193,12 +205,12 @@ static int dp_graphtrace_request(enum dp_graphtrace_action action, struct dp_gra static int dp_graphtrace_start(void) { + int ret; struct dp_graphtrace_mp_reply reply; - if (DP_FAILED(dp_graphtrace_request(DP_GRAPHTRACE_ACTION_START, &reply))) { - fprintf(stderr, "Failed to request graph tracing\n"); - return DP_ERROR; - } + ret = dp_graphtrace_request(DP_GRAPHTRACE_ACTION_START, &reply); + if (DP_FAILED(ret)) + return ret; primary_alive = true; return DP_OK; @@ -212,36 +224,7 @@ static int dp_graphtrace_stop(void) if (!primary_alive) return DP_OK; - if (DP_FAILED(dp_graphtrace_request(DP_GRAPHTRACE_ACTION_STOP, &reply))) { - fprintf(stderr, "Failed to request graph tracing termination\n"); - return DP_ERROR; - } - - return DP_OK; -} - -static int dp_graphtrace_enable_hw_capture(void) -{ - struct dp_graphtrace_mp_reply reply; - - if (DP_FAILED(dp_graphtrace_request(DP_GRAPHTRACE_ACTION_ENABLE_HW_CAPTURE, &reply))) { - fprintf(stderr, "Failed to enable hardware packet capture\n"); - return DP_ERROR; - } - - return DP_OK; -} - -static int dp_graphtrace_disable_hw_capture(void) -{ - struct dp_graphtrace_mp_reply reply; - - if (DP_FAILED(dp_graphtrace_request(DP_GRAPHTRACE_ACTION_DISABLE_HW_CAPTURE, &reply))) { - fprintf(stderr, "Failed to disable hardware packet capture\n"); - return DP_ERROR; - } - - return DP_OK; + return dp_graphtrace_request(DP_GRAPHTRACE_ACTION_STOP, &reply); } static void dp_graphtrace_monitor_primary(void *arg __rte_unused) @@ -268,20 +251,6 @@ static void dp_graphtrace_monitor_primary(void *arg __rte_unused) fprintf(stderr, "Warning: Cannot re-schedule primary process monitor %s\n", dp_strerror_verbose(ret)); } -static int dp_graphtrace_init_hw_pkt_capture(struct dp_graphtrace *graphtrace) -{ - if (!capture_hw_pkt) - return DP_OK; - - if (DP_FAILED(dp_graphtrace_enable_hw_capture())) { - fprintf(stderr, "Failed to enable hardware packet capture\n"); - rte_eal_alarm_cancel(dp_graphtrace_monitor_primary, (void *)-1); - return DP_ERROR; - } - - return DP_OK; -} - static int do_graphtrace(struct dp_graphtrace *graphtrace) { int ret; @@ -303,24 +272,13 @@ static int do_graphtrace(struct dp_graphtrace *graphtrace) return DP_ERROR; } - if (DP_FAILED(dp_graphtrace_init_hw_pkt_capture(graphtrace))) { - if (dp_graphtrace_stop()) // rollback if failed - fprintf(stderr, "Failed to stop graph tracing after failing to init hw pkt capture\n"); - rte_eal_alarm_cancel(dp_graphtrace_monitor_primary, (void *)-1); - return DP_ERROR; - } - ret = dp_graphtrace_dump(graphtrace); - if (capture_hw_pkt) - if (DP_FAILED(dp_graphtrace_disable_hw_capture())) - ret = DP_ERROR; - if (DP_FAILED(dp_graphtrace_stop())) ret = DP_ERROR; rte_eal_alarm_cancel(dp_graphtrace_monitor_primary, (void *)-1); - + return ret; } @@ -332,7 +290,8 @@ static void signal_handler(__rte_unused int signum) static void dp_print_usage(const char *prgname) { fprintf(stderr, - " --help show this help message and exit\n" + "%s: dp-service graph-tracing utility\n" + " --help show this help message and exit\n" " --hw-packet capture pkts after offloading rules are installed (experimental feature, only VF's outgoing packets are supported)\n", prgname); }