13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 23998e2a0SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3e8ae9b66SAlan Carew */ 4e8ae9b66SAlan Carew 572b452c5SDmitry Kozlyuk #include <ctype.h> 6e8ae9b66SAlan Carew #include <unistd.h> 7e8ae9b66SAlan Carew #include <stdio.h> 8e8ae9b66SAlan Carew #include <stdlib.h> 9e8ae9b66SAlan Carew #include <stdint.h> 10e8ae9b66SAlan Carew #include <signal.h> 11e8ae9b66SAlan Carew #include <errno.h> 12e8ae9b66SAlan Carew #include <string.h> 13a63504a9SDavid Hunt #include <fcntl.h> 14e8ae9b66SAlan Carew #include <sys/types.h> 15e8ae9b66SAlan Carew #include <sys/epoll.h> 16e8ae9b66SAlan Carew #include <sys/queue.h> 17f14791a8SRory Sexton #include <sys/time.h> 18a63504a9SDavid Hunt #include <sys/socket.h> 19a63504a9SDavid Hunt #include <sys/select.h> 20a63504a9SDavid Hunt #ifdef USE_JANSSON 21a63504a9SDavid Hunt #include <jansson.h> 22a63504a9SDavid Hunt #else 23a63504a9SDavid Hunt #pragma message "Jansson dev libs unavailable, not including JSON parsing" 24a63504a9SDavid Hunt #endif 256723c0fcSBruce Richardson #include <rte_string_fns.h> 26e8ae9b66SAlan Carew #include <rte_log.h> 27e8ae9b66SAlan Carew #include <rte_memory.h> 28e8ae9b66SAlan Carew #include <rte_malloc.h> 29f14791a8SRory Sexton #include <rte_cycles.h> 30f14791a8SRory Sexton #include <rte_ethdev.h> 31a8d0d473SBruce Richardson #ifdef RTE_NET_I40E 32f14791a8SRory Sexton #include <rte_pmd_i40e.h> 33e4d028a0SDavid Hunt #endif 34f30a1bbdSSivaprasad Tummala #include <rte_power_cpufreq.h> 35*b462f273SDavid Marchand #include <rte_power_guest_channel.h> 36e8ae9b66SAlan Carew 37f14791a8SRory Sexton #include <libvirt/libvirt.h> 38e8ae9b66SAlan Carew #include "channel_monitor.h" 39e8ae9b66SAlan Carew #include "channel_manager.h" 40e8ae9b66SAlan Carew #include "power_manager.h" 41b89168efSDavid Hunt #include "oob_monitor.h" 42e8ae9b66SAlan Carew 43e8ae9b66SAlan Carew #define RTE_LOGTYPE_CHANNEL_MONITOR RTE_LOGTYPE_USER1 44e8ae9b66SAlan Carew 45e8ae9b66SAlan Carew #define MAX_EVENTS 256 46e8ae9b66SAlan Carew 47f14791a8SRory Sexton uint64_t vsi_pkt_count_prev[384]; 48f14791a8SRory Sexton uint64_t rdtsc_prev[384]; 49a63504a9SDavid Hunt #define MAX_JSON_STRING_LEN 1024 50a63504a9SDavid Hunt char json_data[MAX_JSON_STRING_LEN]; 51e8ae9b66SAlan Carew 52e4f66da3SDavid Hunt double time_period_ms = 1; 53e8ae9b66SAlan Carew static volatile unsigned run_loop = 1; 54e8ae9b66SAlan Carew static int global_event_fd; 55f14791a8SRory Sexton static unsigned int policy_is_set; 56e8ae9b66SAlan Carew static struct epoll_event *global_events_list; 57221e7026SMarcin Hajkowski static struct policy policies[RTE_MAX_LCORE]; 58e8ae9b66SAlan Carew 59a63504a9SDavid Hunt #ifdef USE_JANSSON 60a63504a9SDavid Hunt 61a63504a9SDavid Hunt union PFID { 626d13ea8eSOlivier Matz struct rte_ether_addr addr; 63a63504a9SDavid Hunt uint64_t pfid; 64a63504a9SDavid Hunt }; 65a63504a9SDavid Hunt 66a63504a9SDavid Hunt static int 676d13ea8eSOlivier Matz str_to_ether_addr(const char *a, struct rte_ether_addr *ether_addr) 68a63504a9SDavid Hunt { 69a63504a9SDavid Hunt int i; 70a63504a9SDavid Hunt char *end; 7135b2d13fSOlivier Matz unsigned long o[RTE_ETHER_ADDR_LEN]; 72a63504a9SDavid Hunt 73a63504a9SDavid Hunt i = 0; 74a63504a9SDavid Hunt do { 75a63504a9SDavid Hunt errno = 0; 76a63504a9SDavid Hunt o[i] = strtoul(a, &end, 16); 77a63504a9SDavid Hunt if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0)) 78a63504a9SDavid Hunt return -1; 79a63504a9SDavid Hunt a = end + 1; 80a63504a9SDavid Hunt } while (++i != RTE_DIM(o) / sizeof(o[0]) && end[0] != 0); 81a63504a9SDavid Hunt 82a63504a9SDavid Hunt /* Junk at the end of line */ 83a63504a9SDavid Hunt if (end[0] != 0) 84a63504a9SDavid Hunt return -1; 85a63504a9SDavid Hunt 86a63504a9SDavid Hunt /* Support the format XX:XX:XX:XX:XX:XX */ 8735b2d13fSOlivier Matz if (i == RTE_ETHER_ADDR_LEN) { 88a63504a9SDavid Hunt while (i-- != 0) { 89a63504a9SDavid Hunt if (o[i] > UINT8_MAX) 90a63504a9SDavid Hunt return -1; 91a63504a9SDavid Hunt ether_addr->addr_bytes[i] = (uint8_t)o[i]; 92a63504a9SDavid Hunt } 93a63504a9SDavid Hunt /* Support the format XXXX:XXXX:XXXX */ 9435b2d13fSOlivier Matz } else if (i == RTE_ETHER_ADDR_LEN / 2) { 95a63504a9SDavid Hunt while (i-- != 0) { 96a63504a9SDavid Hunt if (o[i] > UINT16_MAX) 97a63504a9SDavid Hunt return -1; 98a63504a9SDavid Hunt ether_addr->addr_bytes[i * 2] = 99a63504a9SDavid Hunt (uint8_t)(o[i] >> 8); 100a63504a9SDavid Hunt ether_addr->addr_bytes[i * 2 + 1] = 101a63504a9SDavid Hunt (uint8_t)(o[i] & 0xff); 102a63504a9SDavid Hunt } 103a63504a9SDavid Hunt /* unknown format */ 104a63504a9SDavid Hunt } else 105a63504a9SDavid Hunt return -1; 106a63504a9SDavid Hunt 107a63504a9SDavid Hunt return 0; 108a63504a9SDavid Hunt } 109a63504a9SDavid Hunt 110a63504a9SDavid Hunt static int 111bd5b6720SBruce Richardson set_policy_mac(struct rte_power_channel_packet *pkt, int idx, char *mac) 112a63504a9SDavid Hunt { 113a63504a9SDavid Hunt union PFID pfid; 114a63504a9SDavid Hunt int ret; 115a63504a9SDavid Hunt 116a63504a9SDavid Hunt /* Use port MAC address as the vfid */ 117a63504a9SDavid Hunt ret = str_to_ether_addr(mac, &pfid.addr); 118a63504a9SDavid Hunt 119a63504a9SDavid Hunt if (ret != 0) { 120a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 121a63504a9SDavid Hunt "Invalid mac address received in JSON\n"); 122a63504a9SDavid Hunt pkt->vfid[idx] = 0; 123a63504a9SDavid Hunt return -1; 124a63504a9SDavid Hunt } 125a63504a9SDavid Hunt 126a63504a9SDavid Hunt printf("Received MAC Address: %02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":" 127a63504a9SDavid Hunt "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n", 128a7db3afcSAman Deep Singh RTE_ETHER_ADDR_BYTES(&pfid.addr)); 129a63504a9SDavid Hunt 130a63504a9SDavid Hunt pkt->vfid[idx] = pfid.pfid; 131a63504a9SDavid Hunt return 0; 132a63504a9SDavid Hunt } 133a63504a9SDavid Hunt 134221e7026SMarcin Hajkowski static char* 135221e7026SMarcin Hajkowski get_resource_name_from_chn_path(const char *channel_path) 136221e7026SMarcin Hajkowski { 137221e7026SMarcin Hajkowski char *substr = NULL; 138221e7026SMarcin Hajkowski 139221e7026SMarcin Hajkowski substr = strstr(channel_path, CHANNEL_MGR_FIFO_PATTERN_NAME); 140221e7026SMarcin Hajkowski 141221e7026SMarcin Hajkowski return substr; 142221e7026SMarcin Hajkowski } 143a63504a9SDavid Hunt 144a63504a9SDavid Hunt static int 145221e7026SMarcin Hajkowski get_resource_id_from_vmname(const char *vm_name) 146221e7026SMarcin Hajkowski { 147221e7026SMarcin Hajkowski int result = -1; 148221e7026SMarcin Hajkowski int off = 0; 149221e7026SMarcin Hajkowski 150221e7026SMarcin Hajkowski if (vm_name == NULL) 151221e7026SMarcin Hajkowski return -1; 152221e7026SMarcin Hajkowski 153221e7026SMarcin Hajkowski while (vm_name[off] != '\0') { 154221e7026SMarcin Hajkowski if (isdigit(vm_name[off])) 155221e7026SMarcin Hajkowski break; 156221e7026SMarcin Hajkowski off++; 157221e7026SMarcin Hajkowski } 158221e7026SMarcin Hajkowski result = atoi(&vm_name[off]); 159221e7026SMarcin Hajkowski if ((result == 0) && (vm_name[off] != '0')) 160221e7026SMarcin Hajkowski return -1; 161221e7026SMarcin Hajkowski 162221e7026SMarcin Hajkowski return result; 163221e7026SMarcin Hajkowski } 164221e7026SMarcin Hajkowski 165221e7026SMarcin Hajkowski static int 166bd5b6720SBruce Richardson parse_json_to_pkt(json_t *element, struct rte_power_channel_packet *pkt, 167221e7026SMarcin Hajkowski const char *vm_name) 168a63504a9SDavid Hunt { 169a63504a9SDavid Hunt const char *key; 170a63504a9SDavid Hunt json_t *value; 171a63504a9SDavid Hunt int ret; 172221e7026SMarcin Hajkowski int resource_id; 173a63504a9SDavid Hunt 174bd5b6720SBruce Richardson memset(pkt, 0, sizeof(*pkt)); 175a63504a9SDavid Hunt 176a63504a9SDavid Hunt pkt->nb_mac_to_monitor = 0; 177a63504a9SDavid Hunt pkt->t_boost_status.tbEnabled = false; 17838d232b9SBruce Richardson pkt->workload = RTE_POWER_WL_LOW; 17938d232b9SBruce Richardson pkt->policy_to_use = RTE_POWER_POLICY_TIME; 18038d232b9SBruce Richardson pkt->command = RTE_POWER_PKT_POLICY; 18138d232b9SBruce Richardson pkt->core_type = RTE_POWER_CORE_TYPE_PHYSICAL; 182a63504a9SDavid Hunt 183221e7026SMarcin Hajkowski if (vm_name == NULL) { 184221e7026SMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, 185221e7026SMarcin Hajkowski "vm_name is NULL, request rejected !\n"); 186221e7026SMarcin Hajkowski return -1; 187221e7026SMarcin Hajkowski } 188221e7026SMarcin Hajkowski 189a63504a9SDavid Hunt json_object_foreach(element, key, value) { 190a63504a9SDavid Hunt if (!strcmp(key, "policy")) { 191a63504a9SDavid Hunt /* Recurse in to get the contents of profile */ 192221e7026SMarcin Hajkowski ret = parse_json_to_pkt(value, pkt, vm_name); 193a63504a9SDavid Hunt if (ret) 194a63504a9SDavid Hunt return ret; 195a63504a9SDavid Hunt } else if (!strcmp(key, "instruction")) { 196a63504a9SDavid Hunt /* Recurse in to get the contents of instruction */ 197221e7026SMarcin Hajkowski ret = parse_json_to_pkt(value, pkt, vm_name); 198a63504a9SDavid Hunt if (ret) 199a63504a9SDavid Hunt return ret; 200a63504a9SDavid Hunt } else if (!strcmp(key, "command")) { 201a63504a9SDavid Hunt char command[32]; 2026723c0fcSBruce Richardson strlcpy(command, json_string_value(value), 32); 203a63504a9SDavid Hunt if (!strcmp(command, "power")) { 20438d232b9SBruce Richardson pkt->command = RTE_POWER_CPU_POWER; 205a63504a9SDavid Hunt } else if (!strcmp(command, "create")) { 20638d232b9SBruce Richardson pkt->command = RTE_POWER_PKT_POLICY; 207a63504a9SDavid Hunt } else if (!strcmp(command, "destroy")) { 20838d232b9SBruce Richardson pkt->command = RTE_POWER_PKT_POLICY_REMOVE; 209a63504a9SDavid Hunt } else { 210a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 211a63504a9SDavid Hunt "Invalid command received in JSON\n"); 212a63504a9SDavid Hunt return -1; 213a63504a9SDavid Hunt } 214a63504a9SDavid Hunt } else if (!strcmp(key, "policy_type")) { 215a63504a9SDavid Hunt char command[32]; 2166723c0fcSBruce Richardson strlcpy(command, json_string_value(value), 32); 217a63504a9SDavid Hunt if (!strcmp(command, "TIME")) { 21838d232b9SBruce Richardson pkt->policy_to_use = 21938d232b9SBruce Richardson RTE_POWER_POLICY_TIME; 220a63504a9SDavid Hunt } else if (!strcmp(command, "TRAFFIC")) { 22138d232b9SBruce Richardson pkt->policy_to_use = 22238d232b9SBruce Richardson RTE_POWER_POLICY_TRAFFIC; 223a63504a9SDavid Hunt } else if (!strcmp(command, "WORKLOAD")) { 22438d232b9SBruce Richardson pkt->policy_to_use = 22538d232b9SBruce Richardson RTE_POWER_POLICY_WORKLOAD; 226a63504a9SDavid Hunt } else if (!strcmp(command, "BRANCH_RATIO")) { 22738d232b9SBruce Richardson pkt->policy_to_use = 22838d232b9SBruce Richardson RTE_POWER_POLICY_BRANCH_RATIO; 229a63504a9SDavid Hunt } else { 230a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 231a63504a9SDavid Hunt "Wrong policy_type received in JSON\n"); 232a63504a9SDavid Hunt return -1; 233a63504a9SDavid Hunt } 234a63504a9SDavid Hunt } else if (!strcmp(key, "workload")) { 235a63504a9SDavid Hunt char command[32]; 2366723c0fcSBruce Richardson strlcpy(command, json_string_value(value), 32); 237a63504a9SDavid Hunt if (!strcmp(command, "HIGH")) { 23838d232b9SBruce Richardson pkt->workload = RTE_POWER_WL_HIGH; 239a63504a9SDavid Hunt } else if (!strcmp(command, "MEDIUM")) { 24038d232b9SBruce Richardson pkt->workload = RTE_POWER_WL_MEDIUM; 241a63504a9SDavid Hunt } else if (!strcmp(command, "LOW")) { 24238d232b9SBruce Richardson pkt->workload = RTE_POWER_WL_LOW; 243a63504a9SDavid Hunt } else { 244a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 245a63504a9SDavid Hunt "Wrong workload received in JSON\n"); 246a63504a9SDavid Hunt return -1; 247a63504a9SDavid Hunt } 248a63504a9SDavid Hunt } else if (!strcmp(key, "busy_hours")) { 249a63504a9SDavid Hunt unsigned int i; 250a63504a9SDavid Hunt size_t size = json_array_size(value); 251a63504a9SDavid Hunt 252a63504a9SDavid Hunt for (i = 0; i < size; i++) { 253a63504a9SDavid Hunt int hour = (int)json_integer_value( 254a63504a9SDavid Hunt json_array_get(value, i)); 255a63504a9SDavid Hunt pkt->timer_policy.busy_hours[i] = hour; 256a63504a9SDavid Hunt } 257a63504a9SDavid Hunt } else if (!strcmp(key, "quiet_hours")) { 258a63504a9SDavid Hunt unsigned int i; 259a63504a9SDavid Hunt size_t size = json_array_size(value); 260a63504a9SDavid Hunt 261a63504a9SDavid Hunt for (i = 0; i < size; i++) { 262a63504a9SDavid Hunt int hour = (int)json_integer_value( 263a63504a9SDavid Hunt json_array_get(value, i)); 264a63504a9SDavid Hunt pkt->timer_policy.quiet_hours[i] = hour; 265a63504a9SDavid Hunt } 266a63504a9SDavid Hunt } else if (!strcmp(key, "mac_list")) { 267a63504a9SDavid Hunt unsigned int i; 268a63504a9SDavid Hunt size_t size = json_array_size(value); 269a63504a9SDavid Hunt 270a63504a9SDavid Hunt for (i = 0; i < size; i++) { 271a63504a9SDavid Hunt char mac[32]; 2726723c0fcSBruce Richardson strlcpy(mac, 2736723c0fcSBruce Richardson json_string_value(json_array_get(value, i)), 2746723c0fcSBruce Richardson 32); 275a63504a9SDavid Hunt set_policy_mac(pkt, i, mac); 276a63504a9SDavid Hunt } 277a63504a9SDavid Hunt pkt->nb_mac_to_monitor = size; 278a63504a9SDavid Hunt } else if (!strcmp(key, "avg_packet_thresh")) { 279a63504a9SDavid Hunt pkt->traffic_policy.avg_max_packet_thresh = 280a63504a9SDavid Hunt (uint32_t)json_integer_value(value); 281a63504a9SDavid Hunt } else if (!strcmp(key, "max_packet_thresh")) { 282a63504a9SDavid Hunt pkt->traffic_policy.max_max_packet_thresh = 283a63504a9SDavid Hunt (uint32_t)json_integer_value(value); 284a63504a9SDavid Hunt } else if (!strcmp(key, "unit")) { 285a63504a9SDavid Hunt char unit[32]; 2866723c0fcSBruce Richardson strlcpy(unit, json_string_value(value), 32); 287a63504a9SDavid Hunt if (!strcmp(unit, "SCALE_UP")) { 28838d232b9SBruce Richardson pkt->unit = RTE_POWER_SCALE_UP; 289a63504a9SDavid Hunt } else if (!strcmp(unit, "SCALE_DOWN")) { 29038d232b9SBruce Richardson pkt->unit = RTE_POWER_SCALE_DOWN; 291a63504a9SDavid Hunt } else if (!strcmp(unit, "SCALE_MAX")) { 29238d232b9SBruce Richardson pkt->unit = RTE_POWER_SCALE_MAX; 293a63504a9SDavid Hunt } else if (!strcmp(unit, "SCALE_MIN")) { 29438d232b9SBruce Richardson pkt->unit = RTE_POWER_SCALE_MIN; 295a63504a9SDavid Hunt } else if (!strcmp(unit, "ENABLE_TURBO")) { 29638d232b9SBruce Richardson pkt->unit = RTE_POWER_ENABLE_TURBO; 297a63504a9SDavid Hunt } else if (!strcmp(unit, "DISABLE_TURBO")) { 29838d232b9SBruce Richardson pkt->unit = RTE_POWER_DISABLE_TURBO; 299a63504a9SDavid Hunt } else { 300a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 301a63504a9SDavid Hunt "Invalid command received in JSON\n"); 302a63504a9SDavid Hunt return -1; 303a63504a9SDavid Hunt } 304a63504a9SDavid Hunt } else { 305a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 306a63504a9SDavid Hunt "Unknown key received in JSON string: %s\n", 307a63504a9SDavid Hunt key); 308a63504a9SDavid Hunt } 309221e7026SMarcin Hajkowski 310221e7026SMarcin Hajkowski resource_id = get_resource_id_from_vmname(vm_name); 311221e7026SMarcin Hajkowski if (resource_id < 0) { 312221e7026SMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, 313221e7026SMarcin Hajkowski "Could not get resource_id from vm_name:%s\n", 314221e7026SMarcin Hajkowski vm_name); 315221e7026SMarcin Hajkowski return -1; 316221e7026SMarcin Hajkowski } 31738d232b9SBruce Richardson strlcpy(pkt->vm_name, vm_name, RTE_POWER_VM_MAX_NAME_SZ); 318221e7026SMarcin Hajkowski pkt->resource_id = resource_id; 319a63504a9SDavid Hunt } 320a63504a9SDavid Hunt return 0; 321a63504a9SDavid Hunt } 322a63504a9SDavid Hunt #endif 323a63504a9SDavid Hunt 324e8ae9b66SAlan Carew void channel_monitor_exit(void) 325e8ae9b66SAlan Carew { 326e8ae9b66SAlan Carew run_loop = 0; 327e8ae9b66SAlan Carew rte_free(global_events_list); 328e8ae9b66SAlan Carew } 329e8ae9b66SAlan Carew 330f14791a8SRory Sexton static void 331f14791a8SRory Sexton core_share(int pNo, int z, int x, int t) 332f14791a8SRory Sexton { 333f14791a8SRory Sexton if (policies[pNo].core_share[z].pcpu == lvm_info[x].pcpus[t]) { 334f14791a8SRory Sexton if (strcmp(policies[pNo].pkt.vm_name, 335f14791a8SRory Sexton lvm_info[x].vm_name) != 0) { 336f14791a8SRory Sexton policies[pNo].core_share[z].status = 1; 337f14791a8SRory Sexton power_manager_scale_core_max( 338f14791a8SRory Sexton policies[pNo].core_share[z].pcpu); 339f14791a8SRory Sexton } 340f14791a8SRory Sexton } 341f14791a8SRory Sexton } 342f14791a8SRory Sexton 343f14791a8SRory Sexton static void 344f14791a8SRory Sexton core_share_status(int pNo) 345f14791a8SRory Sexton { 346f14791a8SRory Sexton 347395e97bfSDavid Hunt int noVms = 0, noVcpus = 0, z, x, t; 348f14791a8SRory Sexton 349f14791a8SRory Sexton get_all_vm(&noVms, &noVcpus); 350f14791a8SRory Sexton 351f14791a8SRory Sexton /* Reset Core Share Status. */ 352f14791a8SRory Sexton for (z = 0; z < noVcpus; z++) 353f14791a8SRory Sexton policies[pNo].core_share[z].status = 0; 354f14791a8SRory Sexton 355f14791a8SRory Sexton /* Foreach vcpu in a policy. */ 356f14791a8SRory Sexton for (z = 0; z < policies[pNo].pkt.num_vcpu; z++) { 357f14791a8SRory Sexton /* Foreach VM on the platform. */ 358f14791a8SRory Sexton for (x = 0; x < noVms; x++) { 359f14791a8SRory Sexton /* Foreach vcpu of VMs on platform. */ 360f14791a8SRory Sexton for (t = 0; t < lvm_info[x].num_cpus; t++) 361f14791a8SRory Sexton core_share(pNo, z, x, t); 362f14791a8SRory Sexton } 363f14791a8SRory Sexton } 364f14791a8SRory Sexton } 365f14791a8SRory Sexton 3663618326fSDavid Hunt 3673618326fSDavid Hunt static int 3683618326fSDavid Hunt pcpu_monitor(struct policy *pol, struct core_info *ci, int pcpu, int count) 3693618326fSDavid Hunt { 3703618326fSDavid Hunt int ret = 0; 3713618326fSDavid Hunt 37238d232b9SBruce Richardson if (pol->pkt.policy_to_use == RTE_POWER_POLICY_BRANCH_RATIO) { 3733618326fSDavid Hunt ci->cd[pcpu].oob_enabled = 1; 3743618326fSDavid Hunt ret = add_core_to_monitor(pcpu); 3753618326fSDavid Hunt if (ret == 0) 3763618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 3773618326fSDavid Hunt "Monitoring pcpu %d OOB for %s\n", 3783618326fSDavid Hunt pcpu, pol->pkt.vm_name); 3793618326fSDavid Hunt else 3803618326fSDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 3813618326fSDavid Hunt "Error monitoring pcpu %d OOB for %s\n", 3823618326fSDavid Hunt pcpu, pol->pkt.vm_name); 3833618326fSDavid Hunt 3843618326fSDavid Hunt } else { 3853618326fSDavid Hunt pol->core_share[count].pcpu = pcpu; 3863618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 3873618326fSDavid Hunt "Monitoring pcpu %d for %s\n", 3883618326fSDavid Hunt pcpu, pol->pkt.vm_name); 3893618326fSDavid Hunt } 3903618326fSDavid Hunt return ret; 3913618326fSDavid Hunt } 3923618326fSDavid Hunt 393f14791a8SRory Sexton static void 394f14791a8SRory Sexton get_pcpu_to_control(struct policy *pol) 395f14791a8SRory Sexton { 396f14791a8SRory Sexton 397f14791a8SRory Sexton /* Convert vcpu to pcpu. */ 398f14791a8SRory Sexton struct vm_info info; 399f14791a8SRory Sexton int pcpu, count; 400b89168efSDavid Hunt struct core_info *ci; 401b89168efSDavid Hunt 402b89168efSDavid Hunt ci = get_core_info(); 403f14791a8SRory Sexton 404ce4a2766SDavid Hunt RTE_LOG(DEBUG, CHANNEL_MONITOR, 4053618326fSDavid Hunt "Looking for pcpu for %s\n", pol->pkt.vm_name); 4063618326fSDavid Hunt 4073618326fSDavid Hunt /* 4083618326fSDavid Hunt * So now that we're handling virtual and physical cores, we need to 4097be78d02SJosh Soref * differentiate between them when adding them to the branch monitor. 4103618326fSDavid Hunt * Virtual cores need to be converted to physical cores. 4113618326fSDavid Hunt */ 41238d232b9SBruce Richardson if (pol->pkt.core_type == RTE_POWER_CORE_TYPE_VIRTUAL) { 4133618326fSDavid Hunt /* 4143618326fSDavid Hunt * If the cores in the policy are virtual, we need to map them 4153618326fSDavid Hunt * to physical core. We look up the vm info and use that for 4163618326fSDavid Hunt * the mapping. 4173618326fSDavid Hunt */ 418f14791a8SRory Sexton get_info_vm(pol->pkt.vm_name, &info); 419f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 4205776b7a3SDavid Hunt pcpu = info.pcpu_map[pol->pkt.vcpu_to_control[count]]; 4213618326fSDavid Hunt pcpu_monitor(pol, ci, pcpu, count); 4223618326fSDavid Hunt } 423b89168efSDavid Hunt } else { 4243618326fSDavid Hunt /* 4253618326fSDavid Hunt * If the cores in the policy are physical, we just use 4263618326fSDavid Hunt * those core id's directly. 4273618326fSDavid Hunt */ 4283618326fSDavid Hunt for (count = 0; count < pol->pkt.num_vcpu; count++) { 4293618326fSDavid Hunt pcpu = pol->pkt.vcpu_to_control[count]; 4303618326fSDavid Hunt pcpu_monitor(pol, ci, pcpu, count); 431f14791a8SRory Sexton } 432f14791a8SRory Sexton } 433f14791a8SRory Sexton } 434f14791a8SRory Sexton 435f14791a8SRory Sexton static int 436f14791a8SRory Sexton get_pfid(struct policy *pol) 437f14791a8SRory Sexton { 438f14791a8SRory Sexton 4398728ccf3SThomas Monjalon int i, x, ret = 0; 440f14791a8SRory Sexton 441f14791a8SRory Sexton for (i = 0; i < pol->pkt.nb_mac_to_monitor; i++) { 442f14791a8SRory Sexton 4438728ccf3SThomas Monjalon RTE_ETH_FOREACH_DEV(x) { 444a8d0d473SBruce Richardson #ifdef RTE_NET_I40E 445f14791a8SRory Sexton ret = rte_pmd_i40e_query_vfid_by_mac(x, 4466d13ea8eSOlivier Matz (struct rte_ether_addr *)&(pol->pkt.vfid[i])); 447e4d028a0SDavid Hunt #else 448e4d028a0SDavid Hunt ret = -ENOTSUP; 449e4d028a0SDavid Hunt #endif 450f14791a8SRory Sexton if (ret != -EINVAL) { 451f14791a8SRory Sexton pol->port[i] = x; 452f14791a8SRory Sexton break; 453f14791a8SRory Sexton } 454f14791a8SRory Sexton } 455f14791a8SRory Sexton if (ret == -EINVAL || ret == -ENOTSUP || ret == ENODEV) { 456f14791a8SRory Sexton RTE_LOG(INFO, CHANNEL_MONITOR, 457f14791a8SRory Sexton "Error with Policy. MAC not found on " 458f14791a8SRory Sexton "attached ports "); 459f14791a8SRory Sexton pol->enabled = 0; 460f14791a8SRory Sexton return ret; 461f14791a8SRory Sexton } 462f14791a8SRory Sexton pol->pfid[i] = ret; 463f14791a8SRory Sexton } 464f14791a8SRory Sexton return 1; 465f14791a8SRory Sexton } 466f14791a8SRory Sexton 467f14791a8SRory Sexton static int 468bd5b6720SBruce Richardson update_policy(struct rte_power_channel_packet *pkt) 469f14791a8SRory Sexton { 470f14791a8SRory Sexton 471f14791a8SRory Sexton unsigned int updated = 0; 472221e7026SMarcin Hajkowski unsigned int i; 473f14791a8SRory Sexton 4743618326fSDavid Hunt 4753618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 4763618326fSDavid Hunt "Applying policy for %s\n", pkt->vm_name); 4773618326fSDavid Hunt 478221e7026SMarcin Hajkowski for (i = 0; i < RTE_DIM(policies); i++) { 479f14791a8SRory Sexton if (strcmp(policies[i].pkt.vm_name, pkt->vm_name) == 0) { 4803618326fSDavid Hunt /* Copy the contents of *pkt into the policy.pkt */ 481f14791a8SRory Sexton policies[i].pkt = *pkt; 482f14791a8SRory Sexton get_pcpu_to_control(&policies[i]); 483236e164bSLukasz Krakowiak /* Check Eth dev only for Traffic policy */ 48438d232b9SBruce Richardson if (policies[i].pkt.policy_to_use == 48538d232b9SBruce Richardson RTE_POWER_POLICY_TRAFFIC) { 4861b897991SLukasz Krakowiak if (get_pfid(&policies[i]) < 0) { 487f14791a8SRory Sexton updated = 1; 488f14791a8SRory Sexton break; 489f14791a8SRory Sexton } 490236e164bSLukasz Krakowiak } 491f14791a8SRory Sexton core_share_status(i); 492f14791a8SRory Sexton policies[i].enabled = 1; 493f14791a8SRory Sexton updated = 1; 494f14791a8SRory Sexton } 495f14791a8SRory Sexton } 496f14791a8SRory Sexton if (!updated) { 497221e7026SMarcin Hajkowski for (i = 0; i < RTE_DIM(policies); i++) { 498f14791a8SRory Sexton if (policies[i].enabled == 0) { 499f14791a8SRory Sexton policies[i].pkt = *pkt; 500f14791a8SRory Sexton get_pcpu_to_control(&policies[i]); 501236e164bSLukasz Krakowiak /* Check Eth dev only for Traffic policy */ 50238d232b9SBruce Richardson if (policies[i].pkt.policy_to_use == 50338d232b9SBruce Richardson RTE_POWER_POLICY_TRAFFIC) { 504236e164bSLukasz Krakowiak if (get_pfid(&policies[i]) < 0) { 505236e164bSLukasz Krakowiak updated = 1; 506f14791a8SRory Sexton break; 507236e164bSLukasz Krakowiak } 508236e164bSLukasz Krakowiak } 509f14791a8SRory Sexton core_share_status(i); 510f14791a8SRory Sexton policies[i].enabled = 1; 511f14791a8SRory Sexton break; 512f14791a8SRory Sexton } 513f14791a8SRory Sexton } 514f14791a8SRory Sexton } 515f14791a8SRory Sexton return 0; 516f14791a8SRory Sexton } 517f14791a8SRory Sexton 5183618326fSDavid Hunt static int 519bd5b6720SBruce Richardson remove_policy(struct rte_power_channel_packet *pkt __rte_unused) 5203618326fSDavid Hunt { 521221e7026SMarcin Hajkowski unsigned int i; 5223618326fSDavid Hunt 5233618326fSDavid Hunt /* 5243618326fSDavid Hunt * Disabling the policy is simply a case of setting 5253618326fSDavid Hunt * enabled to 0 5263618326fSDavid Hunt */ 527221e7026SMarcin Hajkowski for (i = 0; i < RTE_DIM(policies); i++) { 5283618326fSDavid Hunt if (strcmp(policies[i].pkt.vm_name, pkt->vm_name) == 0) { 5293618326fSDavid Hunt policies[i].enabled = 0; 5303618326fSDavid Hunt return 0; 5313618326fSDavid Hunt } 5323618326fSDavid Hunt } 5333618326fSDavid Hunt return -1; 5343618326fSDavid Hunt } 5353618326fSDavid Hunt 536f14791a8SRory Sexton static uint64_t 537f14791a8SRory Sexton get_pkt_diff(struct policy *pol) 538f14791a8SRory Sexton { 539f14791a8SRory Sexton 540f14791a8SRory Sexton uint64_t vsi_pkt_count, 541f14791a8SRory Sexton vsi_pkt_total = 0, 542f14791a8SRory Sexton vsi_pkt_count_prev_total = 0; 543f14791a8SRory Sexton double rdtsc_curr, rdtsc_diff, diff; 544f14791a8SRory Sexton int x; 545a8d0d473SBruce Richardson #ifdef RTE_NET_I40E 546f14791a8SRory Sexton struct rte_eth_stats vf_stats; 547e4d028a0SDavid Hunt #endif 548f14791a8SRory Sexton 549f14791a8SRory Sexton for (x = 0; x < pol->pkt.nb_mac_to_monitor; x++) { 550f14791a8SRory Sexton 551a8d0d473SBruce Richardson #ifdef RTE_NET_I40E 552f14791a8SRory Sexton /*Read vsi stats*/ 553f14791a8SRory Sexton if (rte_pmd_i40e_get_vf_stats(x, pol->pfid[x], &vf_stats) == 0) 554f14791a8SRory Sexton vsi_pkt_count = vf_stats.ipackets; 555f14791a8SRory Sexton else 556f14791a8SRory Sexton vsi_pkt_count = -1; 557e4d028a0SDavid Hunt #else 558e4d028a0SDavid Hunt vsi_pkt_count = -1; 559e4d028a0SDavid Hunt #endif 560f14791a8SRory Sexton 561f14791a8SRory Sexton vsi_pkt_total += vsi_pkt_count; 562f14791a8SRory Sexton 563f14791a8SRory Sexton vsi_pkt_count_prev_total += vsi_pkt_count_prev[pol->pfid[x]]; 564f14791a8SRory Sexton vsi_pkt_count_prev[pol->pfid[x]] = vsi_pkt_count; 565f14791a8SRory Sexton } 566f14791a8SRory Sexton 567f14791a8SRory Sexton rdtsc_curr = rte_rdtsc_precise(); 568f14791a8SRory Sexton rdtsc_diff = rdtsc_curr - rdtsc_prev[pol->pfid[x-1]]; 569f14791a8SRory Sexton rdtsc_prev[pol->pfid[x-1]] = rdtsc_curr; 570f14791a8SRory Sexton 571f14791a8SRory Sexton diff = (vsi_pkt_total - vsi_pkt_count_prev_total) * 572f14791a8SRory Sexton ((double)rte_get_tsc_hz() / rdtsc_diff); 573f14791a8SRory Sexton 574f14791a8SRory Sexton return diff; 575f14791a8SRory Sexton } 576f14791a8SRory Sexton 577f14791a8SRory Sexton static void 578f14791a8SRory Sexton apply_traffic_profile(struct policy *pol) 579f14791a8SRory Sexton { 580f14791a8SRory Sexton 581f14791a8SRory Sexton int count; 582f14791a8SRory Sexton uint64_t diff = 0; 583f14791a8SRory Sexton 584f14791a8SRory Sexton diff = get_pkt_diff(pol); 585f14791a8SRory Sexton 586f14791a8SRory Sexton if (diff >= (pol->pkt.traffic_policy.max_max_packet_thresh)) { 587f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 588f14791a8SRory Sexton if (pol->core_share[count].status != 1) 589f14791a8SRory Sexton power_manager_scale_core_max( 590f14791a8SRory Sexton pol->core_share[count].pcpu); 591f14791a8SRory Sexton } 592f14791a8SRory Sexton } else if (diff >= (pol->pkt.traffic_policy.avg_max_packet_thresh)) { 593f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 594f14791a8SRory Sexton if (pol->core_share[count].status != 1) 595f14791a8SRory Sexton power_manager_scale_core_med( 596f14791a8SRory Sexton pol->core_share[count].pcpu); 597f14791a8SRory Sexton } 598f14791a8SRory Sexton } else if (diff < (pol->pkt.traffic_policy.avg_max_packet_thresh)) { 599f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 600f14791a8SRory Sexton if (pol->core_share[count].status != 1) 601f14791a8SRory Sexton power_manager_scale_core_min( 602f14791a8SRory Sexton pol->core_share[count].pcpu); 603f14791a8SRory Sexton } 604f14791a8SRory Sexton } 605f14791a8SRory Sexton } 606f14791a8SRory Sexton 607f14791a8SRory Sexton static void 608f14791a8SRory Sexton apply_time_profile(struct policy *pol) 609f14791a8SRory Sexton { 610f14791a8SRory Sexton 611f14791a8SRory Sexton int count, x; 612f14791a8SRory Sexton struct timeval tv; 613f14791a8SRory Sexton struct tm *ptm; 614f14791a8SRory Sexton char time_string[40]; 615f14791a8SRory Sexton 616f14791a8SRory Sexton /* Obtain the time of day, and convert it to a tm struct. */ 617f14791a8SRory Sexton gettimeofday(&tv, NULL); 618f14791a8SRory Sexton ptm = localtime(&tv.tv_sec); 619f14791a8SRory Sexton /* Format the date and time, down to a single second. */ 620f14791a8SRory Sexton strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", ptm); 621f14791a8SRory Sexton 62238d232b9SBruce Richardson for (x = 0; x < RTE_POWER_HOURS_PER_DAY; x++) { 623f14791a8SRory Sexton 624f14791a8SRory Sexton if (ptm->tm_hour == pol->pkt.timer_policy.busy_hours[x]) { 625f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 626f14791a8SRory Sexton if (pol->core_share[count].status != 1) { 627f14791a8SRory Sexton power_manager_scale_core_max( 628f14791a8SRory Sexton pol->core_share[count].pcpu); 629f14791a8SRory Sexton } 630f14791a8SRory Sexton } 631f14791a8SRory Sexton break; 632f14791a8SRory Sexton } else if (ptm->tm_hour == 633f14791a8SRory Sexton pol->pkt.timer_policy.quiet_hours[x]) { 634f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 635f14791a8SRory Sexton if (pol->core_share[count].status != 1) { 636f14791a8SRory Sexton power_manager_scale_core_min( 637f14791a8SRory Sexton pol->core_share[count].pcpu); 638f14791a8SRory Sexton } 639f14791a8SRory Sexton } 640f14791a8SRory Sexton break; 641f14791a8SRory Sexton } else if (ptm->tm_hour == 642f14791a8SRory Sexton pol->pkt.timer_policy.hours_to_use_traffic_profile[x]) { 643f14791a8SRory Sexton apply_traffic_profile(pol); 644f14791a8SRory Sexton break; 645f14791a8SRory Sexton } 646f14791a8SRory Sexton } 647f14791a8SRory Sexton } 648f14791a8SRory Sexton 649f14791a8SRory Sexton static void 650f14791a8SRory Sexton apply_workload_profile(struct policy *pol) 651f14791a8SRory Sexton { 652f14791a8SRory Sexton 653f14791a8SRory Sexton int count; 654f14791a8SRory Sexton 65538d232b9SBruce Richardson if (pol->pkt.workload == RTE_POWER_WL_HIGH) { 656f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 657f14791a8SRory Sexton if (pol->core_share[count].status != 1) 658f14791a8SRory Sexton power_manager_scale_core_max( 659f14791a8SRory Sexton pol->core_share[count].pcpu); 660f14791a8SRory Sexton } 66138d232b9SBruce Richardson } else if (pol->pkt.workload == RTE_POWER_WL_MEDIUM) { 662f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 663f14791a8SRory Sexton if (pol->core_share[count].status != 1) 664f14791a8SRory Sexton power_manager_scale_core_med( 665f14791a8SRory Sexton pol->core_share[count].pcpu); 666f14791a8SRory Sexton } 66738d232b9SBruce Richardson } else if (pol->pkt.workload == RTE_POWER_WL_LOW) { 668f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 669f14791a8SRory Sexton if (pol->core_share[count].status != 1) 670f14791a8SRory Sexton power_manager_scale_core_min( 671f14791a8SRory Sexton pol->core_share[count].pcpu); 672f14791a8SRory Sexton } 673f14791a8SRory Sexton } 674f14791a8SRory Sexton } 675f14791a8SRory Sexton 676f14791a8SRory Sexton static void 677f14791a8SRory Sexton apply_policy(struct policy *pol) 678f14791a8SRory Sexton { 679f14791a8SRory Sexton 680bd5b6720SBruce Richardson struct rte_power_channel_packet *pkt = &pol->pkt; 681f14791a8SRory Sexton 682f14791a8SRory Sexton /*Check policy to use*/ 68338d232b9SBruce Richardson if (pkt->policy_to_use == RTE_POWER_POLICY_TRAFFIC) 684f14791a8SRory Sexton apply_traffic_profile(pol); 68538d232b9SBruce Richardson else if (pkt->policy_to_use == RTE_POWER_POLICY_TIME) 686f14791a8SRory Sexton apply_time_profile(pol); 68738d232b9SBruce Richardson else if (pkt->policy_to_use == RTE_POWER_POLICY_WORKLOAD) 688f14791a8SRory Sexton apply_workload_profile(pol); 689f14791a8SRory Sexton } 690f14791a8SRory Sexton 691e8ae9b66SAlan Carew static int 692db91b52bSMarcin Hajkowski write_binary_packet(void *buffer, 693db91b52bSMarcin Hajkowski size_t buffer_len, 694db91b52bSMarcin Hajkowski struct channel_info *chan_info) 6950de94bcaSMarcin Hajkowski { 696db91b52bSMarcin Hajkowski int ret; 697db91b52bSMarcin Hajkowski 698db91b52bSMarcin Hajkowski if (buffer_len == 0 || buffer == NULL) 699db91b52bSMarcin Hajkowski return -1; 7000de94bcaSMarcin Hajkowski 7010de94bcaSMarcin Hajkowski if (chan_info->fd < 0) { 7020de94bcaSMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, "Channel is not connected\n"); 7030de94bcaSMarcin Hajkowski return -1; 7040de94bcaSMarcin Hajkowski } 7050de94bcaSMarcin Hajkowski 7060de94bcaSMarcin Hajkowski while (buffer_len > 0) { 7070de94bcaSMarcin Hajkowski ret = write(chan_info->fd, buffer, buffer_len); 7080de94bcaSMarcin Hajkowski if (ret == -1) { 7090de94bcaSMarcin Hajkowski if (errno == EINTR) 7100de94bcaSMarcin Hajkowski continue; 7110de94bcaSMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, "Write function failed due to %s.\n", 7120de94bcaSMarcin Hajkowski strerror(errno)); 7130de94bcaSMarcin Hajkowski return -1; 7140de94bcaSMarcin Hajkowski } 7150de94bcaSMarcin Hajkowski buffer = (char *)buffer + ret; 7160de94bcaSMarcin Hajkowski buffer_len -= ret; 7170de94bcaSMarcin Hajkowski } 7180de94bcaSMarcin Hajkowski return 0; 7190de94bcaSMarcin Hajkowski } 7200de94bcaSMarcin Hajkowski 7210de94bcaSMarcin Hajkowski static int 722bd5b6720SBruce Richardson send_freq(struct rte_power_channel_packet *pkt, 723db91b52bSMarcin Hajkowski struct channel_info *chan_info, 724db91b52bSMarcin Hajkowski bool freq_list) 725db91b52bSMarcin Hajkowski { 726db91b52bSMarcin Hajkowski unsigned int vcore_id = pkt->resource_id; 727bd5b6720SBruce Richardson struct rte_power_channel_packet_freq_list channel_pkt_freq_list; 728db91b52bSMarcin Hajkowski struct vm_info info; 729db91b52bSMarcin Hajkowski 730db91b52bSMarcin Hajkowski if (get_info_vm(pkt->vm_name, &info) != 0) 731db91b52bSMarcin Hajkowski return -1; 732db91b52bSMarcin Hajkowski 73338d232b9SBruce Richardson if (!freq_list && vcore_id >= RTE_POWER_MAX_VCPU_PER_VM) 734db91b52bSMarcin Hajkowski return -1; 735db91b52bSMarcin Hajkowski 7361deb502eSMarcin Hajkowski if (!info.allow_query) 7371deb502eSMarcin Hajkowski return -1; 7381deb502eSMarcin Hajkowski 73938d232b9SBruce Richardson channel_pkt_freq_list.command = RTE_POWER_FREQ_LIST; 740db91b52bSMarcin Hajkowski channel_pkt_freq_list.num_vcpu = info.num_vcpus; 741db91b52bSMarcin Hajkowski 742db91b52bSMarcin Hajkowski if (freq_list) { 743db91b52bSMarcin Hajkowski unsigned int i; 744db91b52bSMarcin Hajkowski for (i = 0; i < info.num_vcpus; i++) 745db91b52bSMarcin Hajkowski channel_pkt_freq_list.freq_list[i] = 746db91b52bSMarcin Hajkowski power_manager_get_current_frequency(info.pcpu_map[i]); 747db91b52bSMarcin Hajkowski } else { 748db91b52bSMarcin Hajkowski channel_pkt_freq_list.freq_list[vcore_id] = 749db91b52bSMarcin Hajkowski power_manager_get_current_frequency(info.pcpu_map[vcore_id]); 750db91b52bSMarcin Hajkowski } 751db91b52bSMarcin Hajkowski 752db91b52bSMarcin Hajkowski return write_binary_packet(&channel_pkt_freq_list, 753db91b52bSMarcin Hajkowski sizeof(channel_pkt_freq_list), 754db91b52bSMarcin Hajkowski chan_info); 755db91b52bSMarcin Hajkowski } 756db91b52bSMarcin Hajkowski 757db91b52bSMarcin Hajkowski static int 758bd5b6720SBruce Richardson send_capabilities(struct rte_power_channel_packet *pkt, 75999898ac5SMarcin Hajkowski struct channel_info *chan_info, 76099898ac5SMarcin Hajkowski bool list_requested) 76199898ac5SMarcin Hajkowski { 76299898ac5SMarcin Hajkowski unsigned int vcore_id = pkt->resource_id; 763bd5b6720SBruce Richardson struct rte_power_channel_packet_caps_list channel_pkt_caps_list; 76499898ac5SMarcin Hajkowski struct vm_info info; 76599898ac5SMarcin Hajkowski struct rte_power_core_capabilities caps; 76699898ac5SMarcin Hajkowski int ret; 76799898ac5SMarcin Hajkowski 76899898ac5SMarcin Hajkowski if (get_info_vm(pkt->vm_name, &info) != 0) 76999898ac5SMarcin Hajkowski return -1; 77099898ac5SMarcin Hajkowski 77138d232b9SBruce Richardson if (!list_requested && vcore_id >= RTE_POWER_MAX_VCPU_PER_VM) 77299898ac5SMarcin Hajkowski return -1; 77399898ac5SMarcin Hajkowski 77499898ac5SMarcin Hajkowski if (!info.allow_query) 77599898ac5SMarcin Hajkowski return -1; 77699898ac5SMarcin Hajkowski 77738d232b9SBruce Richardson channel_pkt_caps_list.command = RTE_POWER_CAPS_LIST; 77899898ac5SMarcin Hajkowski channel_pkt_caps_list.num_vcpu = info.num_vcpus; 77999898ac5SMarcin Hajkowski 78099898ac5SMarcin Hajkowski if (list_requested) { 78199898ac5SMarcin Hajkowski unsigned int i; 78299898ac5SMarcin Hajkowski for (i = 0; i < info.num_vcpus; i++) { 78399898ac5SMarcin Hajkowski ret = rte_power_get_capabilities(info.pcpu_map[i], 78499898ac5SMarcin Hajkowski &caps); 78599898ac5SMarcin Hajkowski if (ret == 0) { 78699898ac5SMarcin Hajkowski channel_pkt_caps_list.turbo[i] = 78799898ac5SMarcin Hajkowski caps.turbo; 78899898ac5SMarcin Hajkowski channel_pkt_caps_list.priority[i] = 78999898ac5SMarcin Hajkowski caps.priority; 79099898ac5SMarcin Hajkowski } else 79199898ac5SMarcin Hajkowski return -1; 79299898ac5SMarcin Hajkowski 79399898ac5SMarcin Hajkowski } 79499898ac5SMarcin Hajkowski } else { 79599898ac5SMarcin Hajkowski ret = rte_power_get_capabilities(info.pcpu_map[vcore_id], 79699898ac5SMarcin Hajkowski &caps); 79799898ac5SMarcin Hajkowski if (ret == 0) { 79899898ac5SMarcin Hajkowski channel_pkt_caps_list.turbo[vcore_id] = 79999898ac5SMarcin Hajkowski caps.turbo; 80099898ac5SMarcin Hajkowski channel_pkt_caps_list.priority[vcore_id] = 80199898ac5SMarcin Hajkowski caps.priority; 80299898ac5SMarcin Hajkowski } else 80399898ac5SMarcin Hajkowski return -1; 80499898ac5SMarcin Hajkowski } 80599898ac5SMarcin Hajkowski 80699898ac5SMarcin Hajkowski return write_binary_packet(&channel_pkt_caps_list, 80799898ac5SMarcin Hajkowski sizeof(channel_pkt_caps_list), 80899898ac5SMarcin Hajkowski chan_info); 80999898ac5SMarcin Hajkowski } 81099898ac5SMarcin Hajkowski 81199898ac5SMarcin Hajkowski static int 812bd5b6720SBruce Richardson send_ack_for_received_cmd(struct rte_power_channel_packet *pkt, 8130de94bcaSMarcin Hajkowski struct channel_info *chan_info, 8140de94bcaSMarcin Hajkowski uint32_t command) 8150de94bcaSMarcin Hajkowski { 8160de94bcaSMarcin Hajkowski pkt->command = command; 817db91b52bSMarcin Hajkowski return write_binary_packet(pkt, 818bd5b6720SBruce Richardson sizeof(*pkt), 819db91b52bSMarcin Hajkowski chan_info); 8200de94bcaSMarcin Hajkowski } 8210de94bcaSMarcin Hajkowski 8220de94bcaSMarcin Hajkowski static int 823bd5b6720SBruce Richardson process_request(struct rte_power_channel_packet *pkt, 824bd5b6720SBruce Richardson struct channel_info *chan_info) 825e8ae9b66SAlan Carew { 826d7b713d0SLukasz Krakowiak int ret; 827d7b713d0SLukasz Krakowiak 828e8ae9b66SAlan Carew if (chan_info == NULL) 829e8ae9b66SAlan Carew return -1; 830e8ae9b66SAlan Carew 83114215f34SJoyce Kong uint32_t channel_connected = CHANNEL_MGR_CHANNEL_CONNECTED; 83292e68d9cSTyler Retzlaff if (rte_atomic_compare_exchange_strong_explicit(&(chan_info->status), &channel_connected, 83392e68d9cSTyler Retzlaff CHANNEL_MGR_CHANNEL_PROCESSING, rte_memory_order_relaxed, 83492e68d9cSTyler Retzlaff rte_memory_order_relaxed) == 0) 835e8ae9b66SAlan Carew return -1; 836e8ae9b66SAlan Carew 83738d232b9SBruce Richardson if (pkt->command == RTE_POWER_CPU_POWER) { 8385776b7a3SDavid Hunt unsigned int core_num; 839e8ae9b66SAlan Carew 84038d232b9SBruce Richardson if (pkt->core_type == RTE_POWER_CORE_TYPE_VIRTUAL) 8415776b7a3SDavid Hunt core_num = get_pcpu(chan_info, pkt->resource_id); 842d38e6a6aSDavid Hunt else 843d38e6a6aSDavid Hunt core_num = pkt->resource_id; 844e8ae9b66SAlan Carew 845d7b713d0SLukasz Krakowiak RTE_LOG(DEBUG, CHANNEL_MONITOR, "Processing requested cmd for cpu:%d\n", 846d7b713d0SLukasz Krakowiak core_num); 847d7b713d0SLukasz Krakowiak 8480de94bcaSMarcin Hajkowski int scale_res; 849db91b52bSMarcin Hajkowski bool valid_unit = true; 8500de94bcaSMarcin Hajkowski 851e8ae9b66SAlan Carew switch (pkt->unit) { 85238d232b9SBruce Richardson case(RTE_POWER_SCALE_MIN): 8530de94bcaSMarcin Hajkowski scale_res = power_manager_scale_core_min(core_num); 854e8ae9b66SAlan Carew break; 85538d232b9SBruce Richardson case(RTE_POWER_SCALE_MAX): 8560de94bcaSMarcin Hajkowski scale_res = power_manager_scale_core_max(core_num); 857e8ae9b66SAlan Carew break; 85838d232b9SBruce Richardson case(RTE_POWER_SCALE_DOWN): 8590de94bcaSMarcin Hajkowski scale_res = power_manager_scale_core_down(core_num); 860e8ae9b66SAlan Carew break; 86138d232b9SBruce Richardson case(RTE_POWER_SCALE_UP): 8620de94bcaSMarcin Hajkowski scale_res = power_manager_scale_core_up(core_num); 863e8ae9b66SAlan Carew break; 86438d232b9SBruce Richardson case(RTE_POWER_ENABLE_TURBO): 8650de94bcaSMarcin Hajkowski scale_res = power_manager_enable_turbo_core(core_num); 866567997b9SDavid Hunt break; 86738d232b9SBruce Richardson case(RTE_POWER_DISABLE_TURBO): 8680de94bcaSMarcin Hajkowski scale_res = power_manager_disable_turbo_core(core_num); 869567997b9SDavid Hunt break; 870e8ae9b66SAlan Carew default: 8710de94bcaSMarcin Hajkowski valid_unit = false; 872e8ae9b66SAlan Carew break; 873e8ae9b66SAlan Carew } 8740de94bcaSMarcin Hajkowski 8750de94bcaSMarcin Hajkowski if (valid_unit) { 8760de94bcaSMarcin Hajkowski ret = send_ack_for_received_cmd(pkt, 8770de94bcaSMarcin Hajkowski chan_info, 8781e3ec03dSDavid Hunt scale_res >= 0 ? 87938d232b9SBruce Richardson RTE_POWER_CMD_ACK : 88038d232b9SBruce Richardson RTE_POWER_CMD_NACK); 8810de94bcaSMarcin Hajkowski if (ret < 0) 882db91b52bSMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, "Error during sending ack command.\n"); 8830de94bcaSMarcin Hajkowski } else 884db91b52bSMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, "Unexpected unit type.\n"); 8850de94bcaSMarcin Hajkowski 886e8ae9b66SAlan Carew } 887f14791a8SRory Sexton 88838d232b9SBruce Richardson if (pkt->command == RTE_POWER_PKT_POLICY) { 889ce4a2766SDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, "Processing policy request %s\n", 890ce4a2766SDavid Hunt pkt->vm_name); 8910de94bcaSMarcin Hajkowski int ret = send_ack_for_received_cmd(pkt, 8920de94bcaSMarcin Hajkowski chan_info, 89338d232b9SBruce Richardson RTE_POWER_CMD_ACK); 8940de94bcaSMarcin Hajkowski if (ret < 0) 895db91b52bSMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, "Error during sending ack command.\n"); 896f14791a8SRory Sexton update_policy(pkt); 897f14791a8SRory Sexton policy_is_set = 1; 898f14791a8SRory Sexton } 899f14791a8SRory Sexton 90038d232b9SBruce Richardson if (pkt->command == RTE_POWER_PKT_POLICY_REMOVE) { 901d7b713d0SLukasz Krakowiak ret = remove_policy(pkt); 902d7b713d0SLukasz Krakowiak if (ret == 0) 9033618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 904d7b713d0SLukasz Krakowiak "Removed policy %s\n", pkt->vm_name); 905d7b713d0SLukasz Krakowiak else 906d7b713d0SLukasz Krakowiak RTE_LOG(INFO, CHANNEL_MONITOR, 907d7b713d0SLukasz Krakowiak "Policy %s does not exist\n", pkt->vm_name); 9083618326fSDavid Hunt } 9093618326fSDavid Hunt 91038d232b9SBruce Richardson if (pkt->command == RTE_POWER_QUERY_FREQ_LIST || 91138d232b9SBruce Richardson pkt->command == RTE_POWER_QUERY_FREQ) { 912db91b52bSMarcin Hajkowski 913db91b52bSMarcin Hajkowski RTE_LOG(INFO, CHANNEL_MONITOR, 914db91b52bSMarcin Hajkowski "Frequency for %s requested.\n", pkt->vm_name); 915db91b52bSMarcin Hajkowski int ret = send_freq(pkt, 916db91b52bSMarcin Hajkowski chan_info, 91738d232b9SBruce Richardson pkt->command == RTE_POWER_QUERY_FREQ_LIST); 918db91b52bSMarcin Hajkowski if (ret < 0) 919db91b52bSMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, "Error during frequency sending.\n"); 920db91b52bSMarcin Hajkowski } 921db91b52bSMarcin Hajkowski 92238d232b9SBruce Richardson if (pkt->command == RTE_POWER_QUERY_CAPS_LIST || 92338d232b9SBruce Richardson pkt->command == RTE_POWER_QUERY_CAPS) { 92499898ac5SMarcin Hajkowski 92599898ac5SMarcin Hajkowski RTE_LOG(INFO, CHANNEL_MONITOR, 92699898ac5SMarcin Hajkowski "Capabilities for %s requested.\n", pkt->vm_name); 92799898ac5SMarcin Hajkowski int ret = send_capabilities(pkt, 92899898ac5SMarcin Hajkowski chan_info, 92938d232b9SBruce Richardson pkt->command == RTE_POWER_QUERY_CAPS_LIST); 93099898ac5SMarcin Hajkowski if (ret < 0) 93199898ac5SMarcin Hajkowski RTE_LOG(ERR, CHANNEL_MONITOR, "Error during sending capabilities.\n"); 93299898ac5SMarcin Hajkowski } 93399898ac5SMarcin Hajkowski 9343618326fSDavid Hunt /* 9353618326fSDavid Hunt * Return is not checked as channel status may have been set to DISABLED 936e8ae9b66SAlan Carew * from management thread 937e8ae9b66SAlan Carew */ 93814215f34SJoyce Kong uint32_t channel_processing = CHANNEL_MGR_CHANNEL_PROCESSING; 93992e68d9cSTyler Retzlaff rte_atomic_compare_exchange_strong_explicit(&(chan_info->status), &channel_processing, 94092e68d9cSTyler Retzlaff CHANNEL_MGR_CHANNEL_CONNECTED, rte_memory_order_relaxed, rte_memory_order_relaxed); 941e8ae9b66SAlan Carew return 0; 942e8ae9b66SAlan Carew 943e8ae9b66SAlan Carew } 944e8ae9b66SAlan Carew 945e8ae9b66SAlan Carew int 946e8ae9b66SAlan Carew add_channel_to_monitor(struct channel_info **chan_info) 947e8ae9b66SAlan Carew { 948e8ae9b66SAlan Carew struct channel_info *info = *chan_info; 949e8ae9b66SAlan Carew struct epoll_event event; 950e8ae9b66SAlan Carew 951e8ae9b66SAlan Carew event.events = EPOLLIN; 952e8ae9b66SAlan Carew event.data.ptr = info; 953e8ae9b66SAlan Carew if (epoll_ctl(global_event_fd, EPOLL_CTL_ADD, info->fd, &event) < 0) { 954e8ae9b66SAlan Carew RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to add channel '%s' " 955e8ae9b66SAlan Carew "to epoll\n", info->channel_path); 956e8ae9b66SAlan Carew return -1; 957e8ae9b66SAlan Carew } 9583618326fSDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, "Added channel '%s' " 9593618326fSDavid Hunt "to monitor\n", info->channel_path); 960e8ae9b66SAlan Carew return 0; 961e8ae9b66SAlan Carew } 962e8ae9b66SAlan Carew 963e8ae9b66SAlan Carew int 964e8ae9b66SAlan Carew remove_channel_from_monitor(struct channel_info *chan_info) 965e8ae9b66SAlan Carew { 9663618326fSDavid Hunt if (epoll_ctl(global_event_fd, EPOLL_CTL_DEL, 9673618326fSDavid Hunt chan_info->fd, NULL) < 0) { 968e8ae9b66SAlan Carew RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to remove channel '%s' " 969e8ae9b66SAlan Carew "from epoll\n", chan_info->channel_path); 970e8ae9b66SAlan Carew return -1; 971e8ae9b66SAlan Carew } 972e8ae9b66SAlan Carew return 0; 973e8ae9b66SAlan Carew } 974e8ae9b66SAlan Carew 975e8ae9b66SAlan Carew int 976e8ae9b66SAlan Carew channel_monitor_init(void) 977e8ae9b66SAlan Carew { 978e8ae9b66SAlan Carew global_event_fd = epoll_create1(0); 979e8ae9b66SAlan Carew if (global_event_fd == 0) { 9803618326fSDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 9813618326fSDavid Hunt "Error creating epoll context with error %s\n", 9823618326fSDavid Hunt strerror(errno)); 983e8ae9b66SAlan Carew return -1; 984e8ae9b66SAlan Carew } 9853618326fSDavid Hunt global_events_list = rte_malloc("epoll_events", 9863618326fSDavid Hunt sizeof(*global_events_list) 987fdf20fa7SSergio Gonzalez Monroy * MAX_EVENTS, RTE_CACHE_LINE_SIZE); 988e8ae9b66SAlan Carew if (global_events_list == NULL) { 989e8ae9b66SAlan Carew RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to rte_malloc for " 990e8ae9b66SAlan Carew "epoll events\n"); 991e8ae9b66SAlan Carew return -1; 992e8ae9b66SAlan Carew } 993e8ae9b66SAlan Carew return 0; 994e8ae9b66SAlan Carew } 995e8ae9b66SAlan Carew 996a63504a9SDavid Hunt static void 997a63504a9SDavid Hunt read_binary_packet(struct channel_info *chan_info) 998a63504a9SDavid Hunt { 999bd5b6720SBruce Richardson struct rte_power_channel_packet pkt; 1000a63504a9SDavid Hunt void *buffer = &pkt; 1001a63504a9SDavid Hunt int buffer_len = sizeof(pkt); 1002a63504a9SDavid Hunt int n_bytes, err = 0; 1003a63504a9SDavid Hunt 1004a63504a9SDavid Hunt while (buffer_len > 0) { 1005a63504a9SDavid Hunt n_bytes = read(chan_info->fd, 1006a63504a9SDavid Hunt buffer, buffer_len); 1007a63504a9SDavid Hunt if (n_bytes == buffer_len) 1008a63504a9SDavid Hunt break; 10091b897991SLukasz Krakowiak if (n_bytes < 0) { 1010a63504a9SDavid Hunt err = errno; 1011a63504a9SDavid Hunt RTE_LOG(DEBUG, CHANNEL_MONITOR, 1012a63504a9SDavid Hunt "Received error on " 1013a63504a9SDavid Hunt "channel '%s' read: %s\n", 1014a63504a9SDavid Hunt chan_info->channel_path, 1015a63504a9SDavid Hunt strerror(err)); 1016a63504a9SDavid Hunt remove_channel(&chan_info); 1017a63504a9SDavid Hunt break; 1018a63504a9SDavid Hunt } 1019a63504a9SDavid Hunt buffer = (char *)buffer + n_bytes; 1020a63504a9SDavid Hunt buffer_len -= n_bytes; 1021a63504a9SDavid Hunt } 1022a63504a9SDavid Hunt if (!err) 1023a63504a9SDavid Hunt process_request(&pkt, chan_info); 1024a63504a9SDavid Hunt } 1025a63504a9SDavid Hunt 1026a63504a9SDavid Hunt #ifdef USE_JANSSON 1027a63504a9SDavid Hunt static void 1028a63504a9SDavid Hunt read_json_packet(struct channel_info *chan_info) 1029a63504a9SDavid Hunt { 1030bd5b6720SBruce Richardson struct rte_power_channel_packet pkt; 1031a63504a9SDavid Hunt int n_bytes, ret; 1032a63504a9SDavid Hunt json_t *root; 1033a63504a9SDavid Hunt json_error_t error; 1034221e7026SMarcin Hajkowski const char *resource_name; 1035abeef65dSDavid Hunt char *start, *end; 1036abeef65dSDavid Hunt uint32_t n; 1037221e7026SMarcin Hajkowski 1038a63504a9SDavid Hunt 1039a63504a9SDavid Hunt /* read opening brace to closing brace */ 1040a63504a9SDavid Hunt do { 1041a63504a9SDavid Hunt int idx = 0; 1042a63504a9SDavid Hunt int indent = 0; 1043a63504a9SDavid Hunt do { 1044a63504a9SDavid Hunt n_bytes = read(chan_info->fd, &json_data[idx], 1); 1045a63504a9SDavid Hunt if (n_bytes == 0) 1046a63504a9SDavid Hunt break; 1047a63504a9SDavid Hunt if (json_data[idx] == '{') 1048a63504a9SDavid Hunt indent++; 1049a63504a9SDavid Hunt if (json_data[idx] == '}') 1050a63504a9SDavid Hunt indent--; 1051a63504a9SDavid Hunt if ((indent > 0) || (idx > 0)) 1052a63504a9SDavid Hunt idx++; 10534c2caea0SReshma Pattan if (indent <= 0) 1054a63504a9SDavid Hunt json_data[idx] = 0; 1055a63504a9SDavid Hunt if (idx >= MAX_JSON_STRING_LEN-1) 1056a63504a9SDavid Hunt break; 1057a63504a9SDavid Hunt } while (indent > 0); 1058a63504a9SDavid Hunt 10598f8f876bSDavid Hunt json_data[idx] = '\0'; 1060a63504a9SDavid Hunt 1061a63504a9SDavid Hunt if (strlen(json_data) == 0) 1062a63504a9SDavid Hunt continue; 1063a63504a9SDavid Hunt 1064a63504a9SDavid Hunt printf("got [%s]\n", json_data); 1065a63504a9SDavid Hunt 1066a63504a9SDavid Hunt root = json_loads(json_data, 0, &error); 1067a63504a9SDavid Hunt 1068a63504a9SDavid Hunt if (root) { 1069221e7026SMarcin Hajkowski resource_name = get_resource_name_from_chn_path( 1070221e7026SMarcin Hajkowski chan_info->channel_path); 1071a63504a9SDavid Hunt /* 1072a63504a9SDavid Hunt * Because our data is now in the json 1073a63504a9SDavid Hunt * object, we can overwrite the pkt 1074bd5b6720SBruce Richardson * with a rte_power_channel_packet struct, using 1075a63504a9SDavid Hunt * parse_json_to_pkt() 1076a63504a9SDavid Hunt */ 1077221e7026SMarcin Hajkowski ret = parse_json_to_pkt(root, &pkt, resource_name); 1078a63504a9SDavid Hunt json_decref(root); 1079a63504a9SDavid Hunt if (ret) { 1080a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 1081a63504a9SDavid Hunt "Error validating JSON profile data\n"); 1082a63504a9SDavid Hunt break; 1083a63504a9SDavid Hunt } 1084abeef65dSDavid Hunt start = strstr(pkt.vm_name, 1085abeef65dSDavid Hunt CHANNEL_MGR_FIFO_PATTERN_NAME); 1086abeef65dSDavid Hunt if (start != NULL) { 1087abeef65dSDavid Hunt /* move past pattern to start of fifo id */ 1088abeef65dSDavid Hunt start += strlen(CHANNEL_MGR_FIFO_PATTERN_NAME); 1089abeef65dSDavid Hunt 1090abeef65dSDavid Hunt end = start; 1091abeef65dSDavid Hunt n = (uint32_t)strtoul(start, &end, 10); 1092abeef65dSDavid Hunt 1093abeef65dSDavid Hunt if (end[0] == '\0') { 1094abeef65dSDavid Hunt /* Add core id to core list */ 1095abeef65dSDavid Hunt pkt.num_vcpu = 1; 1096abeef65dSDavid Hunt pkt.vcpu_to_control[0] = n; 1097a63504a9SDavid Hunt process_request(&pkt, chan_info); 1098a63504a9SDavid Hunt } else { 1099a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 1100abeef65dSDavid Hunt "Cannot extract core id from fifo name\n"); 1101abeef65dSDavid Hunt } 1102abeef65dSDavid Hunt } else { 1103abeef65dSDavid Hunt process_request(&pkt, chan_info); 1104abeef65dSDavid Hunt } 1105abeef65dSDavid Hunt } else { 1106abeef65dSDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 1107a63504a9SDavid Hunt "JSON error on line %d: %s\n", 1108a63504a9SDavid Hunt error.line, error.text); 1109a63504a9SDavid Hunt } 1110a63504a9SDavid Hunt } while (n_bytes > 0); 1111a63504a9SDavid Hunt } 1112a63504a9SDavid Hunt #endif 1113a63504a9SDavid Hunt 1114e8ae9b66SAlan Carew void 1115e8ae9b66SAlan Carew run_channel_monitor(void) 1116e8ae9b66SAlan Carew { 1117e8ae9b66SAlan Carew while (run_loop) { 1118e8ae9b66SAlan Carew int n_events, i; 1119e8ae9b66SAlan Carew 1120e8ae9b66SAlan Carew n_events = epoll_wait(global_event_fd, global_events_list, 1121e8ae9b66SAlan Carew MAX_EVENTS, 1); 1122e8ae9b66SAlan Carew if (!run_loop) 1123e8ae9b66SAlan Carew break; 1124e8ae9b66SAlan Carew for (i = 0; i < n_events; i++) { 1125e8ae9b66SAlan Carew struct channel_info *chan_info = (struct channel_info *) 1126e8ae9b66SAlan Carew global_events_list[i].data.ptr; 1127e8ae9b66SAlan Carew if ((global_events_list[i].events & EPOLLERR) || 1128e8ae9b66SAlan Carew (global_events_list[i].events & EPOLLHUP)) { 1129ce4a2766SDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 1130ce4a2766SDavid Hunt "Remote closed connection for " 1131f14791a8SRory Sexton "channel '%s'\n", 1132f14791a8SRory Sexton chan_info->channel_path); 1133e8ae9b66SAlan Carew remove_channel(&chan_info); 1134e8ae9b66SAlan Carew continue; 1135e8ae9b66SAlan Carew } 1136e8ae9b66SAlan Carew if (global_events_list[i].events & EPOLLIN) { 1137e8ae9b66SAlan Carew 1138a63504a9SDavid Hunt switch (chan_info->type) { 1139a63504a9SDavid Hunt case CHANNEL_TYPE_BINARY: 1140a63504a9SDavid Hunt read_binary_packet(chan_info); 1141e8ae9b66SAlan Carew break; 1142a63504a9SDavid Hunt #ifdef USE_JANSSON 1143a63504a9SDavid Hunt case CHANNEL_TYPE_JSON: 1144a63504a9SDavid Hunt read_json_packet(chan_info); 1145a63504a9SDavid Hunt break; 1146a63504a9SDavid Hunt #endif 1147a63504a9SDavid Hunt default: 1148e8ae9b66SAlan Carew break; 1149e8ae9b66SAlan Carew } 1150e8ae9b66SAlan Carew } 1151e8ae9b66SAlan Carew } 1152e4f66da3SDavid Hunt rte_delay_us(time_period_ms*1000); 1153f14791a8SRory Sexton if (policy_is_set) { 1154221e7026SMarcin Hajkowski unsigned int j; 11557abd801fSDavid Hunt 1156221e7026SMarcin Hajkowski for (j = 0; j < RTE_DIM(policies); j++) { 1157f14791a8SRory Sexton if (policies[j].enabled == 1) 1158f14791a8SRory Sexton apply_policy(&policies[j]); 1159f14791a8SRory Sexton } 1160f14791a8SRory Sexton } 1161e8ae9b66SAlan Carew } 1162e8ae9b66SAlan Carew } 1163