13998e2a0SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 23998e2a0SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 3e8ae9b66SAlan Carew */ 4e8ae9b66SAlan Carew 5e8ae9b66SAlan Carew #include <unistd.h> 6e8ae9b66SAlan Carew #include <stdio.h> 7e8ae9b66SAlan Carew #include <stdlib.h> 8e8ae9b66SAlan Carew #include <stdint.h> 9e8ae9b66SAlan Carew #include <signal.h> 10e8ae9b66SAlan Carew #include <errno.h> 11e8ae9b66SAlan Carew #include <string.h> 12a63504a9SDavid Hunt #include <fcntl.h> 13e8ae9b66SAlan Carew #include <sys/types.h> 14e8ae9b66SAlan Carew #include <sys/epoll.h> 15e8ae9b66SAlan Carew #include <sys/queue.h> 16f14791a8SRory Sexton #include <sys/time.h> 17a63504a9SDavid Hunt #include <sys/socket.h> 18a63504a9SDavid Hunt #include <sys/select.h> 19a63504a9SDavid Hunt #ifdef USE_JANSSON 20a63504a9SDavid Hunt #include <jansson.h> 21a63504a9SDavid Hunt #else 22a63504a9SDavid Hunt #pragma message "Jansson dev libs unavailable, not including JSON parsing" 23a63504a9SDavid Hunt #endif 246723c0fcSBruce Richardson #include <rte_string_fns.h> 25e8ae9b66SAlan Carew #include <rte_log.h> 26e8ae9b66SAlan Carew #include <rte_memory.h> 27e8ae9b66SAlan Carew #include <rte_malloc.h> 28e8ae9b66SAlan Carew #include <rte_atomic.h> 29f14791a8SRory Sexton #include <rte_cycles.h> 30f14791a8SRory Sexton #include <rte_ethdev.h> 31f14791a8SRory Sexton #include <rte_pmd_i40e.h> 32e8ae9b66SAlan Carew 33f14791a8SRory Sexton #include <libvirt/libvirt.h> 34e8ae9b66SAlan Carew #include "channel_monitor.h" 35e8ae9b66SAlan Carew #include "channel_commands.h" 36e8ae9b66SAlan Carew #include "channel_manager.h" 37e8ae9b66SAlan Carew #include "power_manager.h" 38b89168efSDavid Hunt #include "oob_monitor.h" 39e8ae9b66SAlan Carew 40e8ae9b66SAlan Carew #define RTE_LOGTYPE_CHANNEL_MONITOR RTE_LOGTYPE_USER1 41e8ae9b66SAlan Carew 42e8ae9b66SAlan Carew #define MAX_EVENTS 256 43e8ae9b66SAlan Carew 44f14791a8SRory Sexton uint64_t vsi_pkt_count_prev[384]; 45f14791a8SRory Sexton uint64_t rdtsc_prev[384]; 46a63504a9SDavid Hunt #define MAX_JSON_STRING_LEN 1024 47a63504a9SDavid Hunt char json_data[MAX_JSON_STRING_LEN]; 48e8ae9b66SAlan Carew 49e4f66da3SDavid Hunt double time_period_ms = 1; 50e8ae9b66SAlan Carew static volatile unsigned run_loop = 1; 51e8ae9b66SAlan Carew static int global_event_fd; 52f14791a8SRory Sexton static unsigned int policy_is_set; 53e8ae9b66SAlan Carew static struct epoll_event *global_events_list; 5490a774c4SDavid Hunt static struct policy policies[MAX_CLIENTS]; 55e8ae9b66SAlan Carew 56a63504a9SDavid Hunt #ifdef USE_JANSSON 57a63504a9SDavid Hunt 58a63504a9SDavid Hunt union PFID { 59a63504a9SDavid Hunt struct ether_addr addr; 60a63504a9SDavid Hunt uint64_t pfid; 61a63504a9SDavid Hunt }; 62a63504a9SDavid Hunt 63a63504a9SDavid Hunt static int 64a63504a9SDavid Hunt str_to_ether_addr(const char *a, struct ether_addr *ether_addr) 65a63504a9SDavid Hunt { 66a63504a9SDavid Hunt int i; 67a63504a9SDavid Hunt char *end; 68a63504a9SDavid Hunt unsigned long o[ETHER_ADDR_LEN]; 69a63504a9SDavid Hunt 70a63504a9SDavid Hunt i = 0; 71a63504a9SDavid Hunt do { 72a63504a9SDavid Hunt errno = 0; 73a63504a9SDavid Hunt o[i] = strtoul(a, &end, 16); 74a63504a9SDavid Hunt if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0)) 75a63504a9SDavid Hunt return -1; 76a63504a9SDavid Hunt a = end + 1; 77a63504a9SDavid Hunt } while (++i != RTE_DIM(o) / sizeof(o[0]) && end[0] != 0); 78a63504a9SDavid Hunt 79a63504a9SDavid Hunt /* Junk at the end of line */ 80a63504a9SDavid Hunt if (end[0] != 0) 81a63504a9SDavid Hunt return -1; 82a63504a9SDavid Hunt 83a63504a9SDavid Hunt /* Support the format XX:XX:XX:XX:XX:XX */ 84a63504a9SDavid Hunt if (i == ETHER_ADDR_LEN) { 85a63504a9SDavid Hunt while (i-- != 0) { 86a63504a9SDavid Hunt if (o[i] > UINT8_MAX) 87a63504a9SDavid Hunt return -1; 88a63504a9SDavid Hunt ether_addr->addr_bytes[i] = (uint8_t)o[i]; 89a63504a9SDavid Hunt } 90a63504a9SDavid Hunt /* Support the format XXXX:XXXX:XXXX */ 91a63504a9SDavid Hunt } else if (i == ETHER_ADDR_LEN / 2) { 92a63504a9SDavid Hunt while (i-- != 0) { 93a63504a9SDavid Hunt if (o[i] > UINT16_MAX) 94a63504a9SDavid Hunt return -1; 95a63504a9SDavid Hunt ether_addr->addr_bytes[i * 2] = 96a63504a9SDavid Hunt (uint8_t)(o[i] >> 8); 97a63504a9SDavid Hunt ether_addr->addr_bytes[i * 2 + 1] = 98a63504a9SDavid Hunt (uint8_t)(o[i] & 0xff); 99a63504a9SDavid Hunt } 100a63504a9SDavid Hunt /* unknown format */ 101a63504a9SDavid Hunt } else 102a63504a9SDavid Hunt return -1; 103a63504a9SDavid Hunt 104a63504a9SDavid Hunt return 0; 105a63504a9SDavid Hunt } 106a63504a9SDavid Hunt 107a63504a9SDavid Hunt static int 108a63504a9SDavid Hunt set_policy_mac(struct channel_packet *pkt, int idx, char *mac) 109a63504a9SDavid Hunt { 110a63504a9SDavid Hunt union PFID pfid; 111a63504a9SDavid Hunt int ret; 112a63504a9SDavid Hunt 113a63504a9SDavid Hunt /* Use port MAC address as the vfid */ 114a63504a9SDavid Hunt ret = str_to_ether_addr(mac, &pfid.addr); 115a63504a9SDavid Hunt 116a63504a9SDavid Hunt if (ret != 0) { 117a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 118a63504a9SDavid Hunt "Invalid mac address received in JSON\n"); 119a63504a9SDavid Hunt pkt->vfid[idx] = 0; 120a63504a9SDavid Hunt return -1; 121a63504a9SDavid Hunt } 122a63504a9SDavid Hunt 123a63504a9SDavid Hunt printf("Received MAC Address: %02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":" 124a63504a9SDavid Hunt "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n", 125a63504a9SDavid Hunt pfid.addr.addr_bytes[0], pfid.addr.addr_bytes[1], 126a63504a9SDavid Hunt pfid.addr.addr_bytes[2], pfid.addr.addr_bytes[3], 127a63504a9SDavid Hunt pfid.addr.addr_bytes[4], pfid.addr.addr_bytes[5]); 128a63504a9SDavid Hunt 129a63504a9SDavid Hunt pkt->vfid[idx] = pfid.pfid; 130a63504a9SDavid Hunt return 0; 131a63504a9SDavid Hunt } 132a63504a9SDavid Hunt 133a63504a9SDavid Hunt 134a63504a9SDavid Hunt static int 135a63504a9SDavid Hunt parse_json_to_pkt(json_t *element, struct channel_packet *pkt) 136a63504a9SDavid Hunt { 137a63504a9SDavid Hunt const char *key; 138a63504a9SDavid Hunt json_t *value; 139a63504a9SDavid Hunt int ret; 140a63504a9SDavid Hunt 141a63504a9SDavid Hunt memset(pkt, 0, sizeof(struct channel_packet)); 142a63504a9SDavid Hunt 143a63504a9SDavid Hunt pkt->nb_mac_to_monitor = 0; 144a63504a9SDavid Hunt pkt->t_boost_status.tbEnabled = false; 145a63504a9SDavid Hunt pkt->workload = LOW; 146a63504a9SDavid Hunt pkt->policy_to_use = TIME; 147a63504a9SDavid Hunt pkt->command = PKT_POLICY; 148a63504a9SDavid Hunt pkt->core_type = CORE_TYPE_PHYSICAL; 149a63504a9SDavid Hunt 150a63504a9SDavid Hunt json_object_foreach(element, key, value) { 151a63504a9SDavid Hunt if (!strcmp(key, "policy")) { 152a63504a9SDavid Hunt /* Recurse in to get the contents of profile */ 153a63504a9SDavid Hunt ret = parse_json_to_pkt(value, pkt); 154a63504a9SDavid Hunt if (ret) 155a63504a9SDavid Hunt return ret; 156a63504a9SDavid Hunt } else if (!strcmp(key, "instruction")) { 157a63504a9SDavid Hunt /* Recurse in to get the contents of instruction */ 158a63504a9SDavid Hunt ret = parse_json_to_pkt(value, pkt); 159a63504a9SDavid Hunt if (ret) 160a63504a9SDavid Hunt return ret; 161a63504a9SDavid Hunt } else if (!strcmp(key, "name")) { 16257fad3e2SReshma Pattan strlcpy(pkt->vm_name, json_string_value(value), 16357fad3e2SReshma Pattan sizeof(pkt->vm_name)); 164a63504a9SDavid Hunt } else if (!strcmp(key, "command")) { 165a63504a9SDavid Hunt char command[32]; 1666723c0fcSBruce Richardson strlcpy(command, json_string_value(value), 32); 167a63504a9SDavid Hunt if (!strcmp(command, "power")) { 168a63504a9SDavid Hunt pkt->command = CPU_POWER; 169a63504a9SDavid Hunt } else if (!strcmp(command, "create")) { 170a63504a9SDavid Hunt pkt->command = PKT_POLICY; 171a63504a9SDavid Hunt } else if (!strcmp(command, "destroy")) { 172a63504a9SDavid Hunt pkt->command = PKT_POLICY_REMOVE; 173a63504a9SDavid Hunt } else { 174a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 175a63504a9SDavid Hunt "Invalid command received in JSON\n"); 176a63504a9SDavid Hunt return -1; 177a63504a9SDavid Hunt } 178a63504a9SDavid Hunt } else if (!strcmp(key, "policy_type")) { 179a63504a9SDavid Hunt char command[32]; 1806723c0fcSBruce Richardson strlcpy(command, json_string_value(value), 32); 181a63504a9SDavid Hunt if (!strcmp(command, "TIME")) { 182a63504a9SDavid Hunt pkt->policy_to_use = TIME; 183a63504a9SDavid Hunt } else if (!strcmp(command, "TRAFFIC")) { 184a63504a9SDavid Hunt pkt->policy_to_use = TRAFFIC; 185a63504a9SDavid Hunt } else if (!strcmp(command, "WORKLOAD")) { 186a63504a9SDavid Hunt pkt->policy_to_use = WORKLOAD; 187a63504a9SDavid Hunt } else if (!strcmp(command, "BRANCH_RATIO")) { 188a63504a9SDavid Hunt pkt->policy_to_use = BRANCH_RATIO; 189a63504a9SDavid Hunt } else { 190a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 191a63504a9SDavid Hunt "Wrong policy_type received in JSON\n"); 192a63504a9SDavid Hunt return -1; 193a63504a9SDavid Hunt } 194a63504a9SDavid Hunt } else if (!strcmp(key, "workload")) { 195a63504a9SDavid Hunt char command[32]; 1966723c0fcSBruce Richardson strlcpy(command, json_string_value(value), 32); 197a63504a9SDavid Hunt if (!strcmp(command, "HIGH")) { 198a63504a9SDavid Hunt pkt->workload = HIGH; 199a63504a9SDavid Hunt } else if (!strcmp(command, "MEDIUM")) { 200a63504a9SDavid Hunt pkt->workload = MEDIUM; 201a63504a9SDavid Hunt } else if (!strcmp(command, "LOW")) { 202a63504a9SDavid Hunt pkt->workload = LOW; 203a63504a9SDavid Hunt } else { 204a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 205a63504a9SDavid Hunt "Wrong workload received in JSON\n"); 206a63504a9SDavid Hunt return -1; 207a63504a9SDavid Hunt } 208a63504a9SDavid Hunt } else if (!strcmp(key, "busy_hours")) { 209a63504a9SDavid Hunt unsigned int i; 210a63504a9SDavid Hunt size_t size = json_array_size(value); 211a63504a9SDavid Hunt 212a63504a9SDavid Hunt for (i = 0; i < size; i++) { 213a63504a9SDavid Hunt int hour = (int)json_integer_value( 214a63504a9SDavid Hunt json_array_get(value, i)); 215a63504a9SDavid Hunt pkt->timer_policy.busy_hours[i] = hour; 216a63504a9SDavid Hunt } 217a63504a9SDavid Hunt } else if (!strcmp(key, "quiet_hours")) { 218a63504a9SDavid Hunt unsigned int i; 219a63504a9SDavid Hunt size_t size = json_array_size(value); 220a63504a9SDavid Hunt 221a63504a9SDavid Hunt for (i = 0; i < size; i++) { 222a63504a9SDavid Hunt int hour = (int)json_integer_value( 223a63504a9SDavid Hunt json_array_get(value, i)); 224a63504a9SDavid Hunt pkt->timer_policy.quiet_hours[i] = hour; 225a63504a9SDavid Hunt } 226a63504a9SDavid Hunt } else if (!strcmp(key, "core_list")) { 227a63504a9SDavid Hunt unsigned int i; 228a63504a9SDavid Hunt size_t size = json_array_size(value); 229a63504a9SDavid Hunt 230a63504a9SDavid Hunt for (i = 0; i < size; i++) { 231a63504a9SDavid Hunt int core = (int)json_integer_value( 232a63504a9SDavid Hunt json_array_get(value, i)); 233a63504a9SDavid Hunt pkt->vcpu_to_control[i] = core; 234a63504a9SDavid Hunt } 235a63504a9SDavid Hunt pkt->num_vcpu = size; 236a63504a9SDavid Hunt } else if (!strcmp(key, "mac_list")) { 237a63504a9SDavid Hunt unsigned int i; 238a63504a9SDavid Hunt size_t size = json_array_size(value); 239a63504a9SDavid Hunt 240a63504a9SDavid Hunt for (i = 0; i < size; i++) { 241a63504a9SDavid Hunt char mac[32]; 2426723c0fcSBruce Richardson strlcpy(mac, 2436723c0fcSBruce Richardson json_string_value(json_array_get(value, i)), 2446723c0fcSBruce Richardson 32); 245a63504a9SDavid Hunt set_policy_mac(pkt, i, mac); 246a63504a9SDavid Hunt } 247a63504a9SDavid Hunt pkt->nb_mac_to_monitor = size; 248a63504a9SDavid Hunt } else if (!strcmp(key, "avg_packet_thresh")) { 249a63504a9SDavid Hunt pkt->traffic_policy.avg_max_packet_thresh = 250a63504a9SDavid Hunt (uint32_t)json_integer_value(value); 251a63504a9SDavid Hunt } else if (!strcmp(key, "max_packet_thresh")) { 252a63504a9SDavid Hunt pkt->traffic_policy.max_max_packet_thresh = 253a63504a9SDavid Hunt (uint32_t)json_integer_value(value); 254a63504a9SDavid Hunt } else if (!strcmp(key, "unit")) { 255a63504a9SDavid Hunt char unit[32]; 2566723c0fcSBruce Richardson strlcpy(unit, json_string_value(value), 32); 257a63504a9SDavid Hunt if (!strcmp(unit, "SCALE_UP")) { 258a63504a9SDavid Hunt pkt->unit = CPU_POWER_SCALE_UP; 259a63504a9SDavid Hunt } else if (!strcmp(unit, "SCALE_DOWN")) { 260a63504a9SDavid Hunt pkt->unit = CPU_POWER_SCALE_DOWN; 261a63504a9SDavid Hunt } else if (!strcmp(unit, "SCALE_MAX")) { 262a63504a9SDavid Hunt pkt->unit = CPU_POWER_SCALE_MAX; 263a63504a9SDavid Hunt } else if (!strcmp(unit, "SCALE_MIN")) { 264a63504a9SDavid Hunt pkt->unit = CPU_POWER_SCALE_MIN; 265a63504a9SDavid Hunt } else if (!strcmp(unit, "ENABLE_TURBO")) { 266a63504a9SDavid Hunt pkt->unit = CPU_POWER_ENABLE_TURBO; 267a63504a9SDavid Hunt } else if (!strcmp(unit, "DISABLE_TURBO")) { 268a63504a9SDavid Hunt pkt->unit = CPU_POWER_DISABLE_TURBO; 269a63504a9SDavid Hunt } else { 270a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 271a63504a9SDavid Hunt "Invalid command received in JSON\n"); 272a63504a9SDavid Hunt return -1; 273a63504a9SDavid Hunt } 274a63504a9SDavid Hunt } else if (!strcmp(key, "resource_id")) { 275a63504a9SDavid Hunt pkt->resource_id = (uint32_t)json_integer_value(value); 276a63504a9SDavid Hunt } else { 277a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 278a63504a9SDavid Hunt "Unknown key received in JSON string: %s\n", 279a63504a9SDavid Hunt key); 280a63504a9SDavid Hunt } 281a63504a9SDavid Hunt } 282a63504a9SDavid Hunt return 0; 283a63504a9SDavid Hunt } 284a63504a9SDavid Hunt #endif 285a63504a9SDavid Hunt 286e8ae9b66SAlan Carew void channel_monitor_exit(void) 287e8ae9b66SAlan Carew { 288e8ae9b66SAlan Carew run_loop = 0; 289e8ae9b66SAlan Carew rte_free(global_events_list); 290e8ae9b66SAlan Carew } 291e8ae9b66SAlan Carew 292f14791a8SRory Sexton static void 293f14791a8SRory Sexton core_share(int pNo, int z, int x, int t) 294f14791a8SRory Sexton { 295f14791a8SRory Sexton if (policies[pNo].core_share[z].pcpu == lvm_info[x].pcpus[t]) { 296f14791a8SRory Sexton if (strcmp(policies[pNo].pkt.vm_name, 297f14791a8SRory Sexton lvm_info[x].vm_name) != 0) { 298f14791a8SRory Sexton policies[pNo].core_share[z].status = 1; 299f14791a8SRory Sexton power_manager_scale_core_max( 300f14791a8SRory Sexton policies[pNo].core_share[z].pcpu); 301f14791a8SRory Sexton } 302f14791a8SRory Sexton } 303f14791a8SRory Sexton } 304f14791a8SRory Sexton 305f14791a8SRory Sexton static void 306f14791a8SRory Sexton core_share_status(int pNo) 307f14791a8SRory Sexton { 308f14791a8SRory Sexton 309395e97bfSDavid Hunt int noVms = 0, noVcpus = 0, z, x, t; 310f14791a8SRory Sexton 311f14791a8SRory Sexton get_all_vm(&noVms, &noVcpus); 312f14791a8SRory Sexton 313f14791a8SRory Sexton /* Reset Core Share Status. */ 314f14791a8SRory Sexton for (z = 0; z < noVcpus; z++) 315f14791a8SRory Sexton policies[pNo].core_share[z].status = 0; 316f14791a8SRory Sexton 317f14791a8SRory Sexton /* Foreach vcpu in a policy. */ 318f14791a8SRory Sexton for (z = 0; z < policies[pNo].pkt.num_vcpu; z++) { 319f14791a8SRory Sexton /* Foreach VM on the platform. */ 320f14791a8SRory Sexton for (x = 0; x < noVms; x++) { 321f14791a8SRory Sexton /* Foreach vcpu of VMs on platform. */ 322f14791a8SRory Sexton for (t = 0; t < lvm_info[x].num_cpus; t++) 323f14791a8SRory Sexton core_share(pNo, z, x, t); 324f14791a8SRory Sexton } 325f14791a8SRory Sexton } 326f14791a8SRory Sexton } 327f14791a8SRory Sexton 3283618326fSDavid Hunt 3293618326fSDavid Hunt static int 3303618326fSDavid Hunt pcpu_monitor(struct policy *pol, struct core_info *ci, int pcpu, int count) 3313618326fSDavid Hunt { 3323618326fSDavid Hunt int ret = 0; 3333618326fSDavid Hunt 3343618326fSDavid Hunt if (pol->pkt.policy_to_use == BRANCH_RATIO) { 3353618326fSDavid Hunt ci->cd[pcpu].oob_enabled = 1; 3363618326fSDavid Hunt ret = add_core_to_monitor(pcpu); 3373618326fSDavid Hunt if (ret == 0) 3383618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 3393618326fSDavid Hunt "Monitoring pcpu %d OOB for %s\n", 3403618326fSDavid Hunt pcpu, pol->pkt.vm_name); 3413618326fSDavid Hunt else 3423618326fSDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 3433618326fSDavid Hunt "Error monitoring pcpu %d OOB for %s\n", 3443618326fSDavid Hunt pcpu, pol->pkt.vm_name); 3453618326fSDavid Hunt 3463618326fSDavid Hunt } else { 3473618326fSDavid Hunt pol->core_share[count].pcpu = pcpu; 3483618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 3493618326fSDavid Hunt "Monitoring pcpu %d for %s\n", 3503618326fSDavid Hunt pcpu, pol->pkt.vm_name); 3513618326fSDavid Hunt } 3523618326fSDavid Hunt return ret; 3533618326fSDavid Hunt } 3543618326fSDavid Hunt 355f14791a8SRory Sexton static void 356f14791a8SRory Sexton get_pcpu_to_control(struct policy *pol) 357f14791a8SRory Sexton { 358f14791a8SRory Sexton 359f14791a8SRory Sexton /* Convert vcpu to pcpu. */ 360f14791a8SRory Sexton struct vm_info info; 361f14791a8SRory Sexton int pcpu, count; 362b89168efSDavid Hunt struct core_info *ci; 363b89168efSDavid Hunt 364b89168efSDavid Hunt ci = get_core_info(); 365f14791a8SRory Sexton 366ce4a2766SDavid Hunt RTE_LOG(DEBUG, CHANNEL_MONITOR, 3673618326fSDavid Hunt "Looking for pcpu for %s\n", pol->pkt.vm_name); 3683618326fSDavid Hunt 3693618326fSDavid Hunt /* 3703618326fSDavid Hunt * So now that we're handling virtual and physical cores, we need to 3713618326fSDavid Hunt * differenciate between them when adding them to the branch monitor. 3723618326fSDavid Hunt * Virtual cores need to be converted to physical cores. 3733618326fSDavid Hunt */ 3743618326fSDavid Hunt if (pol->pkt.core_type == CORE_TYPE_VIRTUAL) { 3753618326fSDavid Hunt /* 3763618326fSDavid Hunt * If the cores in the policy are virtual, we need to map them 3773618326fSDavid Hunt * to physical core. We look up the vm info and use that for 3783618326fSDavid Hunt * the mapping. 3793618326fSDavid Hunt */ 380f14791a8SRory Sexton get_info_vm(pol->pkt.vm_name, &info); 381f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 3825776b7a3SDavid Hunt pcpu = info.pcpu_map[pol->pkt.vcpu_to_control[count]]; 3833618326fSDavid Hunt pcpu_monitor(pol, ci, pcpu, count); 3843618326fSDavid Hunt } 385b89168efSDavid Hunt } else { 3863618326fSDavid Hunt /* 3873618326fSDavid Hunt * If the cores in the policy are physical, we just use 3883618326fSDavid Hunt * those core id's directly. 3893618326fSDavid Hunt */ 3903618326fSDavid Hunt for (count = 0; count < pol->pkt.num_vcpu; count++) { 3913618326fSDavid Hunt pcpu = pol->pkt.vcpu_to_control[count]; 3923618326fSDavid Hunt pcpu_monitor(pol, ci, pcpu, count); 393f14791a8SRory Sexton } 394f14791a8SRory Sexton } 395f14791a8SRory Sexton } 396f14791a8SRory Sexton 397f14791a8SRory Sexton static int 398f14791a8SRory Sexton get_pfid(struct policy *pol) 399f14791a8SRory Sexton { 400f14791a8SRory Sexton 4018728ccf3SThomas Monjalon int i, x, ret = 0; 402f14791a8SRory Sexton 403f14791a8SRory Sexton for (i = 0; i < pol->pkt.nb_mac_to_monitor; i++) { 404f14791a8SRory Sexton 4058728ccf3SThomas Monjalon RTE_ETH_FOREACH_DEV(x) { 406f14791a8SRory Sexton ret = rte_pmd_i40e_query_vfid_by_mac(x, 407f14791a8SRory Sexton (struct ether_addr *)&(pol->pkt.vfid[i])); 408f14791a8SRory Sexton if (ret != -EINVAL) { 409f14791a8SRory Sexton pol->port[i] = x; 410f14791a8SRory Sexton break; 411f14791a8SRory Sexton } 412f14791a8SRory Sexton } 413f14791a8SRory Sexton if (ret == -EINVAL || ret == -ENOTSUP || ret == ENODEV) { 414f14791a8SRory Sexton RTE_LOG(INFO, CHANNEL_MONITOR, 415f14791a8SRory Sexton "Error with Policy. MAC not found on " 416f14791a8SRory Sexton "attached ports "); 417f14791a8SRory Sexton pol->enabled = 0; 418f14791a8SRory Sexton return ret; 419f14791a8SRory Sexton } 420f14791a8SRory Sexton pol->pfid[i] = ret; 421f14791a8SRory Sexton } 422f14791a8SRory Sexton return 1; 423f14791a8SRory Sexton } 424f14791a8SRory Sexton 425f14791a8SRory Sexton static int 426f14791a8SRory Sexton update_policy(struct channel_packet *pkt) 427f14791a8SRory Sexton { 428f14791a8SRory Sexton 429f14791a8SRory Sexton unsigned int updated = 0; 4307abd801fSDavid Hunt int i; 431f14791a8SRory Sexton 4323618326fSDavid Hunt 4333618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 4343618326fSDavid Hunt "Applying policy for %s\n", pkt->vm_name); 4353618326fSDavid Hunt 43690a774c4SDavid Hunt for (i = 0; i < MAX_CLIENTS; i++) { 437f14791a8SRory Sexton if (strcmp(policies[i].pkt.vm_name, pkt->vm_name) == 0) { 4383618326fSDavid Hunt /* Copy the contents of *pkt into the policy.pkt */ 439f14791a8SRory Sexton policies[i].pkt = *pkt; 440f14791a8SRory Sexton get_pcpu_to_control(&policies[i]); 441236e164bSLukasz Krakowiak /* Check Eth dev only for Traffic policy */ 442236e164bSLukasz Krakowiak if (policies[i].pkt.policy_to_use == TRAFFIC) { 4431b897991SLukasz Krakowiak if (get_pfid(&policies[i]) < 0) { 444f14791a8SRory Sexton updated = 1; 445f14791a8SRory Sexton break; 446f14791a8SRory Sexton } 447236e164bSLukasz Krakowiak } 448f14791a8SRory Sexton core_share_status(i); 449f14791a8SRory Sexton policies[i].enabled = 1; 450f14791a8SRory Sexton updated = 1; 451f14791a8SRory Sexton } 452f14791a8SRory Sexton } 453f14791a8SRory Sexton if (!updated) { 45490a774c4SDavid Hunt for (i = 0; i < MAX_CLIENTS; i++) { 455f14791a8SRory Sexton if (policies[i].enabled == 0) { 456f14791a8SRory Sexton policies[i].pkt = *pkt; 457f14791a8SRory Sexton get_pcpu_to_control(&policies[i]); 458236e164bSLukasz Krakowiak /* Check Eth dev only for Traffic policy */ 459236e164bSLukasz Krakowiak if (policies[i].pkt.policy_to_use == TRAFFIC) { 460236e164bSLukasz Krakowiak if (get_pfid(&policies[i]) < 0) { 461236e164bSLukasz Krakowiak updated = 1; 462f14791a8SRory Sexton break; 463236e164bSLukasz Krakowiak } 464236e164bSLukasz Krakowiak } 465f14791a8SRory Sexton core_share_status(i); 466f14791a8SRory Sexton policies[i].enabled = 1; 467f14791a8SRory Sexton break; 468f14791a8SRory Sexton } 469f14791a8SRory Sexton } 470f14791a8SRory Sexton } 471f14791a8SRory Sexton return 0; 472f14791a8SRory Sexton } 473f14791a8SRory Sexton 4743618326fSDavid Hunt static int 4753618326fSDavid Hunt remove_policy(struct channel_packet *pkt __rte_unused) 4763618326fSDavid Hunt { 4773618326fSDavid Hunt int i; 4783618326fSDavid Hunt 4793618326fSDavid Hunt /* 4803618326fSDavid Hunt * Disabling the policy is simply a case of setting 4813618326fSDavid Hunt * enabled to 0 4823618326fSDavid Hunt */ 48390a774c4SDavid Hunt for (i = 0; i < MAX_CLIENTS; i++) { 4843618326fSDavid Hunt if (strcmp(policies[i].pkt.vm_name, pkt->vm_name) == 0) { 4853618326fSDavid Hunt policies[i].enabled = 0; 4863618326fSDavid Hunt return 0; 4873618326fSDavid Hunt } 4883618326fSDavid Hunt } 4893618326fSDavid Hunt return -1; 4903618326fSDavid Hunt } 4913618326fSDavid Hunt 492f14791a8SRory Sexton static uint64_t 493f14791a8SRory Sexton get_pkt_diff(struct policy *pol) 494f14791a8SRory Sexton { 495f14791a8SRory Sexton 496f14791a8SRory Sexton uint64_t vsi_pkt_count, 497f14791a8SRory Sexton vsi_pkt_total = 0, 498f14791a8SRory Sexton vsi_pkt_count_prev_total = 0; 499f14791a8SRory Sexton double rdtsc_curr, rdtsc_diff, diff; 500f14791a8SRory Sexton int x; 501f14791a8SRory Sexton struct rte_eth_stats vf_stats; 502f14791a8SRory Sexton 503f14791a8SRory Sexton for (x = 0; x < pol->pkt.nb_mac_to_monitor; x++) { 504f14791a8SRory Sexton 505f14791a8SRory Sexton /*Read vsi stats*/ 506f14791a8SRory Sexton if (rte_pmd_i40e_get_vf_stats(x, pol->pfid[x], &vf_stats) == 0) 507f14791a8SRory Sexton vsi_pkt_count = vf_stats.ipackets; 508f14791a8SRory Sexton else 509f14791a8SRory Sexton vsi_pkt_count = -1; 510f14791a8SRory Sexton 511f14791a8SRory Sexton vsi_pkt_total += vsi_pkt_count; 512f14791a8SRory Sexton 513f14791a8SRory Sexton vsi_pkt_count_prev_total += vsi_pkt_count_prev[pol->pfid[x]]; 514f14791a8SRory Sexton vsi_pkt_count_prev[pol->pfid[x]] = vsi_pkt_count; 515f14791a8SRory Sexton } 516f14791a8SRory Sexton 517f14791a8SRory Sexton rdtsc_curr = rte_rdtsc_precise(); 518f14791a8SRory Sexton rdtsc_diff = rdtsc_curr - rdtsc_prev[pol->pfid[x-1]]; 519f14791a8SRory Sexton rdtsc_prev[pol->pfid[x-1]] = rdtsc_curr; 520f14791a8SRory Sexton 521f14791a8SRory Sexton diff = (vsi_pkt_total - vsi_pkt_count_prev_total) * 522f14791a8SRory Sexton ((double)rte_get_tsc_hz() / rdtsc_diff); 523f14791a8SRory Sexton 524f14791a8SRory Sexton return diff; 525f14791a8SRory Sexton } 526f14791a8SRory Sexton 527f14791a8SRory Sexton static void 528f14791a8SRory Sexton apply_traffic_profile(struct policy *pol) 529f14791a8SRory Sexton { 530f14791a8SRory Sexton 531f14791a8SRory Sexton int count; 532f14791a8SRory Sexton uint64_t diff = 0; 533f14791a8SRory Sexton 534f14791a8SRory Sexton diff = get_pkt_diff(pol); 535f14791a8SRory Sexton 536f14791a8SRory Sexton if (diff >= (pol->pkt.traffic_policy.max_max_packet_thresh)) { 537f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 538f14791a8SRory Sexton if (pol->core_share[count].status != 1) 539f14791a8SRory Sexton power_manager_scale_core_max( 540f14791a8SRory Sexton pol->core_share[count].pcpu); 541f14791a8SRory Sexton } 542f14791a8SRory Sexton } else if (diff >= (pol->pkt.traffic_policy.avg_max_packet_thresh)) { 543f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 544f14791a8SRory Sexton if (pol->core_share[count].status != 1) 545f14791a8SRory Sexton power_manager_scale_core_med( 546f14791a8SRory Sexton pol->core_share[count].pcpu); 547f14791a8SRory Sexton } 548f14791a8SRory Sexton } else if (diff < (pol->pkt.traffic_policy.avg_max_packet_thresh)) { 549f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 550f14791a8SRory Sexton if (pol->core_share[count].status != 1) 551f14791a8SRory Sexton power_manager_scale_core_min( 552f14791a8SRory Sexton pol->core_share[count].pcpu); 553f14791a8SRory Sexton } 554f14791a8SRory Sexton } 555f14791a8SRory Sexton } 556f14791a8SRory Sexton 557f14791a8SRory Sexton static void 558f14791a8SRory Sexton apply_time_profile(struct policy *pol) 559f14791a8SRory Sexton { 560f14791a8SRory Sexton 561f14791a8SRory Sexton int count, x; 562f14791a8SRory Sexton struct timeval tv; 563f14791a8SRory Sexton struct tm *ptm; 564f14791a8SRory Sexton char time_string[40]; 565f14791a8SRory Sexton 566f14791a8SRory Sexton /* Obtain the time of day, and convert it to a tm struct. */ 567f14791a8SRory Sexton gettimeofday(&tv, NULL); 568f14791a8SRory Sexton ptm = localtime(&tv.tv_sec); 569f14791a8SRory Sexton /* Format the date and time, down to a single second. */ 570f14791a8SRory Sexton strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", ptm); 571f14791a8SRory Sexton 572f14791a8SRory Sexton for (x = 0; x < HOURS; x++) { 573f14791a8SRory Sexton 574f14791a8SRory Sexton if (ptm->tm_hour == pol->pkt.timer_policy.busy_hours[x]) { 575f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 576f14791a8SRory Sexton if (pol->core_share[count].status != 1) { 577f14791a8SRory Sexton power_manager_scale_core_max( 578f14791a8SRory Sexton pol->core_share[count].pcpu); 579f14791a8SRory Sexton } 580f14791a8SRory Sexton } 581f14791a8SRory Sexton break; 582f14791a8SRory Sexton } else if (ptm->tm_hour == 583f14791a8SRory Sexton pol->pkt.timer_policy.quiet_hours[x]) { 584f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 585f14791a8SRory Sexton if (pol->core_share[count].status != 1) { 586f14791a8SRory Sexton power_manager_scale_core_min( 587f14791a8SRory Sexton pol->core_share[count].pcpu); 588f14791a8SRory Sexton } 589f14791a8SRory Sexton } 590f14791a8SRory Sexton break; 591f14791a8SRory Sexton } else if (ptm->tm_hour == 592f14791a8SRory Sexton pol->pkt.timer_policy.hours_to_use_traffic_profile[x]) { 593f14791a8SRory Sexton apply_traffic_profile(pol); 594f14791a8SRory Sexton break; 595f14791a8SRory Sexton } 596f14791a8SRory Sexton } 597f14791a8SRory Sexton } 598f14791a8SRory Sexton 599f14791a8SRory Sexton static void 600f14791a8SRory Sexton apply_workload_profile(struct policy *pol) 601f14791a8SRory Sexton { 602f14791a8SRory Sexton 603f14791a8SRory Sexton int count; 604f14791a8SRory Sexton 605f14791a8SRory Sexton if (pol->pkt.workload == HIGH) { 606f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 607f14791a8SRory Sexton if (pol->core_share[count].status != 1) 608f14791a8SRory Sexton power_manager_scale_core_max( 609f14791a8SRory Sexton pol->core_share[count].pcpu); 610f14791a8SRory Sexton } 611f14791a8SRory Sexton } else if (pol->pkt.workload == MEDIUM) { 612f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 613f14791a8SRory Sexton if (pol->core_share[count].status != 1) 614f14791a8SRory Sexton power_manager_scale_core_med( 615f14791a8SRory Sexton pol->core_share[count].pcpu); 616f14791a8SRory Sexton } 617f14791a8SRory Sexton } else if (pol->pkt.workload == LOW) { 618f14791a8SRory Sexton for (count = 0; count < pol->pkt.num_vcpu; count++) { 619f14791a8SRory Sexton if (pol->core_share[count].status != 1) 620f14791a8SRory Sexton power_manager_scale_core_min( 621f14791a8SRory Sexton pol->core_share[count].pcpu); 622f14791a8SRory Sexton } 623f14791a8SRory Sexton } 624f14791a8SRory Sexton } 625f14791a8SRory Sexton 626f14791a8SRory Sexton static void 627f14791a8SRory Sexton apply_policy(struct policy *pol) 628f14791a8SRory Sexton { 629f14791a8SRory Sexton 630f14791a8SRory Sexton struct channel_packet *pkt = &pol->pkt; 631f14791a8SRory Sexton 632f14791a8SRory Sexton /*Check policy to use*/ 633f14791a8SRory Sexton if (pkt->policy_to_use == TRAFFIC) 634f14791a8SRory Sexton apply_traffic_profile(pol); 635f14791a8SRory Sexton else if (pkt->policy_to_use == TIME) 636f14791a8SRory Sexton apply_time_profile(pol); 637f14791a8SRory Sexton else if (pkt->policy_to_use == WORKLOAD) 638f14791a8SRory Sexton apply_workload_profile(pol); 639f14791a8SRory Sexton } 640f14791a8SRory Sexton 641e8ae9b66SAlan Carew static int 642e8ae9b66SAlan Carew process_request(struct channel_packet *pkt, struct channel_info *chan_info) 643e8ae9b66SAlan Carew { 644d7b713d0SLukasz Krakowiak int ret; 645d7b713d0SLukasz Krakowiak 646e8ae9b66SAlan Carew if (chan_info == NULL) 647e8ae9b66SAlan Carew return -1; 648e8ae9b66SAlan Carew 649e8ae9b66SAlan Carew if (rte_atomic32_cmpset(&(chan_info->status), CHANNEL_MGR_CHANNEL_CONNECTED, 650e8ae9b66SAlan Carew CHANNEL_MGR_CHANNEL_PROCESSING) == 0) 651e8ae9b66SAlan Carew return -1; 652e8ae9b66SAlan Carew 653e8ae9b66SAlan Carew if (pkt->command == CPU_POWER) { 6545776b7a3SDavid Hunt unsigned int core_num; 655e8ae9b66SAlan Carew 656d38e6a6aSDavid Hunt if (pkt->core_type == CORE_TYPE_VIRTUAL) 6575776b7a3SDavid Hunt core_num = get_pcpu(chan_info, pkt->resource_id); 658d38e6a6aSDavid Hunt else 659d38e6a6aSDavid Hunt core_num = pkt->resource_id; 660e8ae9b66SAlan Carew 661d7b713d0SLukasz Krakowiak RTE_LOG(DEBUG, CHANNEL_MONITOR, "Processing requested cmd for cpu:%d\n", 662d7b713d0SLukasz Krakowiak core_num); 663d7b713d0SLukasz Krakowiak 664e8ae9b66SAlan Carew switch (pkt->unit) { 665e8ae9b66SAlan Carew case(CPU_POWER_SCALE_MIN): 666e8ae9b66SAlan Carew power_manager_scale_core_min(core_num); 667e8ae9b66SAlan Carew break; 668e8ae9b66SAlan Carew case(CPU_POWER_SCALE_MAX): 669e8ae9b66SAlan Carew power_manager_scale_core_max(core_num); 670e8ae9b66SAlan Carew break; 671e8ae9b66SAlan Carew case(CPU_POWER_SCALE_DOWN): 672e8ae9b66SAlan Carew power_manager_scale_core_down(core_num); 673e8ae9b66SAlan Carew break; 674e8ae9b66SAlan Carew case(CPU_POWER_SCALE_UP): 675e8ae9b66SAlan Carew power_manager_scale_core_up(core_num); 676e8ae9b66SAlan Carew break; 677567997b9SDavid Hunt case(CPU_POWER_ENABLE_TURBO): 678567997b9SDavid Hunt power_manager_enable_turbo_core(core_num); 679567997b9SDavid Hunt break; 680567997b9SDavid Hunt case(CPU_POWER_DISABLE_TURBO): 681567997b9SDavid Hunt power_manager_disable_turbo_core(core_num); 682567997b9SDavid Hunt break; 683e8ae9b66SAlan Carew default: 684e8ae9b66SAlan Carew break; 685e8ae9b66SAlan Carew } 686e8ae9b66SAlan Carew } 687f14791a8SRory Sexton 688f14791a8SRory Sexton if (pkt->command == PKT_POLICY) { 689ce4a2766SDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, "Processing policy request %s\n", 690ce4a2766SDavid Hunt pkt->vm_name); 691f14791a8SRory Sexton update_policy(pkt); 692f14791a8SRory Sexton policy_is_set = 1; 693f14791a8SRory Sexton } 694f14791a8SRory Sexton 6953618326fSDavid Hunt if (pkt->command == PKT_POLICY_REMOVE) { 696d7b713d0SLukasz Krakowiak ret = remove_policy(pkt); 697d7b713d0SLukasz Krakowiak if (ret == 0) 6983618326fSDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 699d7b713d0SLukasz Krakowiak "Removed policy %s\n", pkt->vm_name); 700d7b713d0SLukasz Krakowiak else 701d7b713d0SLukasz Krakowiak RTE_LOG(INFO, CHANNEL_MONITOR, 702d7b713d0SLukasz Krakowiak "Policy %s does not exist\n", pkt->vm_name); 7033618326fSDavid Hunt } 7043618326fSDavid Hunt 7053618326fSDavid Hunt /* 7063618326fSDavid Hunt * Return is not checked as channel status may have been set to DISABLED 707e8ae9b66SAlan Carew * from management thread 708e8ae9b66SAlan Carew */ 709e8ae9b66SAlan Carew rte_atomic32_cmpset(&(chan_info->status), CHANNEL_MGR_CHANNEL_PROCESSING, 710e8ae9b66SAlan Carew CHANNEL_MGR_CHANNEL_CONNECTED); 711e8ae9b66SAlan Carew return 0; 712e8ae9b66SAlan Carew 713e8ae9b66SAlan Carew } 714e8ae9b66SAlan Carew 715e8ae9b66SAlan Carew int 716e8ae9b66SAlan Carew add_channel_to_monitor(struct channel_info **chan_info) 717e8ae9b66SAlan Carew { 718e8ae9b66SAlan Carew struct channel_info *info = *chan_info; 719e8ae9b66SAlan Carew struct epoll_event event; 720e8ae9b66SAlan Carew 721e8ae9b66SAlan Carew event.events = EPOLLIN; 722e8ae9b66SAlan Carew event.data.ptr = info; 723e8ae9b66SAlan Carew if (epoll_ctl(global_event_fd, EPOLL_CTL_ADD, info->fd, &event) < 0) { 724e8ae9b66SAlan Carew RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to add channel '%s' " 725e8ae9b66SAlan Carew "to epoll\n", info->channel_path); 726e8ae9b66SAlan Carew return -1; 727e8ae9b66SAlan Carew } 7283618326fSDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, "Added channel '%s' " 7293618326fSDavid Hunt "to monitor\n", info->channel_path); 730e8ae9b66SAlan Carew return 0; 731e8ae9b66SAlan Carew } 732e8ae9b66SAlan Carew 733e8ae9b66SAlan Carew int 734e8ae9b66SAlan Carew remove_channel_from_monitor(struct channel_info *chan_info) 735e8ae9b66SAlan Carew { 7363618326fSDavid Hunt if (epoll_ctl(global_event_fd, EPOLL_CTL_DEL, 7373618326fSDavid Hunt chan_info->fd, NULL) < 0) { 738e8ae9b66SAlan Carew RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to remove channel '%s' " 739e8ae9b66SAlan Carew "from epoll\n", chan_info->channel_path); 740e8ae9b66SAlan Carew return -1; 741e8ae9b66SAlan Carew } 742e8ae9b66SAlan Carew return 0; 743e8ae9b66SAlan Carew } 744e8ae9b66SAlan Carew 745e8ae9b66SAlan Carew int 746e8ae9b66SAlan Carew channel_monitor_init(void) 747e8ae9b66SAlan Carew { 748e8ae9b66SAlan Carew global_event_fd = epoll_create1(0); 749e8ae9b66SAlan Carew if (global_event_fd == 0) { 7503618326fSDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 7513618326fSDavid Hunt "Error creating epoll context with error %s\n", 7523618326fSDavid Hunt strerror(errno)); 753e8ae9b66SAlan Carew return -1; 754e8ae9b66SAlan Carew } 7553618326fSDavid Hunt global_events_list = rte_malloc("epoll_events", 7563618326fSDavid Hunt sizeof(*global_events_list) 757fdf20fa7SSergio Gonzalez Monroy * MAX_EVENTS, RTE_CACHE_LINE_SIZE); 758e8ae9b66SAlan Carew if (global_events_list == NULL) { 759e8ae9b66SAlan Carew RTE_LOG(ERR, CHANNEL_MONITOR, "Unable to rte_malloc for " 760e8ae9b66SAlan Carew "epoll events\n"); 761e8ae9b66SAlan Carew return -1; 762e8ae9b66SAlan Carew } 763e8ae9b66SAlan Carew return 0; 764e8ae9b66SAlan Carew } 765e8ae9b66SAlan Carew 766a63504a9SDavid Hunt static void 767a63504a9SDavid Hunt read_binary_packet(struct channel_info *chan_info) 768a63504a9SDavid Hunt { 769a63504a9SDavid Hunt struct channel_packet pkt; 770a63504a9SDavid Hunt void *buffer = &pkt; 771a63504a9SDavid Hunt int buffer_len = sizeof(pkt); 772a63504a9SDavid Hunt int n_bytes, err = 0; 773a63504a9SDavid Hunt 774a63504a9SDavid Hunt while (buffer_len > 0) { 775a63504a9SDavid Hunt n_bytes = read(chan_info->fd, 776a63504a9SDavid Hunt buffer, buffer_len); 777a63504a9SDavid Hunt if (n_bytes == buffer_len) 778a63504a9SDavid Hunt break; 7791b897991SLukasz Krakowiak if (n_bytes < 0) { 780a63504a9SDavid Hunt err = errno; 781a63504a9SDavid Hunt RTE_LOG(DEBUG, CHANNEL_MONITOR, 782a63504a9SDavid Hunt "Received error on " 783a63504a9SDavid Hunt "channel '%s' read: %s\n", 784a63504a9SDavid Hunt chan_info->channel_path, 785a63504a9SDavid Hunt strerror(err)); 786a63504a9SDavid Hunt remove_channel(&chan_info); 787a63504a9SDavid Hunt break; 788a63504a9SDavid Hunt } 789a63504a9SDavid Hunt buffer = (char *)buffer + n_bytes; 790a63504a9SDavid Hunt buffer_len -= n_bytes; 791a63504a9SDavid Hunt } 792a63504a9SDavid Hunt if (!err) 793a63504a9SDavid Hunt process_request(&pkt, chan_info); 794a63504a9SDavid Hunt } 795a63504a9SDavid Hunt 796a63504a9SDavid Hunt #ifdef USE_JANSSON 797a63504a9SDavid Hunt static void 798a63504a9SDavid Hunt read_json_packet(struct channel_info *chan_info) 799a63504a9SDavid Hunt { 800a63504a9SDavid Hunt struct channel_packet pkt; 801a63504a9SDavid Hunt int n_bytes, ret; 802a63504a9SDavid Hunt json_t *root; 803a63504a9SDavid Hunt json_error_t error; 804a63504a9SDavid Hunt 805a63504a9SDavid Hunt /* read opening brace to closing brace */ 806a63504a9SDavid Hunt do { 807a63504a9SDavid Hunt int idx = 0; 808a63504a9SDavid Hunt int indent = 0; 809a63504a9SDavid Hunt do { 810a63504a9SDavid Hunt n_bytes = read(chan_info->fd, &json_data[idx], 1); 811a63504a9SDavid Hunt if (n_bytes == 0) 812a63504a9SDavid Hunt break; 813a63504a9SDavid Hunt if (json_data[idx] == '{') 814a63504a9SDavid Hunt indent++; 815a63504a9SDavid Hunt if (json_data[idx] == '}') 816a63504a9SDavid Hunt indent--; 817a63504a9SDavid Hunt if ((indent > 0) || (idx > 0)) 818a63504a9SDavid Hunt idx++; 8194c2caea0SReshma Pattan if (indent <= 0) 820a63504a9SDavid Hunt json_data[idx] = 0; 821a63504a9SDavid Hunt if (idx >= MAX_JSON_STRING_LEN-1) 822a63504a9SDavid Hunt break; 823a63504a9SDavid Hunt } while (indent > 0); 824a63504a9SDavid Hunt 825*8f8f876bSDavid Hunt json_data[idx] = '\0'; 826a63504a9SDavid Hunt 827a63504a9SDavid Hunt if (strlen(json_data) == 0) 828a63504a9SDavid Hunt continue; 829a63504a9SDavid Hunt 830a63504a9SDavid Hunt printf("got [%s]\n", json_data); 831a63504a9SDavid Hunt 832a63504a9SDavid Hunt root = json_loads(json_data, 0, &error); 833a63504a9SDavid Hunt 834a63504a9SDavid Hunt if (root) { 835a63504a9SDavid Hunt /* 836a63504a9SDavid Hunt * Because our data is now in the json 837a63504a9SDavid Hunt * object, we can overwrite the pkt 838a63504a9SDavid Hunt * with a channel_packet struct, using 839a63504a9SDavid Hunt * parse_json_to_pkt() 840a63504a9SDavid Hunt */ 841a63504a9SDavid Hunt ret = parse_json_to_pkt(root, &pkt); 842a63504a9SDavid Hunt json_decref(root); 843a63504a9SDavid Hunt if (ret) { 844a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 845a63504a9SDavid Hunt "Error validating JSON profile data\n"); 846a63504a9SDavid Hunt break; 847a63504a9SDavid Hunt } 848a63504a9SDavid Hunt process_request(&pkt, chan_info); 849a63504a9SDavid Hunt } else { 850a63504a9SDavid Hunt RTE_LOG(ERR, CHANNEL_MONITOR, 851a63504a9SDavid Hunt "JSON error on line %d: %s\n", 852a63504a9SDavid Hunt error.line, error.text); 853a63504a9SDavid Hunt } 854a63504a9SDavid Hunt } while (n_bytes > 0); 855a63504a9SDavid Hunt } 856a63504a9SDavid Hunt #endif 857a63504a9SDavid Hunt 858e8ae9b66SAlan Carew void 859e8ae9b66SAlan Carew run_channel_monitor(void) 860e8ae9b66SAlan Carew { 861e8ae9b66SAlan Carew while (run_loop) { 862e8ae9b66SAlan Carew int n_events, i; 863e8ae9b66SAlan Carew 864e8ae9b66SAlan Carew n_events = epoll_wait(global_event_fd, global_events_list, 865e8ae9b66SAlan Carew MAX_EVENTS, 1); 866e8ae9b66SAlan Carew if (!run_loop) 867e8ae9b66SAlan Carew break; 868e8ae9b66SAlan Carew for (i = 0; i < n_events; i++) { 869e8ae9b66SAlan Carew struct channel_info *chan_info = (struct channel_info *) 870e8ae9b66SAlan Carew global_events_list[i].data.ptr; 871e8ae9b66SAlan Carew if ((global_events_list[i].events & EPOLLERR) || 872e8ae9b66SAlan Carew (global_events_list[i].events & EPOLLHUP)) { 873ce4a2766SDavid Hunt RTE_LOG(INFO, CHANNEL_MONITOR, 874ce4a2766SDavid Hunt "Remote closed connection for " 875f14791a8SRory Sexton "channel '%s'\n", 876f14791a8SRory Sexton chan_info->channel_path); 877e8ae9b66SAlan Carew remove_channel(&chan_info); 878e8ae9b66SAlan Carew continue; 879e8ae9b66SAlan Carew } 880e8ae9b66SAlan Carew if (global_events_list[i].events & EPOLLIN) { 881e8ae9b66SAlan Carew 882a63504a9SDavid Hunt switch (chan_info->type) { 883a63504a9SDavid Hunt case CHANNEL_TYPE_BINARY: 884a63504a9SDavid Hunt read_binary_packet(chan_info); 885e8ae9b66SAlan Carew break; 886a63504a9SDavid Hunt #ifdef USE_JANSSON 887a63504a9SDavid Hunt case CHANNEL_TYPE_JSON: 888a63504a9SDavid Hunt read_json_packet(chan_info); 889a63504a9SDavid Hunt break; 890a63504a9SDavid Hunt #endif 891a63504a9SDavid Hunt default: 892e8ae9b66SAlan Carew break; 893e8ae9b66SAlan Carew } 894e8ae9b66SAlan Carew } 895e8ae9b66SAlan Carew } 896e4f66da3SDavid Hunt rte_delay_us(time_period_ms*1000); 897f14791a8SRory Sexton if (policy_is_set) { 8987abd801fSDavid Hunt int j; 8997abd801fSDavid Hunt 90090a774c4SDavid Hunt for (j = 0; j < MAX_CLIENTS; j++) { 901f14791a8SRory Sexton if (policies[j].enabled == 1) 902f14791a8SRory Sexton apply_policy(&policies[j]); 903f14791a8SRory Sexton } 904f14791a8SRory Sexton } 905e8ae9b66SAlan Carew } 906e8ae9b66SAlan Carew } 907