- DEBUG(RDT_PLUGIN ": group[%d]:", (int)i);
- DEBUG(RDT_PLUGIN ": description: %s", g_rdt->ngroups[i].desc);
- DEBUG(RDT_PLUGIN ": process names:%s", names);
- DEBUG(RDT_PLUGIN ": events: 0x%X", g_rdt->ngroups[i].events);
- }
-
- return;
-}
-#endif /* LIBPQOS2 */
-
-static inline double bytes_to_kb(const double bytes) { return bytes / 1024.0; }
-
-static inline double bytes_to_mb(const double bytes) {
- return bytes / (1024.0 * 1024.0);
-}
-
-static void rdt_dump_cores_data(void) {
-/*
- * CORE - monitored group of cores
- * RMID - Resource Monitoring ID associated with the monitored group
- * This is not available for monitoring with resource control
- * LLC - last level cache occupancy
- * MBL - local memory bandwidth
- * MBR - remote memory bandwidth
- */
-#ifdef LIBPQOS2
- if (g_interface == PQOS_INTER_OS_RESCTRL_MON) {
- DEBUG(RDT_PLUGIN ": CORE LLC[KB] MBL[MB] MBR[MB]");
- } else {
- DEBUG(RDT_PLUGIN ": CORE RMID LLC[KB] MBL[MB] MBR[MB]");
- }
-#else
- DEBUG(RDT_PLUGIN ": CORE RMID LLC[KB] MBL[MB] MBR[MB]");
-#endif /* LIBPQOS2 */
-
- for (size_t i = 0; i < g_rdt->cores.num_cgroups; i++) {
- const struct pqos_event_values *pv = &g_rdt->pcgroups[i]->values;
-
- double llc = bytes_to_kb(pv->llc);
- double mbr = bytes_to_mb(pv->mbm_remote_delta);
- double mbl = bytes_to_mb(pv->mbm_local_delta);
-#ifdef LIBPQOS2
- if (g_interface == PQOS_INTER_OS_RESCTRL_MON) {
- DEBUG(RDT_PLUGIN ": [%s] %10.1f %10.1f %10.1f",
- g_rdt->cores.cgroups[i].desc, llc, mbl, mbr);
- } else {
- DEBUG(RDT_PLUGIN ": [%s] %8u %10.1f %10.1f %10.1f",
- g_rdt->cores.cgroups[i].desc, g_rdt->pcgroups[i]->poll_ctx[0].rmid,
- llc, mbl, mbr);
- }
-#else
- DEBUG(RDT_PLUGIN ": [%s] %8u %10.1f %10.1f %10.1f",
- g_rdt->cores.cgroups[i].desc, g_rdt->pcgroups[i]->poll_ctx[0].rmid,
- llc, mbl, mbr);
-#endif /* LIBPQOS2 */
- }
-}
-
-#ifdef LIBPQOS2
-static void rdt_dump_pids_data(void) {
- /*
- * NAME - monitored group of processes
- * PIDs - list of PID numbers in the NAME group
- * LLC - last level cache occupancy
- * MBL - local memory bandwidth
- * MBR - remote memory bandwidth
- */
-
- DEBUG(RDT_PLUGIN ": NAME PIDs");
- char pids[DATA_MAX_NAME_LEN];
- for (size_t i = 0; i < g_rdt->num_ngroups; ++i) {
- memset(pids, 0, sizeof(pids));
- for (size_t j = 0; j < g_rdt->ngroups[i].num_names; ++j) {
- pids_list_t *list = g_rdt->ngroups[i].proc_pids_array[j].pids;
- while (list != NULL) {
- snprintf(pids + strlen(pids), sizeof(pids) - strlen(pids) - 1, " %u",
- list->pid);
- list = list->next;
- }
- }
- DEBUG(RDT_PLUGIN ": [%s] %s", g_rdt->ngroups[i].desc, pids);
- }
-
- DEBUG(RDT_PLUGIN ": NAME LLC[KB] MBL[MB] MBR[MB]");
- for (size_t i = 0; i < g_rdt->num_ngroups; i++) {
-
- const struct pqos_event_values *pv = &g_rdt->pngroups[i]->values;
-
- double llc = bytes_to_kb(pv->llc);
- double mbr = bytes_to_mb(pv->mbm_remote_delta);
- double mbl = bytes_to_mb(pv->mbm_local_delta);
-
- DEBUG(RDT_PLUGIN ": [%s] %10.1f %10.1f %10.1f", g_rdt->ngroups[i].desc,
- llc, mbl, mbr);
- }
-}
-#endif /* LIBPQOS2 */
-#endif /* COLLECT_DEBUG */
-
-static void rdt_free_cgroups(void) {
- config_cores_cleanup(&g_rdt->cores);
- for (int i = 0; i < RDT_MAX_CORES; i++) {
- sfree(g_rdt->pcgroups[i]);
- }
-}
-
-#ifdef LIBPQOS2
-static int pids_list_free(pids_list_t *list) {
- assert(list);
-
- pids_list_t *current = list;
- while (current != NULL) {
- pids_list_t *previous = current;
- current = current->next;
- sfree(previous);
- }
- return 0;
-}
-
-static void rdt_free_ngroups(rdt_ctx_t *rdt) {
- for (int i = 0; i < RDT_MAX_NAMES_GROUPS; i++) {
- if (rdt->ngroups[i].desc)
- DEBUG(RDT_PLUGIN ": Freeing pids \'%s\' group\'s data...",
- rdt->ngroups[i].desc);
- sfree(rdt->ngroups[i].desc);
-
- strarray_free(rdt->ngroups[i].names, rdt->ngroups[i].num_names);
-
- if (rdt->ngroups[i].proc_pids_array) {
- for (size_t j = 0; j < rdt->ngroups[i].num_names; ++j) {
- if (NULL == rdt->ngroups[i].proc_pids_array[j].pids)
- continue;
- pids_list_free(rdt->ngroups[i].proc_pids_array[j].pids);
- }
-
- sfree(rdt->ngroups[i].proc_pids_array);
- }
-
- rdt->ngroups[i].num_names = 0;
- sfree(rdt->pngroups[i]);
- }
-}
-#endif /* LIBPQOS2 */
-
-static int rdt_default_cgroups(void) {
- unsigned num_cores = g_rdt->pqos_cpu->num_cores;
-
- g_rdt->cores.cgroups = calloc(num_cores, sizeof(*g_rdt->cores.cgroups));
- if (g_rdt->cores.cgroups == NULL) {
- ERROR(RDT_PLUGIN ": Error allocating core groups array");
- return -ENOMEM;
- }
- g_rdt->cores.num_cgroups = num_cores;
-
- /* configure each core in separate group */
- for (unsigned i = 0; i < num_cores; i++) {
- core_group_t *cgroup = g_rdt->cores.cgroups + i;
- char desc[DATA_MAX_NAME_LEN];
-
- /* set core group info */
- cgroup->cores = calloc(1, sizeof(*cgroup->cores));
- if (cgroup->cores == NULL) {
- ERROR(RDT_PLUGIN ": Error allocating cores array");
- rdt_free_cgroups();
- return -ENOMEM;
- }
- cgroup->num_cores = 1;
- cgroup->cores[0] = i;
-
- snprintf(desc, sizeof(desc), "%d", g_rdt->pqos_cpu->cores[i].lcore);
- cgroup->desc = strdup(desc);
- if (cgroup->desc == NULL) {
- ERROR(RDT_PLUGIN ": Error allocating core group description");
- rdt_free_cgroups();
- return -ENOMEM;
- }
- }
-
- return num_cores;
-}
-
-static int rdt_is_core_id_valid(unsigned int core_id) {
-
- for (unsigned int i = 0; i < g_rdt->pqos_cpu->num_cores; i++)
- if (core_id == g_rdt->pqos_cpu->cores[i].lcore)
- return 1;
-
- return 0;
-}
-
-#ifdef LIBPQOS2
-static int rdt_is_proc_name_valid(const char *name) {
-
- if (name != NULL) {
- unsigned len = strlen(name);
- if (len > 0 && len <= RDT_MAX_NAME_LEN)
- return 1;
- else {
- DEBUG(RDT_PLUGIN
- ": Process name \'%s\' is too long. Max supported len is %d chars.",
- name, RDT_MAX_NAME_LEN);
- }
- }
-
- return 0;
-}
-#endif /* LIBPQOS2 */
-
-static int rdt_config_cgroups(oconfig_item_t *item) {
- size_t n = 0;
- enum pqos_mon_event events = 0;
-
- if (config_cores_parse(item, &g_rdt->cores) < 0) {
- rdt_free_cgroups();
- ERROR(RDT_PLUGIN ": Error parsing core groups configuration.");
- return -EINVAL;
- }
- n = g_rdt->cores.num_cgroups;
-
- /* validate configured core id values */
- for (size_t group_idx = 0; group_idx < n; group_idx++) {
- core_group_t *cgroup = g_rdt->cores.cgroups + group_idx;
- for (size_t core_idx = 0; core_idx < cgroup->num_cores; core_idx++) {
- if (!rdt_is_core_id_valid(cgroup->cores[core_idx])) {
- ERROR(RDT_PLUGIN ": Core group '%s' contains invalid core id '%u'",
- cgroup->desc, cgroup->cores[core_idx]);
- rdt_free_cgroups();
- return -EINVAL;
- }
- }
- }
-
- if (n == 0) {
- /* create default core groups if "Cores" config option is empty */
- int ret = rdt_default_cgroups();
- if (ret < 0) {
- rdt_free_cgroups();
- ERROR(RDT_PLUGIN ": Error creating default core groups configuration.");
- return ret;
- }
- n = (size_t)ret;
- INFO(RDT_PLUGIN
- ": No core groups configured. Default core groups created.");
- }
-
- /* Get all available events on this platform */
- for (unsigned int i = 0; i < g_rdt->cap_mon->u.mon->num_events; i++)
- events |= g_rdt->cap_mon->u.mon->events[i].type;
-
- events &= ~(PQOS_PERF_EVENT_LLC_MISS);
-
- DEBUG(RDT_PLUGIN ": Number of cores in the system: %u",
- g_rdt->pqos_cpu->num_cores);
- DEBUG(RDT_PLUGIN ": Available events to monitor: %#x", events);
-
- g_rdt->cores.num_cgroups = n;
- for (int i = 0; i < n; i++) {
- for (int j = 0; j < i; j++) {
- int found = 0;
- found = config_cores_cmp_cgroups(&g_rdt->cores.cgroups[j],
- &g_rdt->cores.cgroups[i]);
- if (found != 0) {
- rdt_free_cgroups();
- ERROR(RDT_PLUGIN ": Cannot monitor same cores in different groups.");
- return -EINVAL;
- }
- }
-
- g_rdt->events[i] = events;
- g_rdt->pcgroups[i] = calloc(1, sizeof(*g_rdt->pcgroups[i]));
- if (g_rdt->pcgroups[i] == NULL) {
- rdt_free_cgroups();
- ERROR(RDT_PLUGIN ": Failed to allocate memory for monitoring data.");
- return -ENOMEM;
- }
- }
-
- return 0;
-}
-
-#ifdef LIBPQOS2
-static int rdt_config_ngroups(rdt_ctx_t *rdt, const oconfig_item_t *item) {
- int n = 0;
- enum pqos_mon_event events = 0;
-
- if (item == NULL) {
- DEBUG(RDT_PLUGIN ": ngroups_config: Invalid argument.");
- return -EINVAL;
- }
-
- DEBUG(RDT_PLUGIN ": Process names groups [%d]:", item->values_num);
- for (int j = 0; j < item->values_num; j++) {
- if (item->values[j].type != OCONFIG_TYPE_STRING) {
- ERROR(RDT_PLUGIN
- ": given process names group value is not a string [idx=%d]",
- j);
- return -EINVAL;
- }
- DEBUG(RDT_PLUGIN ": [%d]: %s", j, item->values[j].value.string);
- }
-
- n = oconfig_to_ngroups(item, rdt->ngroups, RDT_MAX_NAMES_GROUPS);
- if (n < 0) {
- rdt_free_ngroups(rdt);
- ERROR(RDT_PLUGIN ": Error parsing process name groups configuration.");
- return -EINVAL;