From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by dpdk.org (Postfix) with ESMTP id 2A2998D99 for ; Wed, 30 Sep 2015 11:05:02 +0200 (CEST) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by orsmga103.jf.intel.com with ESMTP; 30 Sep 2015 02:04:44 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.17,611,1437462000"; d="scan'208";a="816043129" Received: from rhorton-mobl.ger.corp.intel.com (HELO localhost.ir.intel.com) ([163.33.229.80]) by fmsmga002.fm.intel.com with ESMTP; 30 Sep 2015 02:04:44 -0700 From: Remy Horton To: dev@dpdk.org Date: Wed, 30 Sep 2015 10:04:40 +0100 Message-Id: <1443603881-4700-3-git-send-email-remy.horton@intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: <1443603881-4700-1-git-send-email-remy.horton@intel.com> References: <1443603881-4700-1-git-send-email-remy.horton@intel.com> Subject: [dpdk-dev] [PATCH v2 2/3] l2fwd: keep alive sample application X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Sep 2015 09:05:02 -0000 Modification of l2fwd to demonstrate keep-alive functionality. Signed-off-by: Remy Horton --- examples/l2fwd/Makefile | 2 +- examples/l2fwd/main.c | 125 ++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 118 insertions(+), 9 deletions(-) diff --git a/examples/l2fwd/Makefile b/examples/l2fwd/Makefile index 78feeeb..8647174 100644 --- a/examples/l2fwd/Makefile +++ b/examples/l2fwd/Makefile @@ -39,7 +39,7 @@ RTE_TARGET ?= x86_64-native-linuxapp-gcc include $(RTE_SDK)/mk/rte.vars.mk # binary name -APP = l2fwd +APP = l2fwd-keepalive # all source are stored in SRCS-y SRCS-y := main.c diff --git a/examples/l2fwd/main.c b/examples/l2fwd/main.c index 720fd5a..131e5a2 100644 --- a/examples/l2fwd/main.c +++ b/examples/l2fwd/main.c @@ -1,7 +1,7 @@ /*- * BSD LICENSE * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2010-2015 Intel Corporation. All rights reserved. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -68,6 +68,8 @@ #include #include #include +#include +#include #define RTE_LOGTYPE_L2FWD RTE_LOGTYPE_USER1 @@ -135,13 +137,18 @@ struct l2fwd_port_statistics { struct l2fwd_port_statistics port_statistics[RTE_MAX_ETHPORTS]; /* A tsc-based timer responsible for triggering statistics printout */ -#define TIMER_MILLISECOND 2000000ULL /* around 1ms at 2 Ghz */ +#define TIMER_MILLISECOND 1 #define MAX_TIMER_PERIOD 86400 /* 1 day max */ static int64_t timer_period = 10 * TIMER_MILLISECOND * 1000; /* default period is 10 seconds */ +static int64_t check_period = 5; /* default check cycle is 5ms */ + +/* Keepalive structure */ +struct rte_keepalive * rte_global_keepalive_info; /* Print out statistics on packets dropped */ static void -print_stats(void) +print_stats(__attribute__((unused)) struct rte_timer *ptr_timer, + __attribute__((unused)) void *ptr_data) { uint64_t total_packets_dropped, total_packets_tx, total_packets_rx; unsigned portid; @@ -283,11 +290,23 @@ l2fwd_main_loop(void) portid); } + uint64_t tsc_initial = rte_rdtsc(); + uint64_t tsc_lifetime = (rand()&0x07) * rte_get_tsc_hz(); + while (1) { + /* Keepalive heartbeat */ + rte_keepalive_mark_alive(rte_global_keepalive_info); cur_tsc = rte_rdtsc(); /* + * Die randomly within 7 secs for demo purposes if + * keepalive enables + */ + if (check_period > 0 && cur_tsc - tsc_initial > tsc_lifetime) + break; + + /* * TX burst queue drain */ diff_tsc = cur_tsc - prev_tsc; @@ -313,7 +332,7 @@ l2fwd_main_loop(void) /* do this only on master core */ if (lcore_id == rte_get_master_lcore()) { - print_stats(); + print_stats(NULL, NULL); /* reset the timer */ timer_tsc = 0; } @@ -357,6 +376,7 @@ l2fwd_usage(const char *prgname) printf("%s [EAL options] -- -p PORTMASK [-q NQ]\n" " -p PORTMASK: hexadecimal bitmask of ports to configure\n" " -q NQ: number of queue (=ports) per lcore (default is 1)\n" + " -K PERIOD: Keepalive check period (5 default; 86400 max)\n" " -T PERIOD: statistics will be refreshed each PERIOD seconds (0 to disable, 10 default, 86400 maximum)\n", prgname); } @@ -412,6 +432,22 @@ l2fwd_parse_timer_period(const char *q_arg) return n; } +static int +l2fwd_parse_check_period(const char *q_arg) +{ + char *end = NULL; + int n; + + /* parse number string */ + n = strtol(q_arg, &end, 10); + if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0')) + return -1; + if (n >= MAX_TIMER_PERIOD) + return -1; + + return n; +} + /* Parse the argument given in the command line of the application */ static int l2fwd_parse_args(int argc, char **argv) @@ -426,7 +462,7 @@ l2fwd_parse_args(int argc, char **argv) argvopt = argv; - while ((opt = getopt_long(argc, argvopt, "p:q:T:", + while ((opt = getopt_long(argc, argvopt, "p:q:T:K:", lgopts, &option_index)) != EOF) { switch (opt) { @@ -460,6 +496,16 @@ l2fwd_parse_args(int argc, char **argv) } break; + /* Check period */ + case 'K': + check_period = l2fwd_parse_check_period(optarg); + if (check_period < 0) { + printf("invalid check period\n"); + l2fwd_usage(prgname); + return -1; + } + break; + /* long options */ case 0: l2fwd_usage(prgname); @@ -534,6 +580,18 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask) } } +static void +dead_core(__attribute__((unused)) void *ptr_data, const int id_core) +{ + printf("Dead core %i - restarting..\n", id_core); + if (rte_eal_get_lcore_state(id_core) == FINISHED) { + rte_eal_wait_lcore(id_core); + rte_eal_remote_launch(l2fwd_launch_one_lcore, NULL, id_core); + } else { + printf("..false positive!\n"); + } +} + int main(int argc, char **argv) { @@ -600,7 +658,7 @@ main(int argc, char **argv) l2fwd_dst_ports[last_port] = last_port; } - rx_lcore_id = 0; + rx_lcore_id = 1; qconf = NULL; /* Initialize the port/queue configuration of each logical core */ @@ -696,8 +754,59 @@ main(int argc, char **argv) check_all_ports_link_status(nb_ports, l2fwd_enabled_port_mask); - /* launch per-lcore init on every lcore */ - rte_eal_mp_remote_launch(l2fwd_launch_one_lcore, NULL, CALL_MASTER); + struct rte_timer hb_timer, stats_timer; + + rte_timer_subsystem_init(); + rte_timer_init(&stats_timer); + + if (check_period > 0) { + rte_global_keepalive_info = rte_keepalive_create(&dead_core, NULL); + if( rte_global_keepalive_info == NULL) + rte_exit(EXIT_FAILURE, "init_keep_alive() failed"); + rte_timer_init(&hb_timer); + if (rte_timer_reset(&hb_timer, + (check_period * rte_get_timer_hz()) / 1000, + PERIODICAL, + rte_lcore_id(), + (void(*)(struct rte_timer*, void*)) + &rte_keepalive_dispatch_pings, + rte_global_keepalive_info + ) != 0 ) + rte_exit(EXIT_FAILURE, "Keepalive setup failure.\n"); + } + if (timer_period > 0) { + if (rte_timer_reset(&stats_timer, + (timer_period * rte_get_timer_hz()) / 1000, + PERIODICAL, + rte_lcore_id(), + &print_stats, NULL + ) != 0 ) + rte_exit(EXIT_FAILURE, "Stats setup failure.\n"); + } + /* launch per-lcore init on every slave lcore */ + RTE_LCORE_FOREACH_SLAVE(lcore_id) { + struct lcore_queue_conf *qconf = &lcore_queue_conf[lcore_id]; + + if (qconf->n_rx_port == 0) + RTE_LOG(INFO, L2FWD, + "lcore %u has nothing to do\n", + lcore_id + ); + else { + rte_eal_remote_launch( + l2fwd_launch_one_lcore, + NULL, + lcore_id + ); + rte_keepalive_register_core(rte_global_keepalive_info, + lcore_id); + } + } + for (;;) { + rte_timer_manage(); + rte_delay_ms(5); + } + RTE_LCORE_FOREACH_SLAVE(lcore_id) { if (rte_eal_wait_lcore(lcore_id) < 0) return -1; -- 1.9.3