DPDK patches and discussions
 help / color / mirror / Atom feed
From: "Hunt, David" <david.hunt@intel.com>
To: Radu Nicolau <radu.nicolau@intel.com>, dev@dpdk.org
Cc: liang.j.ma@intel.com
Subject: Re: [dpdk-dev] [PATCH v4 2/2] examples/l3fwd-power: simple app update to support new API
Date: Tue, 26 Jun 2018 14:03:41 +0100	[thread overview]
Message-ID: <1d61c2cc-6757-bc1a-ad87-1c0e44beb55b@intel.com> (raw)
In-Reply-To: <1530013217-22300-2-git-send-email-radu.nicolau@intel.com>



On 26/6/2018 12:40 PM, Radu Nicolau wrote:
> From: Liang Ma <liang.j.ma@intel.com>
>
> Add the support for new traffic pattern aware power control
> power management API.
>
> Example:
> ./l3fwd-power -l xxx   -n 4   -w 0000:xx:00.0 -w 0000:xx:00.1 -- -p 0x3
> -P --config="(0,0,xx),(1,0,xx)" --empty-poll
>
> Please Reference l3fwd-power document for all parameter except
> empty-poll.
>
> Once enable empty-poll. The system will start with training phase.
> There should not has any traffic pass-through during training phase.
> When training phase complete, system transfer to normal phase.
>
> System will running with modest power stat at beginning.
> If the system busyness percentage above 70%, then system will adjust
> power state move to High power state. If the traffic become lower(eg. The
> system busyness percentage drop below 30%), system will fallback
> to the modest power state.
>
> Example code use master thread to monitoring worker thread busyness.
> the default timer resolution is 10ms.
>
> ChangeLog:
> v2 fix some coding style issues
> v3 rename the API.
> v4 no change
>
> Signed-off-by: Liang Ma <liang.j.ma@intel.com>
> ---
>   examples/l3fwd-power/main.c | 232 ++++++++++++++++++++++++++++++++++++++++----
>   1 file changed, 214 insertions(+), 18 deletions(-)
>
> diff --git a/examples/l3fwd-power/main.c b/examples/l3fwd-power/main.c
> index 596d645..953a2ed 100644
> --- a/examples/l3fwd-power/main.c
> +++ b/examples/l3fwd-power/main.c
> @@ -42,6 +42,7 @@
>   #include <rte_string_fns.h>
>   #include <rte_timer.h>
>   #include <rte_power.h>
> +#include <rte_power_empty_poll.h>
>   #include <rte_spinlock.h>
>   
>   #define RTE_LOGTYPE_L3FWD_POWER RTE_LOGTYPE_USER1
> @@ -129,6 +130,9 @@ static uint32_t enabled_port_mask = 0;
>   static int promiscuous_on = 0;
>   /* NUMA is enabled by default. */
>   static int numa_on = 1;
> +/* emptypoll is disabled by default. */
> +static bool empty_poll_on;
> +volatile bool empty_poll_stop;
>   static int parse_ptype; /**< Parse packet type using rx callback, and */
>   			/**< disabled by default */
>   
> @@ -336,6 +340,10 @@ static inline uint32_t power_idle_heuristic(uint32_t zero_rx_packet_count);
>   static inline enum freq_scale_hint_t power_freq_scaleup_heuristic( \
>   		unsigned int lcore_id, uint16_t port_id, uint16_t queue_id);
>   
> +static int is_done(void)
> +{
> +	return empty_poll_stop;
> +}
>   /* exit signal handler */
>   static void
>   signal_exit_now(int sigtype)
> @@ -344,7 +352,15 @@ signal_exit_now(int sigtype)
>   	unsigned int portid;
>   	int ret;
>   
> +	RTE_SET_USED(lcore_id);
> +	RTE_SET_USED(portid);
> +	RTE_SET_USED(ret);
> +
>   	if (sigtype == SIGINT) {
> +		if (empty_poll_on)
> +			empty_poll_stop = true;
> +
> +
>   		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
>   			if (rte_lcore_is_enabled(lcore_id) == 0)
>   				continue;
> @@ -353,20 +369,23 @@ signal_exit_now(int sigtype)
>   			ret = rte_power_exit(lcore_id);
>   			if (ret)
>   				rte_exit(EXIT_FAILURE, "Power management "
> -					"library de-initialization failed on "
> -							"core%u\n", lcore_id);
> +						"library de-initialization failed on "
> +						"core%u\n", lcore_id);
>   		}
>   
> -		RTE_ETH_FOREACH_DEV(portid) {
> -			if ((enabled_port_mask & (1 << portid)) == 0)
> -				continue;
> +		if (!empty_poll_on) {
> +			RTE_ETH_FOREACH_DEV(portid) {
> +				if ((enabled_port_mask & (1 << portid)) == 0)
> +					continue;
>   
> -			rte_eth_dev_stop(portid);
> -			rte_eth_dev_close(portid);
> +				rte_eth_dev_stop(portid);
> +				rte_eth_dev_close(portid);
> +			}
>   		}
>   	}
>   
> -	rte_exit(EXIT_SUCCESS, "User forced exit\n");
> +	if (!empty_poll_on)
> +		rte_exit(EXIT_SUCCESS, "User forced exit\n");
>   }
>   
>   /*  Freqency scale down timer callback */
> @@ -831,6 +850,107 @@ static int event_register(struct lcore_conf *qconf)
>   
>   	return 0;
>   }
> +/* main processing loop */
> +static int
> +main_empty_poll_loop(__attribute__((unused)) void *dummy)
> +{
> +	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
> +	unsigned int lcore_id;
> +	uint64_t prev_tsc, diff_tsc, cur_tsc;
> +	int i, j, nb_rx;
> +	uint8_t queueid;
> +	uint16_t portid;
> +	struct lcore_conf *qconf;
> +	struct lcore_rx_queue *rx_queue;
> +
> +	const uint64_t drain_tsc =
> +		(rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
> +
> +	prev_tsc = 0;
> +
> +	lcore_id = rte_lcore_id();
> +	qconf = &lcore_conf[lcore_id];
> +
> +	if (qconf->n_rx_queue == 0) {
> +		RTE_LOG(INFO, L3FWD_POWER, "lcore %u has nothing to do\n", lcore_id);
> +		return 0;
> +	}
> +
> +	for (i = 0; i < qconf->n_rx_queue; i++) {
> +		portid = qconf->rx_queue_list[i].port_id;
> +		queueid = qconf->rx_queue_list[i].queue_id;
> +		RTE_LOG(INFO, L3FWD_POWER, " -- lcoreid=%u portid=%u "
> +				"rxqueueid=%hhu\n", lcore_id, portid, queueid);
> +	}
> +
> +	while (!is_done()) {
> +		stats[lcore_id].nb_iteration_looped++;
> +
> +		cur_tsc = rte_rdtsc();
> +		/*
> +		 * TX burst queue drain
> +		 */
> +		diff_tsc = cur_tsc - prev_tsc;
> +		if (unlikely(diff_tsc > drain_tsc)) {
> +			for (i = 0; i < qconf->n_tx_port; ++i) {
> +				portid = qconf->tx_port_id[i];
> +				rte_eth_tx_buffer_flush(portid,
> +						qconf->tx_queue_id[portid],
> +						qconf->tx_buffer[portid]);
> +			}
> +			prev_tsc = cur_tsc;
> +		}
> +
> +		/*
> +		 * Read packet from RX queues
> +		 */
> +		for (i = 0; i < qconf->n_rx_queue; ++i) {
> +			rx_queue = &(qconf->rx_queue_list[i]);
> +			rx_queue->idle_hint = 0;
> +			portid = rx_queue->port_id;
> +			queueid = rx_queue->queue_id;
> +
> +			nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
> +					MAX_PKT_BURST);
> +
> +			stats[lcore_id].nb_rx_processed += nb_rx;
> +
> +			if (nb_rx == 0) {
> +
> +				rte_power_empty_poll_stat_update(lcore_id);
> +
> +				continue;
> +			} else {
> +				rte_power_poll_stat_update(lcore_id, nb_rx);
> +			}
> +
> +
> +			/* Prefetch first packets */
> +			for (j = 0; j < PREFETCH_OFFSET && j < nb_rx; j++) {
> +				rte_prefetch0(rte_pktmbuf_mtod(
> +							pkts_burst[j], void *));
> +			}
> +
> +			/* Prefetch and forward already prefetched packets */
> +			for (j = 0; j < (nb_rx - PREFETCH_OFFSET); j++) {
> +				rte_prefetch0(rte_pktmbuf_mtod(pkts_burst[
> +							j + PREFETCH_OFFSET], void *));
> +				l3fwd_simple_forward(pkts_burst[j], portid,
> +						qconf);
> +			}
> +
> +			/* Forward remaining prefetched packets */
> +			for (; j < nb_rx; j++) {
> +				l3fwd_simple_forward(pkts_burst[j], portid,
> +						qconf);
> +			}
> +
> +		}
> +
> +	}
> +
> +	return 0;
> +}
>   
>   /* main processing loop */
>   static int
> @@ -1128,7 +1248,8 @@ print_usage(const char *prgname)
>   		"  --no-numa: optional, disable numa awareness\n"
>   		"  --enable-jumbo: enable jumbo frame"
>   		" which max packet len is PKTLEN in decimal (64-9600)\n"
> -		"  --parse-ptype: parse packet type by software\n",
> +		"  --parse-ptype: parse packet type by software\n"
> +		"  --empty=poll: enable empty poll detection\n",
>   		prgname);
>   }
>   
> @@ -1231,10 +1352,12 @@ parse_args(int argc, char **argv)
>   	int opt, ret;
>   	char **argvopt;
>   	int option_index;
> +	uint32_t limit;
>   	char *prgname = argv[0];
>   	static struct option lgopts[] = {
>   		{"config", 1, 0, 0},
>   		{"no-numa", 0, 0, 0},
> +		{"empty-poll", 0, 0, 0},
>   		{"enable-jumbo", 0, 0, 0},
>   		{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, 0},
>   		{NULL, 0, 0, 0}
> @@ -1259,7 +1382,18 @@ parse_args(int argc, char **argv)
>   			printf("Promiscuous mode selected\n");
>   			promiscuous_on = 1;
>   			break;
> -
> +		case 'l':
> +			limit = parse_portmask(optarg);
> +			rte_power_empty_poll_set_freq(LOW, limit);
> +			break;
> +		case 'm':
> +			limit = parse_portmask(optarg);
> +			rte_power_empty_poll_set_freq(MED, limit);
> +			break;
> +		case 'h':
> +			limit = parse_portmask(optarg);
> +			rte_power_empty_poll_set_freq(HGH, limit);
> +			break;
>   		/* long options */
>   		case 0:
>   			if (!strncmp(lgopts[option_index].name, "config", 6)) {
> @@ -1278,6 +1412,12 @@ parse_args(int argc, char **argv)
>   			}
>   
>   			if (!strncmp(lgopts[option_index].name,
> +						"empty-poll", 10)) {
> +				printf("empty-poll is enabled\n");
> +				empty_poll_on = true;
> +			}
> +
> +			if (!strncmp(lgopts[option_index].name,
>   					"enable-jumbo", 12)) {
>   				struct option lenopts =
>   					{"max-pkt-len", required_argument, \
> @@ -1609,6 +1749,41 @@ static int check_ptype(uint16_t portid)
>   
>   }
>   
> +static int
> +launch_timer(unsigned int lcore_id)
> +{
> +	int64_t prev_tsc = 0, cur_tsc, diff_tsc, cycles_10ms;
> +
> +	RTE_SET_USED(lcore_id);
> +
> +
> +	if (rte_get_master_lcore() != lcore_id) {
> +		rte_panic("timer on lcore:%d which is not master core:%d\n",
> +				lcore_id,
> +				rte_get_master_lcore());
> +	}
> +
> +	RTE_LOG(INFO, POWER, "Bring up the Timer\n");
> +
> +	rte_power_empty_poll_setup_timer();
> +
> +	cycles_10ms = rte_get_timer_hz() / 100;
> +
> +	while (!is_done()) {
> +		cur_tsc = rte_rdtsc();
> +		diff_tsc = cur_tsc - prev_tsc;
> +		if (diff_tsc > cycles_10ms) {
> +			rte_timer_manage();
> +			prev_tsc = cur_tsc;
> +			cycles_10ms = rte_get_timer_hz() / 100;
> +		}
> +	}
> +
> +	RTE_LOG(INFO, POWER, "Timer_subsystem is done\n");
> +
> +	return 0;
> +}
> +
>   int
>   main(int argc, char **argv)
>   {
> @@ -1693,6 +1868,10 @@ main(int argc, char **argv)
>   		if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
>   			local_port_conf.txmode.offloads |=
>   				DEV_TX_OFFLOAD_MBUF_FAST_FREE;
> +
> +		local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
> +			dev_info.flow_type_rss_offloads;
> +
>   		ret = rte_eth_dev_configure(portid, nb_rx_queue,
>   					(uint16_t)n_tx_queue, &local_port_conf);
>   		if (ret < 0)
> @@ -1780,14 +1959,15 @@ main(int argc, char **argv)
>   				"Library initialization failed on core %u\n", lcore_id);
>   
>   		/* init timer structures for each enabled lcore */
> -		rte_timer_init(&power_timers[lcore_id]);
> -		hz = rte_get_timer_hz();
> -		rte_timer_reset(&power_timers[lcore_id],
> -			hz/TIMER_NUMBER_PER_SECOND, SINGLE, lcore_id,
> -						power_timer_cb, NULL);
> -
> +		if (empty_poll_on == false) {
> +			rte_timer_init(&power_timers[lcore_id]);
> +			hz = rte_get_timer_hz();
> +			rte_timer_reset(&power_timers[lcore_id],
> +					hz/TIMER_NUMBER_PER_SECOND, SINGLE, lcore_id,
> +					power_timer_cb, NULL);
> +		}
>   		qconf = &lcore_conf[lcore_id];
> -		printf("\nInitializing rx queues on lcore %u ... ", lcore_id );
> +		printf("\nInitializing rx queues on lcore %u ...\n", lcore_id);
>   		fflush(stdout);
>   		/* init RX queues */
>   		for(queue = 0; queue < qconf->n_rx_queue; ++queue) {
> @@ -1856,12 +2036,28 @@ main(int argc, char **argv)
>   
>   	check_all_ports_link_status(enabled_port_mask);
>   
> +	if (empty_poll_on == true)
> +		rte_power_empty_poll_stat_init();
> +
> +
>   	/* launch per-lcore init on every lcore */
> -	rte_eal_mp_remote_launch(main_loop, NULL, CALL_MASTER);
> +	if (empty_poll_on == false) {
> +		rte_eal_mp_remote_launch(main_loop, NULL, CALL_MASTER);
> +	} else {
> +		empty_poll_stop = false;
> +		rte_eal_mp_remote_launch(main_empty_poll_loop, NULL, SKIP_MASTER);
> +	}
> +
> +	if (empty_poll_on == true)
> +		launch_timer(rte_lcore_id());
> +
>   	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
>   		if (rte_eal_wait_lcore(lcore_id) < 0)
>   			return -1;
>   	}
>   
> +	if (empty_poll_on)
> +		rte_power_empty_poll_stat_free();
> +
>   	return 0;
>   }

Acked-by: David Hunt<david.hunt@intel.com>

  reply	other threads:[~2018-06-26 13:02 UTC|newest]

Thread overview: 79+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-06-08  9:57 [dpdk-dev] [PATCH v1 1/2] lib/librte_power: traffic pattern aware power control Liang Ma
2018-06-08  9:57 ` [dpdk-dev] [PATCH v1 2/2] examples/l3fwd-power: simple app update to support new API Liang Ma
2018-06-19 10:31   ` Hunt, David
2018-06-08 15:26 ` [dpdk-dev] [PATCH v2 1/2] lib/librte_power: traffic pattern aware power control Liang Ma
2018-06-08 15:26   ` [dpdk-dev] [PATCH v2 2/2] examples/l3fwd-power: simple app update to support new API Liang Ma
2018-06-20 14:44     ` [dpdk-dev] [PATCH v3 1/2] lib/librte_power: traffic pattern aware power control Liang Ma
2018-06-20 14:44       ` [dpdk-dev] [PATCH v3 2/2] examples/l3fwd-power: simple app update to support new API Liang Ma
2018-06-26 11:40         ` [dpdk-dev] [PATCH v4 1/2] lib/librte_power: traffic pattern aware power control Radu Nicolau
2018-06-26 11:40           ` [dpdk-dev] [PATCH v4 2/2] examples/l3fwd-power: simple app update to support new API Radu Nicolau
2018-06-26 13:03             ` Hunt, David [this message]
2018-06-26 13:03           ` [dpdk-dev] [PATCH v4 1/2] lib/librte_power: traffic pattern aware power control Hunt, David
2018-06-27 17:33           ` Kevin Traynor
2018-07-05 14:45             ` Liang, Ma
2018-07-12 17:30               ` Thomas Monjalon
2018-09-11  9:19             ` Hunt, David
2018-09-13  9:46               ` Kevin Traynor
2018-09-13 13:30                 ` Liang, Ma
2018-07-10 16:04           ` [dpdk-dev] [PATCH v5 " Radu Nicolau
2018-07-10 16:04             ` [dpdk-dev] [PATCH v5 2/2] examples/l3fwd-power: simple app update to support new API Radu Nicolau
2018-08-31 15:04             ` [dpdk-dev] [PATCH v6 1/4] lib/librte_power: traffic pattern aware power control Liang Ma
2018-08-31 15:04               ` [dpdk-dev] [PATCH v6 2/4] examples/l3fwd-power: simple app update for new API Liang Ma
2018-08-31 15:04               ` [dpdk-dev] [PATCH v6 3/4] doc/guides/proguides/power-man: update the power API Liang Ma
2018-08-31 15:04               ` [dpdk-dev] [PATCH v6 4/4] doc/guides/sample_app_ug/l3_forward_power_man.rst: empty poll update Liang Ma
2018-09-04  1:11               ` [dpdk-dev] [PATCH v6 1/4] lib/librte_power: traffic pattern aware power control Yao, Lei A
2018-09-04  2:09               ` Yao, Lei A
2018-09-04 14:10               ` [dpdk-dev] [PATCH v7 " Liang Ma
2018-09-04 14:10                 ` [dpdk-dev] [PATCH v7 2/4] examples/l3fwd-power: simple app update for new API Liang Ma
2018-09-04 14:10                 ` [dpdk-dev] [PATCH v7 3/4] doc/guides/proguides/power-man: update the power API Liang Ma
2018-09-04 14:10                 ` [dpdk-dev] [PATCH v7 4/4] doc/guides/sample_app_ug/l3_forward_power_man.rst: empty poll update Liang Ma
2018-09-13 10:54                 ` [dpdk-dev] [PATCH v7 1/4] lib/librte_power: traffic pattern aware power control Kevin Traynor
2018-09-13 13:37                   ` Liang, Ma
2018-09-13 14:05                     ` Hunt, David
2018-09-17 13:30                 ` [dpdk-dev] [PATCH v8 " Liang Ma
2018-09-17 13:30                   ` [dpdk-dev] [PATCH v8 2/4] examples/l3fwd-power: simple app update for new API Liang Ma
2018-09-28 11:19                     ` Hunt, David
2018-10-02 10:18                       ` Liang, Ma
2018-09-17 13:30                   ` [dpdk-dev] [PATCH v8 3/4] doc/guides/proguide/power-man: update the power API Liang Ma
2018-09-25 12:31                     ` Kovacevic, Marko
2018-09-25 12:44                     ` Kovacevic, Marko
2018-09-28 12:30                     ` Hunt, David
2018-09-17 13:30                   ` [dpdk-dev] [PATCH v8 4/4] doc/guides/sample_app_ug/l3_forward_power_man.rst: empty poll update Liang Ma
2018-09-25 13:20                     ` Kovacevic, Marko
2018-09-28 12:43                       ` Hunt, David
2018-09-28 12:52                         ` Liang, Ma
2018-09-28 10:47                   ` [dpdk-dev] [PATCH v8 1/4] lib/librte_power: traffic pattern aware power control Hunt, David
2018-10-02 10:13                     ` Liang, Ma
2018-09-28 14:58                   ` [dpdk-dev] [PATCH v9 " Liang Ma
2018-09-28 14:58                     ` [dpdk-dev] [PATCH v9 2/4] examples/l3fwd-power: simple app update for new API Liang Ma
2018-09-28 14:58                     ` [dpdk-dev] [PATCH v9 3/4] doc/guides/pro_guide/power-man: update the power API Liang Ma
2018-10-02 13:48                     ` [dpdk-dev] [PATCH v10 1/4] lib/librte_power: traffic pattern aware power control Liang Ma
2018-10-02 13:48                       ` [dpdk-dev] [PATCH v10 2/4] examples/l3fwd-power: simple app update for new API Liang Ma
2018-10-02 14:23                         ` Hunt, David
2018-10-02 13:48                       ` [dpdk-dev] [PATCH v10 3/4] doc/guides/pro_guide/power-man: update the power API Liang Ma
2018-10-02 14:24                         ` Hunt, David
2018-10-02 13:48                       ` [dpdk-dev] [PATCH v10 4/4] doc/guides/sample_app_ug/l3_forward_power_man.rst: update Liang Ma
2018-10-02 14:25                         ` Hunt, David
2018-10-02 14:22                       ` [dpdk-dev] [PATCH v10 1/4] lib/librte_power: traffic pattern aware power control Hunt, David
2018-10-12  1:59                       ` Yao, Lei A
2018-10-12 10:02                         ` Liang, Ma
2018-10-12 13:22                           ` Yao, Lei A
2018-10-19 10:23                       ` [dpdk-dev] [PATCH v11 1/5] " Liang Ma
2018-10-19 10:23                         ` [dpdk-dev] [PATCH v11 2/5] examples/l3fwd-power: simple app update for new API Liang Ma
2018-10-19 10:23                         ` [dpdk-dev] [PATCH v11 3/5] doc/guides/pro_guide/power-man: update the power API Liang Ma
2018-10-19 10:23                         ` [dpdk-dev] [PATCH v11 5/5] doc: update release notes for empty poll library Liang Ma
2018-10-19 11:07                         ` [dpdk-dev] [PATCH v12 1/5] lib/librte_power: traffic pattern aware power control Liang Ma
2018-10-19 11:07                           ` [dpdk-dev] [PATCH v12 2/5] examples/l3fwd-power: simple app update for new API Liang Ma
2018-10-19 11:07                           ` [dpdk-dev] [PATCH v12 3/5] doc/guides/pro_guide/power-man: update the power API Liang Ma
2018-10-19 11:07                           ` [dpdk-dev] [PATCH v12 4/5] doc/guides/sample_app_ug/l3_forward_power_man.rst: update Liang Ma
2018-10-19 11:07                           ` [dpdk-dev] [PATCH v12 5/5] doc: update release notes for empty poll library Liang Ma
2018-10-22 12:41                             ` Kovacevic, Marko
2018-10-25 23:39                             ` Thomas Monjalon
2018-10-25 23:22                           ` [dpdk-dev] [PATCH v12 1/5] lib/librte_power: traffic pattern aware power control Thomas Monjalon
2018-10-25 23:32                             ` Thomas Monjalon
2018-10-25 23:54                           ` Thomas Monjalon
2018-10-25 23:55                           ` Thomas Monjalon
2018-10-26 13:34                             ` Liang, Ma
2018-10-01 10:06                   ` [dpdk-dev] [PATCH v9 4/4] doc/guides/sample_app_ug/l3_forward_power_man.rst: empty poll update Liang Ma
2018-06-14 10:59 ` [dpdk-dev] [PATCH v1 1/2] lib/librte_power: traffic pattern aware power control Hunt, David
2018-06-18 16:11   ` Liang, Ma

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1d61c2cc-6757-bc1a-ad87-1c0e44beb55b@intel.com \
    --to=david.hunt@intel.com \
    --cc=dev@dpdk.org \
    --cc=liang.j.ma@intel.com \
    --cc=radu.nicolau@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).