* [dpdk-dev] [RFC 01/10] net/i40e: add API to convert VF Id to PF Id
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 02/10] net/i40e: add API to get received packet count David Hunt
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
Need a way to convert a vf id to a pf id on the host so as to query the pf
for relevant statistics which are used for the frequency changes in the
vm_power_manager app. Used when profiles are passed down from the guest
to the host, allowing the host to map the vfs to pfs.
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>
---
drivers/net/i40e/i40e_ethdev.c | 1 +
drivers/net/i40e/i40e_rxtx.c | 27 +++++++++++++++++++++++++++
drivers/net/i40e/i40e_rxtx.h | 1 +
lib/librte_ether/rte_ethdev.h | 11 +++++++++++
4 files changed, 40 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5f26e24..8fb67d8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -445,6 +445,7 @@ static const struct rte_pci_id pci_id_i40e_map[] = {
};
static const struct eth_dev_ops i40e_eth_dev_ops = {
+ .vfid_to_pfid = i40e_vf_mac_to_vsi,
.dev_configure = i40e_dev_configure,
.dev_start = i40e_dev_start,
.dev_stop = i40e_dev_stop,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index d42c23c..1379d5e 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -806,6 +806,33 @@ i40e_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
return nb_rx;
}
+uint64_t
+i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid) {
+ struct ether_addr *vf_mac_addr = (struct ether_addr *)&vfid;
+ struct ether_addr *mac;
+ struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ int vsi_id = 0, i, x;
+ struct i40e_pf_vf *vf;
+ uint16_t vf_num = pf->vf_num;
+
+ for (x = 0; x < vf_num; x++) {
+ int mac_addr_matches = 1;
+ vf = &pf->vfs[x];
+ mac = &vf->mac_addr;
+
+ for (i = 0; i < ETHER_ADDR_LEN; i++) {
+ if (mac->addr_bytes[i] != vf_mac_addr->addr_bytes[i])
+ mac_addr_matches = 0;
+ }
+ if (mac_addr_matches) {
+ vsi_id = vf->vsi->vsi_id;
+ return vsi_id;
+ }
+ }
+
+ return -1;
+}
+
uint16_t
i40e_recv_scattered_pkts(void *rx_queue,
struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 20084d6..bc6d355 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -192,6 +192,7 @@ union i40e_tx_offload {
};
};
+uint64_t i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid);
int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 0adf327..fec7e92 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1411,6 +1411,8 @@ typedef int (*eth_l2_tunnel_offload_set_t)
uint8_t en);
/**< @internal enable/disable the l2 tunnel offload functions */
+typedef uint64_t (*vfid_to_pfid)(struct rte_eth_dev *dev,
+ uint64_t vfid);
typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
enum rte_filter_type filter_type,
@@ -1429,6 +1431,7 @@ typedef int (*eth_get_dcb_info)(struct rte_eth_dev *dev,
* @internal A structure containing the functions exported by an Ethernet driver.
*/
struct eth_dev_ops {
+ vfid_to_pfid vfid_to_pfid; /**< Convert vfid to pfid */
eth_dev_configure_t dev_configure; /**< Configure device. */
eth_dev_start_t dev_start; /**< Start device. */
eth_dev_stop_t dev_stop; /**< Stop device. */
@@ -2928,6 +2931,14 @@ static inline int rte_eth_tx_descriptor_status(uint8_t port_id,
return (*dev->dev_ops->tx_descriptor_status)(txq, offset);
}
+static inline uint64_t
+vfid_to_pfid_direct(uint8_t port_id, uint64_t vfid)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ uint64_t pfid = (*dev->dev_ops->vfid_to_pfid)(dev, vfid);
+ return pfid;
+}
+
/**
* Send a burst of output packets on a transmit queue of an Ethernet device.
*
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 02/10] net/i40e: add API to get received packet count
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 01/10] net/i40e: add API to convert VF Id to PF Id David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 03/10] lib/librte_power: add extra msg type for policies David Hunt
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
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>
---
drivers/net/i40e/i40e_ethdev.c | 1 +
drivers/net/i40e/i40e_rxtx.c | 10 ++++++++++
drivers/net/i40e/i40e_rxtx.h | 1 +
lib/librte_ether/rte_ethdev.h | 19 +++++++++++++++++++
4 files changed, 31 insertions(+)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 8fb67d8..d9806fc 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -446,6 +446,7 @@ static const struct rte_pci_id pci_id_i40e_map[] = {
static const struct eth_dev_ops i40e_eth_dev_ops = {
.vfid_to_pfid = i40e_vf_mac_to_vsi,
+ .read_pf_stats = i40e_vsi_stats_read,
.dev_configure = i40e_dev_configure,
.dev_start = i40e_dev_start,
.dev_stop = i40e_dev_stop,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 1379d5e..cc036b7 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -833,6 +833,16 @@ i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid) {
return -1;
}
+uint64_t
+i40e_vsi_stats_read(struct rte_eth_dev *dev, uint8_t vsi_id) {
+ struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+
+ uint64_t glv_uprch = I40E_READ_REG(hw,
+ I40E_GLV_UPRCH(vsi_id)) && 0x0000FFFF;
+ uint64_t glv_uprcl = I40E_READ_REG(hw, I40E_GLV_UPRCL(vsi_id));
+ return glv_uprcl + (glv_uprch << 32);
+}
+
uint16_t
i40e_recv_scattered_pkts(void *rx_queue,
struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index bc6d355..db19153 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -193,6 +193,7 @@ union i40e_tx_offload {
};
uint64_t i40e_vf_mac_to_vsi(struct rte_eth_dev *dev, uint64_t vfid);
+uint64_t i40e_vsi_stats_read(struct rte_eth_dev *dev, uint8_t vsi_id);
int i40e_dev_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id);
int i40e_dev_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id);
int i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id);
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index fec7e92..4917233 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1413,6 +1413,9 @@ typedef int (*eth_l2_tunnel_offload_set_t)
typedef uint64_t (*vfid_to_pfid)(struct rte_eth_dev *dev,
uint64_t vfid);
+/**< @internal Ethernet device configuration. */
+typedef uint64_t (*read_pf_stats)(struct rte_eth_dev *dev, uint8_t pfid);
+
typedef int (*eth_filter_ctrl_t)(struct rte_eth_dev *dev,
enum rte_filter_type filter_type,
@@ -1432,6 +1435,7 @@ typedef int (*eth_get_dcb_info)(struct rte_eth_dev *dev,
*/
struct eth_dev_ops {
vfid_to_pfid vfid_to_pfid; /**< Convert vfid to pfid */
+ read_pf_stats read_pf_stats;/**<Read low-level pf stats .*/
eth_dev_configure_t dev_configure; /**< Configure device. */
eth_dev_start_t dev_start; /**< Start device. */
eth_dev_stop_t dev_stop; /**< Stop device. */
@@ -2939,6 +2943,21 @@ vfid_to_pfid_direct(uint8_t port_id, uint64_t vfid)
return pfid;
}
+/*
+ * Reads the NIC occupancy if possible with device in use.
+ * @param port_id
+ * The port identifier of the Ethernet device.
+ * @return
+ * Nic occupany in bytes.
+ */
+static inline uint64_t
+read_pf_stats_direct(uint8_t port_id, uint8_t pfid)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ uint64_t pkt_count = (*dev->dev_ops->read_pf_stats)(dev, pfid);
+ return pkt_count;
+}
+
/**
* Send a burst of output packets on a transmit queue of an Ethernet device.
*
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 03/10] lib/librte_power: add extra msg type for policies
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 01/10] net/i40e: add API to convert VF Id to PF Id David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 02/10] net/i40e: add API to get received packet count David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 04/10] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
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>
---
lib/librte_power/channel_commands.h | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/lib/librte_power/channel_commands.h b/lib/librte_power/channel_commands.h
index 383897b..79799b7 100644
--- a/lib/librte_power/channel_commands.h
+++ b/lib/librte_power/channel_commands.h
@@ -46,17 +46,50 @@ extern "C" {
/* Valid Commands */
#define CPU_POWER 1
#define CPU_POWER_CONNECT 2
+#define PKT_POLICY 3
/* CPU Power Command Scaling */
#define CPU_POWER_SCALE_UP 1
#define CPU_POWER_SCALE_DOWN 2
#define CPU_POWER_SCALE_MAX 3
#define CPU_POWER_SCALE_MIN 4
+#define HOURS 24
+#define MAX_VFS 10
+
+typedef enum {false, true} bool;
+
+struct t_boost_status {
+ bool tbEnabled;
+};
+
+struct timer_profile {
+ int busy_hours[HOURS];
+ int quiet_hours[HOURS];
+ int hours_to_use_traffic_profile[HOURS];
+};
+
+enum workload {HIGH, MEDIUM, LOW};
+enum policy_to_use {TRAFFIC, TIME, WORKLOAD};
+
+struct traffic {
+ uint32_t min_packet_thresh;
+ uint32_t avg_max_packet_thresh;
+ uint32_t max_max_packet_thresh;
+};
struct channel_packet {
uint64_t resource_id; /**< core_num, device */
uint32_t unit; /**< scale down/up/min/max */
uint32_t command; /**< Power, IO, etc */
+ char vm_name[32];
+ uint64_t vfid[MAX_VFS];
+ int nb_mac_to_monitor;
+ uint8_t vcpu_to_control[5];
+ struct traffic traffic_policy;
+ struct timer_profile timer_policy;
+ enum workload workload;
+ enum policy_to_use policy_to_use;
+ struct t_boost_status t_boost_status;
};
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 04/10] examples/vm_power_mgr: add vcpu to pcpu mapping
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
` (2 preceding siblings ...)
2017-08-04 13:54 ` [dpdk-dev] [RFC 03/10] lib/librte_power: add extra msg type for policies David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 05/10] examples/vm_power_mgr: add policy to channels David Hunt
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
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_manager.c | 55 +++++++++++++++++++++++++++++
examples/vm_power_manager/channel_manager.h | 16 ++++++++-
2 files changed, 70 insertions(+), 1 deletion(-)
diff --git a/examples/vm_power_manager/channel_manager.c b/examples/vm_power_manager/channel_manager.c
index e068ae2..2abba9c 100644
--- a/examples/vm_power_manager/channel_manager.c
+++ b/examples/vm_power_manager/channel_manager.c
@@ -574,6 +574,61 @@ set_channel_status(const char *vm_name, unsigned *channel_list,
return num_channels_changed;
}
+void
+get_all_vm(int *noVms, int *noVcpus) {
+
+ virNodeInfo info;
+ virDomainPtr *domptr;
+ uint64_t mask;
+ int ret, i, numVcpus[MAX_VCPUS], cpu;
+ unsigned int ii, jj, n_vcpus;
+ const char *vm_name;
+ unsigned int flags = VIR_CONNECT_LIST_DOMAINS_RUNNING |
+ VIR_CONNECT_LIST_DOMAINS_PERSISTENT;
+ unsigned int flag = VIR_DOMAIN_VCPU_CONFIG;
+
+
+ memset(global_cpumaps, 0, CHANNEL_CMDS_MAX_CPUS*global_maplen);
+ if (virNodeGetInfo(global_vir_conn_ptr, &info))
+ RTE_LOG(ERR, CHANNEL_MANAGER, "Unable to retrieve node Info\n");
+
+ /*Returns number of pcpus*/
+ global_n_host_cpus = (unsigned int)info.cpus;
+
+ /*Returns number of active domains */
+ ret = virConnectListAllDomains(global_vir_conn_ptr, &domptr, flags);
+ *noVms = ret;
+ if (ret < 0)
+ RTE_LOG(ERR, CHANNEL_MANAGER, "No Active Domains Running\n");
+
+ for (i = 0; i < ret; i++) {
+
+ /*Get Domain Names*/
+ vm_name = virDomainGetName(domptr[i]);
+ lvm_info[i].vm_name = vm_name;
+ /*Get Number of Vcpus*/
+ numVcpus[i] = virDomainGetVcpusFlags(domptr[i], flag);
+ /*Get Number of VCpus & VcpuPinInfo*/
+ n_vcpus = virDomainGetVcpuPinInfo(domptr[i],
+ numVcpus[i], global_cpumaps,
+ global_maplen, flag);
+ if ((int)n_vcpus > *noVcpus)
+ *noVcpus = n_vcpus;
+ for (ii = 0; ii < n_vcpus; ii++) {
+ mask = 0;
+ for (jj = 0; jj < global_n_host_cpus; jj++) {
+ if (VIR_CPU_USABLE(global_cpumaps,
+ global_maplen, ii, jj) > 0) {
+ mask |= 1ULL << jj;
+ }
+ }
+ ITERATIVE_BITMASK_CHECK_64(mask, cpu) {
+ lvm_info[i].pcpus[ii] = cpu;
+ }
+ }
+ }
+}
+
int
get_info_vm(const char *vm_name, struct vm_info *info)
{
diff --git a/examples/vm_power_manager/channel_manager.h b/examples/vm_power_manager/channel_manager.h
index 47c3b9c..8dff76c 100644
--- a/examples/vm_power_manager/channel_manager.h
+++ b/examples/vm_power_manager/channel_manager.h
@@ -66,6 +66,16 @@ struct sockaddr_un _sockaddr_un;
#define UNIX_PATH_MAX sizeof(_sockaddr_un.sun_path)
#endif
+#define MAX_VMS 4
+#define MAX_VCPUS 20
+
+
+struct libvirt_vm_info {
+ const char *vm_name;
+ unsigned int pcpus[22];
+};
+
+struct libvirt_vm_info lvm_info[MAX_VMS];
/* Communication Channel Status */
enum channel_status { CHANNEL_MGR_CHANNEL_DISCONNECTED = 0,
CHANNEL_MGR_CHANNEL_CONNECTED,
@@ -318,7 +328,11 @@ int set_channel_status(const char *vm_name, unsigned *channel_list,
* - Negative on error.
*/
int get_info_vm(const char *vm_name, struct vm_info *info);
-
+/**
+ * Populates a table with all domains running and their physical cpu.
+ * All information is gathered through libvirt api.
+ */
+void get_all_vm(int *noVms, int *noVcpus);
#ifdef __cplusplus
}
#endif
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 05/10] examples/vm_power_mgr: add policy to channels
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
` (3 preceding siblings ...)
2017-08-04 13:54 ` [dpdk-dev] [RFC 04/10] examples/vm_power_mgr: add vcpu to pcpu mapping David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 06/10] examples/vm_power_mgr: add scale to medium freq fn David Hunt
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
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 | 353 +++++++++++++++++++++++-----
examples/vm_power_manager/channel_monitor.h | 18 ++
2 files changed, 315 insertions(+), 56 deletions(-)
diff --git a/examples/vm_power_manager/channel_monitor.c b/examples/vm_power_manager/channel_monitor.c
index e7f5cc4..822f2cb 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,70 +76,292 @@ void channel_monitor_exit(void)
rte_free(global_events_list);
}
-static int
-process_request(struct channel_packet *pkt, struct channel_info *chan_info)
+static void
+core_share(int pNo, int z, int x, int t)
{
- uint64_t core_mask;
+ 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);
+ }
+ }
+}
- if (chan_info == NULL)
- return -1;
+static void
+core_share_status(int pNo) {
- if (rte_atomic32_cmpset(&(chan_info->status), CHANNEL_MGR_CHANNEL_CONNECTED,
- CHANNEL_MGR_CHANNEL_PROCESSING) == 0)
- return -1;
+ int noVms, noVcpus, z, x, t;
- if (pkt->command == CPU_POWER) {
- core_mask = get_pcpus_mask(chan_info, pkt->resource_id);
- if (core_mask == 0) {
- RTE_LOG(ERR, CHANNEL_MONITOR, "Error get physical CPU mask for "
- "channel '%s' using vCPU(%u)\n", chan_info->channel_path,
- (unsigned)pkt->unit);
- return -1;
+ 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);
}
- if (__builtin_popcountll(core_mask) == 1) {
+ }
+}
- unsigned core_num = __builtin_ffsll(core_mask) - 1;
+#define ITERATIVE_BITMASK_CHECK_64(mask_u64b, i) \
+ for (i = 0; mask_u64b; mask_u64b &= ~(1ULL << i++)) \
+ if ((mask_u64b >> i) & 1) \
- switch (pkt->unit) {
- case(CPU_POWER_SCALE_MIN):
- power_manager_scale_core_min(core_num);
- break;
- case(CPU_POWER_SCALE_MAX):
- power_manager_scale_core_max(core_num);
- break;
- case(CPU_POWER_SCALE_DOWN):
- power_manager_scale_core_down(core_num);
- break;
- case(CPU_POWER_SCALE_UP):
- power_manager_scale_core_up(core_num);
- break;
- default:
+static void
+get_pcpu_to_control(struct policy *pol) {
+
+ /* Convert vcpu to pcpu. */
+ struct vm_info info;
+ int pcpu, count;
+
+ 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++) {
+ ITERATIVE_BITMASK_CHECK_64(
+ info.pcpu_mask[pol->pkt.vcpu_to_control[count]],
+ pcpu) {
+ pol->core_share[count].pcpu = pcpu;
+ printf("pcpu is %d\n", 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;
}
- } else {
- switch (pkt->unit) {
- case(CPU_POWER_SCALE_MIN):
- power_manager_scale_mask_min(core_mask);
- break;
- case(CPU_POWER_SCALE_MAX):
- power_manager_scale_mask_max(core_mask);
+ }
+ 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;
- case(CPU_POWER_SCALE_DOWN):
- power_manager_scale_mask_down(core_mask);
+ } 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;
- case(CPU_POWER_SCALE_UP):
- power_manager_scale_mask_up(core_mask);
+ } else if (ptm->tm_hour ==
+ pol->pkt.timer_policy.hours_to_use_traffic_profile[x]) {
+ apply_traffic_profile(pol);
break;
- default:
- 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)
+{
+ if (chan_info == NULL)
+ return -1;
+
+ if (rte_atomic32_cmpset(&(chan_info->status),
+ CHANNEL_MGR_CHANNEL_CONNECTED,
+ CHANNEL_MGR_CHANNEL_PROCESSING) == 0)
+ return -1;
+
+ 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
+ /* Return is not checked as channel status may have been set to
+ * DISABLED from management thread
*/
- rte_atomic32_cmpset(&(chan_info->status), CHANNEL_MGR_CHANNEL_PROCESSING,
+ rte_atomic32_cmpset(&(chan_info->status),
+ CHANNEL_MGR_CHANNEL_PROCESSING,
CHANNEL_MGR_CHANNEL_CONNECTED);
return 0;
@@ -197,9 +427,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 +442,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 +463,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
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 06/10] examples/vm_power_mgr: add scale to medium freq fn
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
` (4 preceding siblings ...)
2017-08-04 13:54 ` [dpdk-dev] [RFC 05/10] examples/vm_power_mgr: add policy to channels David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 07/10] examples/vm_power_mgr: add port initialisation David Hunt
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
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/power_manager.c | 15 +++++++++++++++
examples/vm_power_manager/power_manager.h | 13 +++++++++++++
2 files changed, 28 insertions(+)
diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c
index 2644fce..7b0afda 100644
--- a/examples/vm_power_manager/power_manager.c
+++ b/examples/vm_power_manager/power_manager.c
@@ -250,3 +250,18 @@ power_manager_scale_core_max(unsigned core_num)
POWER_SCALE_CORE(max, core_num, ret);
return ret;
}
+
+int
+power_manager_scale_core_med(unsigned int core_num)
+{
+ int ret = 0;
+
+ if (core_num >= POWER_MGR_MAX_CPUS)
+ return -1;
+ if (!(global_enabled_cpus & (1ULL << core_num)))
+ return -1;
+ rte_spinlock_lock(&global_core_freq_info[core_num].power_sl);
+ ret = rte_power_set_freq(core_num, 5);
+ rte_spinlock_unlock(&global_core_freq_info[core_num].power_sl);
+ return ret;
+}
diff --git a/examples/vm_power_manager/power_manager.h b/examples/vm_power_manager/power_manager.h
index 1b45bab..6cdec7a 100644
--- a/examples/vm_power_manager/power_manager.h
+++ b/examples/vm_power_manager/power_manager.h
@@ -179,6 +179,19 @@ int power_manager_scale_core_max(unsigned core_num);
*/
uint32_t power_manager_get_current_frequency(unsigned core_num);
+/**
+ * Scale to medium frequency for the core specified by core_num.
+ * It is thread-safe.
+ *
+ * @param core_num
+ * The core number to change frequency
+ *
+ * @return
+ * - 1 on success.
+ * - 0 if frequency not changed.
+ * - Negative on error.
+ */
+int power_manager_scale_core_med(unsigned int core_num);
#ifdef __cplusplus
}
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 07/10] examples/vm_power_mgr: add port initialisation
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
` (5 preceding siblings ...)
2017-08-04 13:54 ` [dpdk-dev] [RFC 06/10] examples/vm_power_mgr: add scale to medium freq fn David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 08/10] examples/guest_cli: add send policy to host David Hunt
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic
We need to initialise the port's we're monitoring to be able to see
the throughput.
Signed-off-by: Nemanja Marjanovic <nemanja.marjanovic@intel.com>
Signed-off-by: David Hunt <david.hunt@intel.com>
---
examples/vm_power_manager/main.c | 220 +++++++++++++++++++++++++++++++++++++++
1 file changed, 220 insertions(+)
diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c
index c33fcc9..698abca 100644
--- a/examples/vm_power_manager/main.c
+++ b/examples/vm_power_manager/main.c
@@ -49,6 +49,9 @@
#include <rte_log.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
+#include <rte_ethdev.h>
+#include <getopt.h>
+#include <rte_cycles.h>
#include <rte_debug.h>
#include "channel_manager.h"
@@ -56,6 +59,192 @@
#include "power_manager.h"
#include "vm_power_cli.h"
+#define RX_RING_SIZE 512
+#define TX_RING_SIZE 512
+
+#define NUM_MBUFS 8191
+#define MBUF_CACHE_SIZE 250
+#define BURST_SIZE 32
+
+static uint32_t enabled_port_mask;
+static volatile bool force_quit;
+
+/****************/
+static const struct rte_eth_conf port_conf_default = {
+ .rxmode = { .max_rx_pkt_len = ETHER_MAX_LEN }
+};
+
+static inline int
+port_init(uint8_t port, struct rte_mempool *mbuf_pool)
+{
+ struct rte_eth_conf port_conf = port_conf_default;
+ const uint16_t rx_rings = 1, tx_rings = 1;
+ int retval;
+ uint16_t q;
+
+ if (port >= rte_eth_dev_count())
+ return -1;
+
+ /* Configure the Ethernet device. */
+ retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
+ if (retval != 0)
+ return retval;
+
+ /* Allocate and set up 1 RX queue per Ethernet port. */
+ for (q = 0; q < rx_rings; q++) {
+ retval = rte_eth_rx_queue_setup(port, q, RX_RING_SIZE,
+ rte_eth_dev_socket_id(port), NULL, mbuf_pool);
+ if (retval < 0)
+ return retval;
+ }
+
+ /* Allocate and set up 1 TX queue per Ethernet port. */
+ for (q = 0; q < tx_rings; q++) {
+ retval = rte_eth_tx_queue_setup(port, q, TX_RING_SIZE,
+ rte_eth_dev_socket_id(port), NULL);
+ if (retval < 0)
+ return retval;
+ }
+
+ /* Start the Ethernet port. */
+ retval = rte_eth_dev_start(port);
+ if (retval < 0)
+ return retval;
+
+ /* Display the port MAC address. */
+ struct ether_addr addr;
+ rte_eth_macaddr_get(port, &addr);
+ printf("Port %u MAC: %02" PRIx8 " %02" PRIx8 " %02" PRIx8
+ " %02" PRIx8 " %02" PRIx8 " %02" PRIx8 "\n",
+ (unsigned int)port,
+ addr.addr_bytes[0], addr.addr_bytes[1],
+ addr.addr_bytes[2], addr.addr_bytes[3],
+ addr.addr_bytes[4], addr.addr_bytes[5]);
+
+ /* Enable RX in promiscuous mode for the Ethernet device. */
+ rte_eth_promiscuous_enable(port);
+
+
+ return 0;
+}
+
+static int
+parse_portmask(const char *portmask)
+{
+ char *end = NULL;
+ unsigned long pm;
+
+ /* parse hexadecimal string */
+ pm = strtoul(portmask, &end, 16);
+ if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
+ return -1;
+
+ if (pm == 0)
+ return -1;
+
+ return pm;
+}
+/* Parse the argument given in the command line of the application */
+static int
+parse_args(int argc, char **argv)
+{
+ int opt, ret;
+ char **argvopt;
+ int option_index;
+ char *prgname = argv[0];
+ static struct option lgopts[] = {
+ { "mac-updating", no_argument, 0, 1},
+ { "no-mac-updating", no_argument, 0, 0},
+ {NULL, 0, 0, 0}
+ };
+ argvopt = argv;
+
+ while ((opt = getopt_long(argc, argvopt, "p:q:T:",
+ lgopts, &option_index)) != EOF) {
+
+ switch (opt) {
+ /* portmask */
+ case 'p':
+ enabled_port_mask = parse_portmask(optarg);
+ if (enabled_port_mask == 0) {
+ printf("invalid portmask\n");
+ return -1;
+ }
+ break;
+ /* long options */
+ case 0:
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+ if (optind >= 0)
+ argv[optind-1] = prgname;
+
+ ret = optind-1;
+ optind = 0; /* reset getopt lib */
+ return ret;
+}
+
+static void
+check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
+{
+#define CHECK_INTERVAL 100 /* 100ms */
+#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
+ uint8_t portid, count, all_ports_up, print_flag = 0;
+ struct rte_eth_link link;
+
+ printf("\nChecking link status");
+ fflush(stdout);
+ for (count = 0; count <= MAX_CHECK_TIME; count++) {
+ if (force_quit)
+ return;
+ all_ports_up = 1;
+ for (portid = 0; portid < port_num; portid++) {
+ if (force_quit)
+ return;
+ if ((port_mask & (1 << portid)) == 0)
+ continue;
+ memset(&link, 0, sizeof(link));
+ rte_eth_link_get_nowait(portid, &link);
+ /* print link status if flag set */
+ if (print_flag == 1) {
+ if (link.link_status)
+ printf("Port %d Link Up - speed %u "
+ "Mbps - %s\n", (uint8_t)portid,
+ (unsigned int)link.link_speed,
+ (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
+ ("full-duplex") : ("half-duplex\n"));
+ else
+ printf("Port %d Link Down\n",
+ (uint8_t)portid);
+ continue;
+ }
+ /* clear all_ports_up flag if any link down */
+ if (link.link_status == ETH_LINK_DOWN) {
+ all_ports_up = 0;
+ break;
+ }
+ }
+ /* after finally printing all link status, get out */
+ if (print_flag == 1)
+ break;
+
+ if (all_ports_up == 0) {
+ printf(".");
+ fflush(stdout);
+ rte_delay_ms(CHECK_INTERVAL);
+ }
+
+ /* set the print_flag if all ports up or timeout */
+ if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
+ print_flag = 1;
+ printf("done\n");
+ }
+ }
+}
static int
run_monitor(__attribute__((unused)) void *arg)
{
@@ -82,6 +271,10 @@ main(int argc, char **argv)
{
int ret;
unsigned lcore_id;
+ unsigned int nb_ports;
+ struct rte_mempool *mbuf_pool;
+ uint8_t portid;
+
ret = rte_eal_init(argc, argv);
if (ret < 0)
@@ -90,12 +283,39 @@ main(int argc, char **argv)
signal(SIGINT, sig_handler);
signal(SIGTERM, sig_handler);
+ argc -= ret;
+ argv += ret;
+
+ /* parse application arguments (after the EAL ones) */
+ ret = parse_args(argc, argv);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Invalid arguments\n");
+
+ nb_ports = rte_eth_dev_count();
+
+ mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports,
+ MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
+
+ if (mbuf_pool == NULL)
+ rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
+
+ /* Initialize ports. */
+ for (portid = 0; portid < nb_ports; portid++) {
+ if ((enabled_port_mask & (1 << portid)) == 0)
+ continue;
+ if (port_init(portid, mbuf_pool) != 0)
+ rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
+ portid);
+ }
+
lcore_id = rte_get_next_lcore(-1, 1, 0);
if (lcore_id == RTE_MAX_LCORE) {
RTE_LOG(ERR, EAL, "A minimum of two cores are required to run "
"application\n");
return 0;
}
+
+ check_all_ports_link_status(nb_ports, enabled_port_mask);
rte_eal_remote_launch(run_monitor, NULL, lcore_id);
if (power_manager_init() < 0) {
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 08/10] examples/guest_cli: add send policy to host
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
` (6 preceding siblings ...)
2017-08-04 13:54 ` [dpdk-dev] [RFC 07/10] examples/vm_power_mgr: add port initialisation David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 09/10] examples/vm_power_mgr: set MAC address of VF David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 10/10] net/i40e: set register for no drop David Hunt
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
Here we're adding an example of setting up a policy, and allowing the
vm_cli_guest app to send it to the host using the cli command
"send_policy now"
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>
---
.../guest_cli/vm_power_cli_guest.c | 94 ++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
index 7931135..bff2afc 100644
--- a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
+++ b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
@@ -45,6 +45,7 @@
#include <cmdline.h>
#include <rte_log.h>
#include <rte_lcore.h>
+#include <rte_ethdev.h>
#include <rte_power.h>
@@ -135,8 +136,101 @@ cmdline_parse_inst_t cmd_set_cpu_freq_set = {
},
};
+struct cmd_send_policy_result {
+ cmdline_fixed_string_t send_policy;
+ cmdline_fixed_string_t cmd;
+};
+
+union PFID {
+ struct ether_addr addr;
+ uint64_t pfid;
+};
+
+static inline int
+send_policy(void)
+{
+ struct channel_packet pkt;
+ union PFID pfid;
+ int ret;
+
+ /* Use port MAC address as the vfid */
+ rte_eth_macaddr_get(0, &pfid.addr);
+ printf("Port %u MAC: %02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":"
+ "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n",
+ 1,
+ pfid.addr.addr_bytes[0], pfid.addr.addr_bytes[1],
+ pfid.addr.addr_bytes[2], pfid.addr.addr_bytes[3],
+ pfid.addr.addr_bytes[4], pfid.addr.addr_bytes[5]);
+ pkt.vfid[0] = pfid.pfid;
+
+ pkt.nb_mac_to_monitor = 1;
+ pkt.t_boost_status.tbEnabled = false;
+
+ pkt.vcpu_to_control[0] = 0;
+ pkt.vcpu_to_control[1] = 1;
+ /* Dummy Population. */
+ pkt.traffic_policy.min_packet_thresh = 96000;
+ pkt.traffic_policy.avg_max_packet_thresh = 1800000;
+ pkt.traffic_policy.max_max_packet_thresh = 2000000;
+
+ pkt.timer_policy.busy_hours[0] = 3;
+ pkt.timer_policy.busy_hours[1] = 4;
+ pkt.timer_policy.busy_hours[2] = 5;
+ pkt.timer_policy.quiet_hours[0] = 11;
+ pkt.timer_policy.quiet_hours[1] = 12;
+ pkt.timer_policy.quiet_hours[2] = 13;
+ pkt.timer_policy.hours_to_use_traffic_profile[0] = 8;
+ pkt.timer_policy.hours_to_use_traffic_profile[1] = 10;
+
+ pkt.workload = LOW;
+ pkt.policy_to_use = TRAFFIC;
+ pkt.command = PKT_POLICY;
+ strcpy(pkt.vm_name, "ubintu2");
+ ret = guest_channel_send_msg(&pkt, 1);
+ if (ret == 0)
+ return 1;
+ RTE_LOG(DEBUG, POWER, "Error sending message: %s\n",
+ ret > 0 ? strerror(ret) : "channel not connected");
+ return -1;
+}
+
+static void
+cmd_send_policy_parsed(void *parsed_result, struct cmdline *cl,
+ __attribute__((unused)) void *data)
+{
+ int ret = -1;
+ struct cmd_send_policy_result *res = parsed_result;
+
+ if (!strcmp(res->cmd, "now")) {
+ printf("Sending Policy down now!\n");
+ ret = send_policy();
+ }
+ if (ret != 1)
+ cmdline_printf(cl, "Error sending message: %s\n",
+ strerror(ret));
+}
+
+cmdline_parse_token_string_t cmd_send_policy =
+ TOKEN_STRING_INITIALIZER(struct cmd_send_policy_result,
+ send_policy, "send_policy");
+cmdline_parse_token_string_t cmd_send_policy_cmd_cmd =
+ TOKEN_STRING_INITIALIZER(struct cmd_send_policy_result,
+ cmd, "now");
+
+cmdline_parse_inst_t cmd_send_policy_set = {
+ .f = cmd_send_policy_parsed,
+ .data = NULL,
+ .help_str = "send_policy now",
+ .tokens = {
+ (void *)&cmd_send_policy,
+ (void *)&cmd_send_policy_cmd_cmd,
+ NULL,
+ },
+};
+
cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_quit,
+ (cmdline_parse_inst_t *)&cmd_send_policy_set,
(cmdline_parse_inst_t *)&cmd_set_cpu_freq_set,
NULL,
};
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 09/10] examples/vm_power_mgr: set MAC address of VF
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
` (7 preceding siblings ...)
2017-08-04 13:54 ` [dpdk-dev] [RFC 08/10] examples/guest_cli: add send policy to host David Hunt
@ 2017-08-04 13:54 ` David Hunt
2017-08-04 13:54 ` [dpdk-dev] [RFC 10/10] net/i40e: set register for no drop David Hunt
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt
We need to set vf mac from the host, so that they will be in sync on the
guest and the host. Otherwise, we'll have a random mac on the guest, and
a 00:00:00:00:00:00 mac on the host.
Signed-off-by: David Hunt <david.hunt@intel.com>
---
examples/vm_power_manager/main.c | 58 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c
index 698abca..f307ec7 100644
--- a/examples/vm_power_manager/main.c
+++ b/examples/vm_power_manager/main.c
@@ -58,6 +58,15 @@
#include "channel_monitor.h"
#include "power_manager.h"
#include "vm_power_cli.h"
+#ifdef RTE_LIBRTE_IXGBE_PMD
+#include <rte_pmd_ixgbe.h>
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+#include <rte_pmd_i40e.h>
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+#include <rte_pmd_bnxt.h>
+#endif
#define RX_RING_SIZE 512
#define TX_RING_SIZE 512
@@ -222,7 +231,7 @@ check_all_ports_link_status(uint8_t port_num, uint32_t port_mask)
(uint8_t)portid);
continue;
}
- /* clear all_ports_up flag if any link down */
+ /* clear all_ports_up flag if any link down */
if (link.link_status == ETH_LINK_DOWN) {
all_ports_up = 0;
break;
@@ -301,11 +310,58 @@ main(int argc, char **argv)
/* Initialize ports. */
for (portid = 0; portid < nb_ports; portid++) {
+ struct ether_addr eth;
+ int w, j;
+ int ret = -ENOTSUP;
+
if ((enabled_port_mask & (1 << portid)) == 0)
continue;
+
+ eth.addr_bytes[0] = 0xe0;
+ eth.addr_bytes[1] = 0xe0;
+ eth.addr_bytes[2] = 0xe0;
+ eth.addr_bytes[3] = 0xe0;
+ eth.addr_bytes[4] = portid + 0xf0;
+
if (port_init(portid, mbuf_pool) != 0)
rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n",
portid);
+
+ for (w = 0; w < MAX_VFS; w++) {
+ eth.addr_bytes[5] = w + 0xf0;
+
+#ifdef RTE_LIBRTE_IXGBE_PMD
+ if (ret == -ENOTSUP)
+ ret = rte_pmd_ixgbe_set_vf_mac_addr(portid,
+ w, ð);
+#endif
+#ifdef RTE_LIBRTE_I40E_PMD
+ if (ret == -ENOTSUP)
+ ret = rte_pmd_i40e_set_vf_mac_addr(portid,
+ w, ð);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+ if (ret == -ENOTSUP)
+ ret = rte_pmd_bnxt_set_vf_mac_addr(portid,
+ w, ð);
+#endif
+
+
+ ret = rte_pmd_i40e_set_vf_mac_addr(portid, w,
+ ð);
+ switch (ret) {
+ case 0:
+ printf("Port %d VF %d MAC: ",
+ portid, w);
+ for (j = 0; j < 6; j++) {
+ printf("%02x", eth.addr_bytes[j]);
+ if (j < 5)
+ printf(":");
+ }
+ printf("\n");
+ break;
+ }
+ }
}
lcore_id = rte_get_next_lcore(-1, 1, 0);
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread
* [dpdk-dev] [RFC 10/10] net/i40e: set register for no drop
2017-08-04 13:54 [dpdk-dev] [RFC] Policy Based Power Control for Guest David Hunt
` (8 preceding siblings ...)
2017-08-04 13:54 ` [dpdk-dev] [RFC 09/10] examples/vm_power_mgr: set MAC address of VF David Hunt
@ 2017-08-04 13:54 ` David Hunt
9 siblings, 0 replies; 11+ messages in thread
From: David Hunt @ 2017-08-04 13:54 UTC (permalink / raw)
To: dev; +Cc: thomas, jingjing.wu, David Hunt, Nemanja Marjanovic, Rory Sexton
See the XL710 controller datasheet for more information on this register
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>
---
drivers/net/i40e/i40e_ethdev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index d9806fc..24b713e 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1156,7 +1156,7 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
* in firmware in the future.
*/
i40e_configure_registers(hw);
-
+ I40E_WRITE_REG(hw, I40E_PRTDCB_TC2PFC, 0xff);
/* Get hw capabilities */
ret = i40e_get_cap(hw);
if (ret != I40E_SUCCESS) {
--
2.7.4
^ permalink raw reply [flat|nested] 11+ messages in thread