All of lore.kernel.org
 help / color / mirror / Atom feed
From: David Hunt <david.hunt@intel.com>
To: dev@dpdk.org
Cc: David Hunt <david.hunt@intel.com>,
	Nemanja Marjanovic <nemanja.marjanovic@intel.com>,
	Rory Sexton <rory.sexton@intel.com>
Subject: [PATCH v1 06/10] examples/vm_power_mgr: add policy to channels
Date: Fri, 25 Aug 2017 17:02:17 +0100	[thread overview]
Message-ID: <1503676941-80981-7-git-send-email-david.hunt@intel.com> (raw)
In-Reply-To: <1503676941-80981-1-git-send-email-david.hunt@intel.com>

Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
Signed-off-by: Rory Sexton <rory.sexton@intel.com>
Signed-off-by: David Hunt <david.hunt@intel.com>
---
 examples/vm_power_manager/channel_monitor.c | 302 +++++++++++++++++++++++++++-
 examples/vm_power_manager/channel_monitor.h |  18 ++
 2 files changed, 312 insertions(+), 8 deletions(-)

diff --git a/examples/vm_power_manager/channel_monitor.c b/examples/vm_power_manager/channel_monitor.c
index e7f5cc4..94fa03c 100644
--- a/examples/vm_power_manager/channel_monitor.c
+++ b/examples/vm_power_manager/channel_monitor.c
@@ -41,13 +41,16 @@
 #include <sys/types.h>
 #include <sys/epoll.h>
 #include <sys/queue.h>
+#include <sys/time.h>
 
 #include <rte_log.h>
 #include <rte_memory.h>
 #include <rte_malloc.h>
 #include <rte_atomic.h>
+#include <rte_cycles.h>
+#include <rte_ethdev.h>
 
-
+#include <libvirt/libvirt.h>
 #include "channel_monitor.h"
 #include "channel_commands.h"
 #include "channel_manager.h"
@@ -57,10 +60,15 @@
 
 #define MAX_EVENTS 256
 
-
+uint64_t vsi_pkt_count_prev[384];
+uint64_t rdtsc_prev[384];
+double time_period_s = 1;
+double cpu_tsc_hz = 2200000000;
 static volatile unsigned run_loop = 1;
 static int global_event_fd;
+static unsigned int policy_is_set;
 static struct epoll_event *global_events_list;
+static struct policy policies[MAX_VMS];
 
 void channel_monitor_exit(void)
 {
@@ -68,6 +76,266 @@ void channel_monitor_exit(void)
 	rte_free(global_events_list);
 }
 
+static void
+core_share(int pNo, int z, int x, int t)
+{
+	if (policies[pNo].core_share[z].pcpu == lvm_info[x].pcpus[t]) {
+		if (strcmp(policies[pNo].pkt.vm_name,
+				lvm_info[x].vm_name) != 0) {
+			policies[pNo].core_share[z].status = 1;
+			power_manager_scale_core_max(
+					policies[pNo].core_share[z].pcpu);
+		}
+	}
+}
+
+static void
+core_share_status(int pNo) {
+
+	int noVms, noVcpus, z, x, t;
+
+	get_all_vm(&noVms, &noVcpus);
+
+	/* Reset Core Share Status. */
+	for (z = 0; z < noVcpus; z++)
+		policies[pNo].core_share[z].status = 0;
+
+	/* Foreach vcpu in a policy. */
+	for (z = 0; z < noVcpus; z++) {
+		/* Foreach VM on the platform. */
+		for (x = 0; x < noVms; x++) {
+			/* Foreach vcpu of VMs on platform. */
+			for (t = 0; t < noVcpus; t++)
+				core_share(pNo, z, x, t);
+		}
+	}
+}
+
+static void
+get_pcpu_to_control(struct policy *pol) {
+
+	/* Convert vcpu to pcpu. */
+	struct vm_info info;
+	int pcpu, count;
+	uint64_t mask_u64b;
+
+	printf("Looking for pcpu for %s\n", pol->pkt.vm_name);
+	get_info_vm(pol->pkt.vm_name, &info);
+
+	for (count = 0; count < 2; count++) {
+		mask_u64b = info.pcpu_mask[pol->pkt.vcpu_to_control[count]];
+		for (pcpu = 0; mask_u64b; mask_u64b &= ~(1ULL << pcpu++)) {
+			if ((mask_u64b >> pcpu) & 1)
+				pol->core_share[count].pcpu = pcpu;
+		}
+	}
+}
+
+static int
+get_pfid(struct policy *pol) {
+
+	int i, x, ret = 0, nb_ports;
+
+	nb_ports = rte_eth_dev_count();
+	for (i = 0; i < pol->pkt.nb_mac_to_monitor; i++) {
+
+		for (x = 0; x < nb_ports; x++) {
+			ret = vfid_to_pfid_direct(x, pol->pkt.vfid[i]);
+			if (ret != -1) {
+				pol->port[i] = x;
+				break;
+			}
+		}
+		if (ret == -1) {
+			RTE_LOG(ERR, CHANNEL_MONITOR,
+				"Error with Policy. MAC not found on "
+				"attached ports ");
+			pol->enabled = 0;
+			return ret;
+		}
+		pol->pfid[i] = ret;
+	}
+	return 1;
+}
+
+static int
+update_policy(struct channel_packet *pkt) {
+
+	unsigned int updated = 0;
+
+	for (int i = 0; i < MAX_VMS; i++) {
+		if (strcmp(policies[i].pkt.vm_name, pkt->vm_name) == 0) {
+			policies[i].pkt = *pkt;
+			get_pcpu_to_control(&policies[i]);
+			if (get_pfid(&policies[i]) == -1) {
+				updated = 1;
+				break;
+			}
+			core_share_status(i);
+			policies[i].enabled = 1;
+			updated = 1;
+		}
+	}
+	if (!updated) {
+		for (int i = 0; i < MAX_VMS; i++) {
+			if (policies[i].enabled == 0) {
+				policies[i].pkt = *pkt;
+				get_pcpu_to_control(&policies[i]);
+				if (get_pfid(&policies[i]) == -1)
+					break;
+				core_share_status(i);
+				policies[i].enabled = 1;
+				break;
+			}
+		}
+	}
+	return 0;
+}
+
+static uint64_t
+get_pkt_diff(struct policy *pol) {
+
+	uint64_t vsi_pkt_count,
+		vsi_pkt_total = 0,
+		vsi_pkt_count_prev_total = 0;
+	double rdtsc_curr, rdtsc_diff, diff;
+	int x;
+
+	for (x = 0; x < pol->pkt.nb_mac_to_monitor; x++) {
+
+		/*Read vsi stats*/
+		vsi_pkt_count = read_pf_stats_direct(x, pol->pfid[x]);
+		vsi_pkt_total += vsi_pkt_count;
+
+		vsi_pkt_count_prev_total += vsi_pkt_count_prev[pol->pfid[x]];
+		vsi_pkt_count_prev[pol->pfid[x]] = vsi_pkt_count;
+	}
+
+	rdtsc_curr = rte_rdtsc_precise();
+	rdtsc_diff = rdtsc_curr - rdtsc_prev[pol->pfid[x-1]];
+	rdtsc_prev[pol->pfid[x-1]] = rdtsc_curr;
+
+	diff = (vsi_pkt_total - vsi_pkt_count_prev_total) *
+			(cpu_tsc_hz / rdtsc_diff);
+
+	return diff;
+}
+
+static void
+apply_traffic_profile(struct policy *pol) {
+
+	int count;
+	uint64_t diff = 0;
+
+	diff = get_pkt_diff(pol);
+
+	printf("Applying traffic profile\n");
+
+	if (diff >= (pol->pkt.traffic_policy.max_max_packet_thresh)) {
+		for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				power_manager_scale_core_max(
+						pol->core_share[count].pcpu);
+		}
+	} else if (diff >= (pol->pkt.traffic_policy.avg_max_packet_thresh)) {
+		for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				power_manager_scale_core_med(
+						pol->core_share[count].pcpu);
+		}
+	} else if (diff < (pol->pkt.traffic_policy.avg_max_packet_thresh)) {
+		for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				power_manager_scale_core_min(
+						pol->core_share[count].pcpu);
+		}
+	}
+}
+
+static void
+apply_time_profile(struct policy *pol) {
+
+	int count, x;
+	struct timeval tv;
+	struct tm *ptm;
+	char time_string[40];
+
+	/* Obtain the time of day, and convert it to a tm struct. */
+	gettimeofday(&tv, NULL);
+	ptm = localtime(&tv.tv_sec);
+	/* Format the date and time, down to a single second. */
+	strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", ptm);
+
+	for (x = 0; x < HOURS; x++) {
+
+		if (ptm->tm_hour == pol->pkt.timer_policy.busy_hours[x]) {
+			for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				printf("Scaling up core %d to max\n",
+					 pol->core_share[count].pcpu);
+				power_manager_scale_core_max(
+						pol->core_share[count].pcpu);
+			}
+			break;
+		} else if (ptm->tm_hour ==
+				pol->pkt.timer_policy.quiet_hours[x]) {
+			for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				printf("Scaling down core %d to min\n",
+					 pol->core_share[count].pcpu);
+				power_manager_scale_core_min(
+						pol->core_share[count].pcpu);
+			}
+			break;
+		} else if (ptm->tm_hour ==
+			pol->pkt.timer_policy.hours_to_use_traffic_profile[x]) {
+			apply_traffic_profile(pol);
+			break;
+		}
+	}
+}
+
+static void
+apply_workload_profile(struct policy *pol) {
+
+	int count;
+
+	if (pol->pkt.workload == HIGH) {
+		for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				power_manager_scale_core_max(
+						pol->core_share[count].pcpu);
+		}
+	} else if (pol->pkt.workload == MEDIUM) {
+		for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				power_manager_scale_core_med(
+						pol->core_share[count].pcpu);
+		}
+	} else if (pol->pkt.workload == LOW) {
+		for (count = 0; count < 2; count++) {
+			if (pol->core_share[count].status != 1)
+				power_manager_scale_core_min(
+						pol->core_share[count].pcpu);
+		}
+	}
+}
+
+static void
+apply_policy(struct policy *pol) {
+
+	struct channel_packet *pkt = &pol->pkt;
+
+	/*Check policy to use*/
+	if (pkt->policy_to_use == TRAFFIC)
+		apply_traffic_profile(pol);
+	else if (pkt->policy_to_use == TIME)
+		apply_time_profile(pol);
+	else if (pkt->policy_to_use == WORKLOAD)
+		apply_workload_profile(pol);
+}
+
+
 static int
 process_request(struct channel_packet *pkt, struct channel_info *chan_info)
 {
@@ -128,6 +396,13 @@ process_request(struct channel_packet *pkt, struct channel_info *chan_info)
 
 		}
 	}
+
+	if (pkt->command == PKT_POLICY) {
+		printf("\nProcessing Policy request from Guest\n");
+		update_policy(pkt);
+		policy_is_set = 1;
+	}
+
 	/* Return is not checked as channel status may have been set to DISABLED
 	 * from management thread
 	 */
@@ -197,9 +472,10 @@ run_channel_monitor(void)
 			struct channel_info *chan_info = (struct channel_info *)
 					global_events_list[i].data.ptr;
 			if ((global_events_list[i].events & EPOLLERR) ||
-					(global_events_list[i].events & EPOLLHUP)) {
+				(global_events_list[i].events & EPOLLHUP)) {
 				RTE_LOG(DEBUG, CHANNEL_MONITOR, "Remote closed connection for "
-						"channel '%s'\n", chan_info->channel_path);
+						"channel '%s'\n",
+						chan_info->channel_path);
 				remove_channel(&chan_info);
 				continue;
 			}
@@ -211,14 +487,17 @@ run_channel_monitor(void)
 				int buffer_len = sizeof(pkt);
 
 				while (buffer_len > 0) {
-					n_bytes = read(chan_info->fd, buffer, buffer_len);
+					n_bytes = read(chan_info->fd,
+							buffer, buffer_len);
 					if (n_bytes == buffer_len)
 						break;
 					if (n_bytes == -1) {
 						err = errno;
-						RTE_LOG(DEBUG, CHANNEL_MONITOR, "Received error on "
-								"channel '%s' read: %s\n",
-								chan_info->channel_path, strerror(err));
+						RTE_LOG(DEBUG, CHANNEL_MONITOR,
+							"Received error on "
+							"channel '%s' read: %s\n",
+							chan_info->channel_path,
+							strerror(err));
 						remove_channel(&chan_info);
 						break;
 					}
@@ -229,5 +508,12 @@ run_channel_monitor(void)
 					process_request(&pkt, chan_info);
 			}
 		}
+		rte_delay_us(time_period_s*1000000);
+		if (policy_is_set) {
+			for (int j = 0; j < MAX_VMS; j++) {
+				if (policies[j].enabled == 1)
+					apply_policy(&policies[j]);
+			}
+		}
 	}
 }
diff --git a/examples/vm_power_manager/channel_monitor.h b/examples/vm_power_manager/channel_monitor.h
index c138607..eb1383f 100644
--- a/examples/vm_power_manager/channel_monitor.h
+++ b/examples/vm_power_manager/channel_monitor.h
@@ -35,6 +35,24 @@
 #define CHANNEL_MONITOR_H_
 
 #include "channel_manager.h"
+#include "channel_commands.h"
+
+struct core_share {
+	unsigned int pcpu;
+	/*
+	 * 1 CORE SHARE
+	 * 0 NOT SHARED
+	 */
+	int status;
+};
+
+struct policy {
+	struct channel_packet pkt;
+	uint32_t pfid[MAX_VFS];
+	uint32_t port[MAX_VFS];
+	unsigned int enabled;
+	struct core_share core_share[2];
+};
 
 #ifdef __cplusplus
 extern "C" {
-- 
2.7.4

  parent reply	other threads:[~2017-08-25 16:02 UTC|newest]

Thread overview: 105+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-08-25 16:02 [PATCH v1 0/10] Policy Based Power Control for Guest David Hunt
2017-08-25 16:02 ` [PATCH v1 01/10] net/i40e: add API to convert VF Id to PF Id David Hunt
2017-09-22  9:56   ` Thomas Monjalon
2017-09-22 12:39     ` Hunt, David
2017-09-25  2:43   ` Wu, Jingjing
2017-09-25  9:57     ` Hunt, David
2017-08-25 16:02 ` [PATCH v1 02/10] net/i40e: add API to get received packet count David Hunt
2017-09-25  2:47   ` Wu, Jingjing
2017-09-25  9:59     ` Hunt, David
2017-08-25 16:02 ` [PATCH v1 03/10] lib/librte_power: add extra msg type for policies David Hunt
2017-08-25 16:02 ` [PATCH v1 04/10] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
2017-08-25 16:02 ` [PATCH v1 05/10] examples/vm_power_mgr: add scale to medium freq fn David Hunt
2017-08-25 16:02 ` David Hunt [this message]
2017-08-25 16:02 ` [PATCH v1 07/10] examples/vm_power_mgr: add port initialisation David Hunt
2017-08-25 16:02 ` [PATCH v1 08/10] examples/guest_cli: add send policy to host David Hunt
2017-08-25 16:02 ` [PATCH v1 09/10] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-08-25 16:02 ` [PATCH v1 10/10] net/i40e: set register for no drop David Hunt
2017-09-25  2:50   ` Wu, Jingjing
2017-09-25  9:44     ` Hunt, David
2017-08-29 13:03 ` [PATCH v1 0/10] Policy Based Power Control for Guest Ananyev, Konstantin
2017-09-22  9:51   ` Thomas Monjalon
2017-09-22 10:28     ` Hunt, David
2017-09-22 13:03       ` Thomas Monjalon
2017-09-22 13:12         ` Hunt, David
2017-09-25 12:27 ` [PATCH v2] " David Hunt
2017-09-25 12:27   ` [PATCH v2 1/8] net/i40e: add API to convert VF MAC to VSI index David Hunt
2017-09-26 14:04     ` Wu, Jingjing
2017-09-25 12:27   ` [PATCH v2 2/8] lib/librte_power: add extra msg type for policies David Hunt
2017-09-25 12:27   ` [PATCH v2 3/8] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
2017-09-25 12:27   ` [PATCH v2 4/8] examples/vm_power_mgr: add scale to medium freq fn David Hunt
2017-09-25 12:27   ` [PATCH v2 5/8] examples/vm_power_mgr: add policy to channels David Hunt
2017-09-25 12:27   ` [PATCH v2 6/8] examples/vm_power_mgr: add port initialisation David Hunt
2017-09-25 12:27   ` [PATCH v2 7/8] examples/guest_cli: add send policy to host David Hunt
2017-09-25 12:27   ` [PATCH v2 8/8] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-10-04  9:15   ` [PATCH v4] Policy Based Power Control for Guest David Hunt
2017-10-04  9:15     ` [PATCH v4 1/9] net/i40e: add API to convert VF MAC to VF id David Hunt
2017-10-04 15:26       ` santosh
2017-10-04  9:15     ` [PATCH v4 2/9] lib/librte_power: add extra msg type for policies David Hunt
2017-10-04 15:36       ` santosh
2017-10-05  8:38         ` Hunt, David
2017-10-05  9:21           ` santosh
2017-10-05  9:51             ` Hunt, David
2017-10-04  9:15     ` [PATCH v4 3/9] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
2017-10-04  9:15     ` [PATCH v4 4/9] examples/vm_power_mgr: add scale to medium freq fn David Hunt
2017-10-04  9:15     ` [PATCH v4 5/9] examples/vm_power_mgr: add policy to channels David Hunt
2017-10-04  9:15     ` [PATCH v4 6/9] examples/vm_power_mgr: add port initialisation David Hunt
2017-10-04  9:15     ` [PATCH v4 7/9] power: add send channel msg function to map file David Hunt
2017-10-04  9:15     ` [PATCH v4 8/9] examples/guest_cli: add send policy to host David Hunt
2017-10-04  9:15     ` [PATCH v4 9/9] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-10-04 15:25     ` [PATCH v5 0/9] Policy Based Power Control for Guest David Hunt
2017-10-04 15:25       ` [PATCH v5 1/9] net/i40e: add API to convert VF MAC to VF id David Hunt
2017-10-04 15:41         ` santosh
2017-10-05  8:31           ` Hunt, David
2017-10-05  9:22             ` santosh
2017-10-04 15:25       ` [PATCH v5 2/9] lib/librte_power: add extra msg type for policies David Hunt
2017-10-04 15:47         ` santosh
2017-10-05  8:41           ` Hunt, David
2017-10-04 15:25       ` [PATCH v5 3/9] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
2017-10-04 15:58         ` santosh
2017-10-05  8:44           ` Hunt, David
2017-10-04 15:25       ` [PATCH v5 4/9] examples/vm_power_mgr: add scale to medium freq fn David Hunt
2017-10-04 16:04         ` santosh
2017-10-05  8:47           ` Hunt, David
2017-10-05  9:07             ` santosh
2017-10-04 15:25       ` [PATCH v5 5/9] examples/vm_power_mgr: add policy to channels David Hunt
2017-10-04 15:25       ` [PATCH v5 6/9] examples/vm_power_mgr: add port initialisation David Hunt
2017-10-04 15:25       ` [PATCH v5 7/9] power: add send channel msg function to map file David Hunt
2017-10-04 16:20         ` santosh
2017-10-04 15:25       ` [PATCH v5 8/9] examples/guest_cli: add send policy to host David Hunt
2017-10-04 15:25       ` [PATCH v5 9/9] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-10-05 12:25       ` [PATCH v6 0/9] Policy Based Power Control for Guest David Hunt
2017-10-05 12:25         ` [PATCH v6 1/9] net/i40e: add API to convert VF MAC to VF id David Hunt
2017-10-05 12:45           ` Ananyev, Konstantin
2017-10-05 12:51             ` Hunt, David
2017-10-05 12:25         ` [PATCH v6 2/9] lib/librte_power: add extra msg type for policies David Hunt
2017-10-05 12:25         ` [PATCH v6 3/9] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
2017-10-05 12:25         ` [PATCH v6 4/9] examples/vm_power_mgr: add scale to medium freq fn David Hunt
2017-10-05 12:25         ` [PATCH v6 5/9] examples/vm_power_mgr: add policy to channels David Hunt
2017-10-05 12:25         ` [PATCH v6 6/9] examples/vm_power_mgr: add port initialisation David Hunt
2017-10-05 12:25         ` [PATCH v6 7/9] power: add send channel msg function to map file David Hunt
2017-10-05 12:25         ` [PATCH v6 8/9] examples/guest_cli: add send policy to host David Hunt
2017-10-05 12:25         ` [PATCH v6 9/9] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-10-05 13:28         ` [PATCH v7 0/9] Policy Based Power Control for Guest David Hunt
2017-10-05 13:28           ` [PATCH v7 1/9] net/i40e: add API to convert VF MAC to VF id David Hunt
2017-10-05 13:28           ` [PATCH v7 2/9] lib/librte_power: add extra msg type for policies David Hunt
2017-10-05 13:28           ` [PATCH v7 3/9] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
2017-10-05 13:28           ` [PATCH v7 4/9] examples/vm_power_mgr: add scale to medium freq fn David Hunt
2017-10-05 13:28           ` [PATCH v7 5/9] examples/vm_power_mgr: add policy to channels David Hunt
2017-10-05 13:28           ` [PATCH v7 6/9] examples/vm_power_mgr: add port initialisation David Hunt
2017-10-05 13:28           ` [PATCH v7 7/9] power: add send channel msg function to map file David Hunt
2017-10-05 13:28           ` [PATCH v7 8/9] examples/guest_cli: add send policy to host David Hunt
2017-10-05 13:28           ` [PATCH v7 9/9] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-10-05 13:54           ` [PATCH v7 0/9] Policy Based Power Control for Guest Ananyev, Konstantin
2017-10-05 14:12           ` santosh
2017-10-05 14:34           ` [PATCH v8 " David Hunt
2017-10-05 14:34             ` [PATCH v8 1/9] net/i40e: add API to convert VF MAC to VF id David Hunt
2017-10-05 14:34             ` [PATCH v8 2/9] lib/librte_power: add extra msg type for policies David Hunt
2017-10-05 14:34             ` [PATCH v8 3/9] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
2017-10-05 14:34             ` [PATCH v8 4/9] examples/vm_power_mgr: add scale to medium freq fn David Hunt
2017-10-05 14:34             ` [PATCH v8 5/9] examples/vm_power_mgr: add policy to channels David Hunt
2017-10-05 14:34             ` [PATCH v8 6/9] examples/vm_power_mgr: add port initialisation David Hunt
2017-10-05 14:34             ` [PATCH v8 7/9] power: add send channel msg function to map file David Hunt
2017-10-05 14:34             ` [PATCH v8 8/9] examples/guest_cli: add send policy to host David Hunt
2017-10-05 14:34             ` [PATCH v8 9/9] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-10-09 22:34             ` [PATCH v8 0/9] Policy Based Power Control for Guest Ferruh Yigit

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=1503676941-80981-7-git-send-email-david.hunt@intel.com \
    --to=david.hunt@intel.com \
    --cc=dev@dpdk.org \
    --cc=nemanja.marjanovic@intel.com \
    --cc=rory.sexton@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.