Ejemplo n.º 1
0
int
pqos_cap_get_event(const struct pqos_cap *cap,
                   const enum pqos_mon_event event,
                   const struct pqos_monitor **p_mon)
{
        const struct pqos_capability *cap_item = NULL;
        const struct pqos_cap_mon *mon = NULL;
        int ret = PQOS_RETVAL_OK;
        unsigned i;

        if (cap == NULL || p_mon == NULL)
                return PQOS_RETVAL_PARAM;

        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_MON, &cap_item);
        if (ret != PQOS_RETVAL_OK)
                return ret;

        ASSERT(cap_item != NULL);
        mon = cap_item->u.mon;

        ret = PQOS_RETVAL_ERROR;

        for (i = 0; i < mon->num_events; i++) {
                if (mon->events[i].type == event) {
                        *p_mon = &mon->events[i];
                        ret = PQOS_RETVAL_OK;
                        break;
                }
        }

        return ret;
}
Ejemplo n.º 2
0
int main(int argc, char *argv[])
{
        struct pqos_config cfg;
        const struct pqos_cpuinfo *p_cpu = NULL;
        const struct pqos_cap *p_cap = NULL;
        const struct pqos_capability *cap_l3ca = NULL;
        unsigned sock_count, *sockets = NULL;
        int ret, exit_val = EXIT_SUCCESS;

	memset(&cfg, 0, sizeof(cfg));
        cfg.fd_log = STDOUT_FILENO;
        cfg.verbose = 0;
	/* PQoS Initialization - Check and initialize CAT and CMT capability */
	ret = pqos_init(&cfg);
	if (ret != PQOS_RETVAL_OK) {
		printf("Error initializing PQoS library!\n");
		exit_val = EXIT_FAILURE;
		goto error_exit;
	}
	/* Get CMT capability and CPU info pointer */
	ret = pqos_cap_get(&p_cap, &p_cpu);
        if (ret != PQOS_RETVAL_OK) {
                printf("Error retrieving PQoS capabilities!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit;
        }
	if (argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "-H"))) {
		printf("Usage: %s\n\n", argv[0]);
		goto error_exit;
	}
	/* Reset Api */
        ret = pqos_alloc_reset(PQOS_REQUIRE_CDP_ANY, PQOS_REQUIRE_CDP_ANY,
                               PQOS_MBA_ANY);
	if (ret != PQOS_RETVAL_OK)
		printf("CAT reset failed!\n");
	else
		printf("CAT reset successful\n");
	/* Get CPU socket information to set COS */
	sockets = pqos_cpu_get_sockets(p_cpu, &sock_count);
        if (sockets == NULL) {
                printf("Error retrieving CPU socket information!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit;
        }
	(void) pqos_cap_get_type(p_cap, PQOS_CAP_TYPE_L3CA, &cap_l3ca);
	/* Print COS and associated cores */
	print_allocation_config(cap_l3ca, sock_count, sockets, p_cpu);
 error_exit:
	/* reset and deallocate all the resources */
	ret = pqos_fini();
	if (ret != PQOS_RETVAL_OK)
		printf("Error shutting down PQoS library!\n");
        if (sockets != NULL)
                free(sockets);
	return exit_val;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[])
{
	struct pqos_config config;
	const struct pqos_cpuinfo *p_cpu = NULL;
	const struct pqos_cap *p_cap = NULL;
	int ret, exit_val = EXIT_SUCCESS;
	const struct pqos_capability *cap_mon = NULL;

	memset(&config, 0, sizeof(config));
        config.fd_log = STDOUT_FILENO;
        config.verbose = 0;
	/* PQoS Initialization - Check and initialize CAT and CMT capability */
	ret = pqos_init(&config);
	if (ret != PQOS_RETVAL_OK) {
		printf("Error initializing PQoS library!\n");
		exit_val = EXIT_FAILURE;
		goto error_exit;
	}
	/* Get CMT capability and CPU info pointer */
	ret = pqos_cap_get(&p_cap, &p_cpu);
	if (ret != PQOS_RETVAL_OK) {
		printf("Error retrieving PQoS capabilities!\n");
		exit_val = EXIT_FAILURE;
		goto error_exit;
	}
	/* Get input from user */
	monitoring_get_input(argc, argv);
	(void) pqos_cap_get_type(p_cap, PQOS_CAP_TYPE_MON, &cap_mon);
	/* Setup the monitoring resources */
	ret = setup_monitoring(p_cpu, cap_mon);
	if (ret != PQOS_RETVAL_OK) {
		printf("Error Setting up monitoring!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit;
        }
	/* Start Monitoring */
	monitoring_loop();
	/* Stop Monitoring */
	stop_monitoring();
 error_exit:
	ret = pqos_fini();
	if (ret != PQOS_RETVAL_OK)
		printf("Error shutting down PQoS library!\n");
	return exit_val;
}
Ejemplo n.º 4
0
int
pqos_l3ca_get_cos_num(const struct pqos_cap *cap,
                       unsigned *cos_num)
{
        const struct pqos_capability *item = NULL;
        int ret = PQOS_RETVAL_OK;

        ASSERT(cap != NULL && cos_num != NULL);
        if (cap == NULL || cos_num == NULL)
                return PQOS_RETVAL_PARAM;

        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L3CA, &item);
        if (ret != PQOS_RETVAL_OK)
                return ret;                           /**< no L3CA capability */

        ASSERT(item != NULL);
        *cos_num = item->u.l3ca->num_classes;
        return ret;
}
Ejemplo n.º 5
0
int
pqos_l3ca_cdp_enabled(const struct pqos_cap *cap,
                      int *cdp_supported,
                      int *cdp_enabled)
{
        const struct pqos_capability *item = NULL;
        int ret = PQOS_RETVAL_OK;

        ASSERT(cap != NULL && (cdp_enabled != NULL || cdp_supported != NULL));
        if (cap == NULL || (cdp_enabled == NULL && cdp_supported == NULL))
                return PQOS_RETVAL_PARAM;

        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L3CA, &item);
        if (ret != PQOS_RETVAL_OK)
                return ret;                           /**< no L3CA capability */

        ASSERT(item != NULL);
        if (cdp_supported != NULL)
                *cdp_supported = item->u.l3ca->cdp;
        if (cdp_enabled != NULL)
                *cdp_enabled = item->u.l3ca->cdp_on;
        return ret;
}
Ejemplo n.º 6
0
/**
 * @brief Allocates RMID for given \a event
 *
 * @param [in] cluster CPU cluster id
 * @param [in] event Monitoring event type
 * @param [out] rmid resource monitoring id
 *
 * @return Operations status
 */
static int
rmid_alloc(const unsigned cluster,
           const enum pqos_mon_event event,
           pqos_rmid_t *rmid)
{
    enum rmid_state *rmid_table = NULL;
    const struct pqos_capability *item = NULL;
    const struct pqos_cap_mon *mon = NULL;
    int ret = PQOS_RETVAL_OK;
    unsigned max_rmid = 0;
    unsigned i;
    int j;
    unsigned mask_found = 0;

    if (rmid == NULL)
        return PQOS_RETVAL_PARAM;

    ret = mon_rmid_alloc_param_check(cluster, &rmid_table);
    if (ret != PQOS_RETVAL_OK)
        return ret;
    ASSERT(rmid_table != NULL);

    /**
     * This is not so straight forward as it appears to be.
     * We first have to figure out max RMID
     * for given event type. In order to do so we need:
     * - go through capabilities structure
     * - find monitoring capability
     * - look for the \a event in the event list
     * - find max RMID matching the \a event
     */
    ASSERT(m_cap != NULL);
    ret = pqos_cap_get_type(m_cap, PQOS_CAP_TYPE_MON, &item);
    if (ret != PQOS_RETVAL_OK)
        return ret;
    ASSERT(item != NULL);
    mon = item->u.mon;

    /* Find which events are supported */
    max_rmid = m_rmid_max;
    for (i = 0; i < mon->num_events; i++) {
        if (event & mon->events[i].type) {
            mask_found |= mon->events[i].type;
            max_rmid = (max_rmid > mon->events[i].max_rmid) ?
                       mon->events[i].max_rmid : max_rmid;
        }
    }

    /**
     * Check if all of the events are supported
     */
    if (event != mask_found || max_rmid == 0)
        return PQOS_RETVAL_ERROR;
    ASSERT(m_rmid_max >= max_rmid);

    /**
     * Check for free RMID in the table
     * Do it backwards (from max to 0) in order to preserve low RMID values
     * for overlapping RMID ranges for future events.
     */
    ret = PQOS_RETVAL_ERROR;
    for (j = (int)max_rmid-1; j >= 0; j--) {
        if (rmid_table[j] != RMID_STATE_FREE)
            continue;
        rmid_table[j] = RMID_STATE_ALLOCATED;
        *rmid = (pqos_rmid_t) j;
        ret = PQOS_RETVAL_OK;
        break;
    }

    return ret;
}
Ejemplo n.º 7
0
int
pqos_mon_init(const struct pqos_cpuinfo *cpu,
              const struct pqos_cap *cap,
              const struct pqos_config *cfg)
{
    const struct pqos_capability *item = NULL;
    unsigned i = 0, fails = 0;
    int ret = PQOS_RETVAL_OK;

    m_cpu = cpu;
    m_cap = cap;

#ifndef PQOS_NO_PID_API
    /**
     * Init monitoring processes
     */
    ret = pqos_pid_init(m_cap);
    if (ret == PQOS_RETVAL_ERROR)
        return ret;
#endif /* PQOS_NO_PID_API */

    /**
     * If monitoring capability has been discovered
     * then get max RMID supported by a CPU socket
     * and allocate memory for RMID table
     */
    ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_MON, &item);
    if (ret != PQOS_RETVAL_OK)
        return ret;

    m_num_clusters = cpu_get_num_clusters(m_cpu);
    ASSERT(m_num_clusters >= 1);

    ASSERT(item != NULL);
    m_rmid_max = item->u.mon->max_rmid;
    if (m_rmid_max == 0) {
        pqos_mon_fini();
        return PQOS_RETVAL_PARAM;
    }

    LOG_DEBUG("Max RMID per monitoring cluster is %u\n", m_rmid_max);

    ASSERT(m_cpu != NULL);

    m_dim_cores = cpu_get_num_cores(m_cpu);
    m_core_map =
        (struct mon_entry *)malloc(m_dim_cores * sizeof(m_core_map[0]));
    ASSERT(m_core_map != NULL);
    if (m_core_map == NULL) {
        pqos_mon_fini();
        return PQOS_RETVAL_ERROR;
    }
    memset(m_core_map, 0, m_dim_cores*sizeof(m_core_map[0]));

    m_rmid_cluster_map =
        (enum rmid_state **)malloc(m_num_clusters *
                                   sizeof(m_rmid_cluster_map[0]));
    ASSERT(m_rmid_cluster_map != NULL);
    if (m_rmid_cluster_map == NULL) {
        pqos_mon_fini();
        return PQOS_RETVAL_ERROR;
    }

    for (i = 0 ; i < m_num_clusters; i++) {
        const size_t size = m_rmid_max * sizeof(enum rmid_state);
        enum rmid_state *st = (enum rmid_state *)malloc(size);

        if (st == NULL) {
            pqos_mon_fini();
            return PQOS_RETVAL_RESOURCE;
        }
        m_rmid_cluster_map[i] = st;
        memset(st, 0, size);
        st[RMID0] = RMID_STATE_UNAVAILABLE; /**< RMID0 has a special
                                                       meaning */
    }

    LOG_DEBUG("RMID internal tables allocated\n");
    m_force_mon = cfg->free_in_use_rmid;

    /**
     * Read current core<=>RMID associations
     */
    for (i = 0; i < m_cpu->num_cores; i++) {
        pqos_rmid_t rmid = 0;
        unsigned coreid = m_cpu->cores[i].lcore;
        unsigned clusterid = m_cpu->cores[i].cluster;

        ret = mon_assoc_get(coreid, &rmid);
        if (ret != PQOS_RETVAL_OK) {
            LOG_ERROR("Failed to read RMID association of "
                      "lcore %u!\n", coreid);
            fails++;
        } else {
            ASSERT(rmid < m_rmid_max);

            m_core_map[coreid].rmid = rmid;
            m_core_map[coreid].unavailable = 0;
            m_core_map[coreid].grp = NULL;

            if (rmid == RMID0)
                continue;

            /**
             * At this stage we know core is assigned to non-zero RMID
             * This means it may be used by another instance of
             * the program for monitoring.
             * The other option is that previously ran program
             * died and it didn't revert RMID association.
             */

            if (!cfg->free_in_use_rmid) {
                enum rmid_state *pstate = NULL;

                LOG_DEBUG("Detected RMID%u is associated with "
                          "core %u. "
                          "Marking RMID & core unavailable.\n",
                          rmid, coreid);

                ASSERT(clusterid < m_num_clusters);
                pstate = m_rmid_cluster_map[clusterid];
                pstate[rmid] = RMID_STATE_UNAVAILABLE;

                m_core_map[coreid].unavailable = 1;
            } else {
                LOG_DEBUG("Detected RMID%u is associated with "
                          "core %u. "
                          "Freeing the RMID and associating "
                          "core with RMID0.\n",
                          rmid, coreid);
                ret = mon_assoc_set_nocheck(coreid, RMID0);
                if (ret != PQOS_RETVAL_OK) {
                    LOG_ERROR("Failed to associate core %u "
                              "with RMID0!\n", coreid);
                    fails++;
                }
            }
        }
    }

    ret = (fails == 0) ? PQOS_RETVAL_OK : PQOS_RETVAL_ERROR;

    if (ret != PQOS_RETVAL_OK)
        pqos_mon_fini();

    return ret;
}
Ejemplo n.º 8
0
static int rdt_preinit(void) {
  int ret;

  if (g_rdt != NULL) {
    /* already initialized if config callback was called before init callback */
    return 0;
  }

  g_rdt = calloc(1, sizeof(*g_rdt));
  if (g_rdt == NULL) {
    ERROR(RDT_PLUGIN ": Failed to allocate memory for rdt context.");
    return -ENOMEM;
  }

  struct pqos_config pqos = {.fd_log = -1,
                             .callback_log = rdt_pqos_log,
                             .context_log = NULL,
                             .verbose = 0};

  ret = pqos_init(&pqos);
  if (ret != PQOS_RETVAL_OK) {
    ERROR(RDT_PLUGIN ": Error initializing PQoS library!");
    goto rdt_preinit_error1;
  }

  ret = pqos_cap_get(&g_rdt->pqos_cap, &g_rdt->pqos_cpu);
  if (ret != PQOS_RETVAL_OK) {
    ERROR(RDT_PLUGIN ": Error retrieving PQoS capabilities.");
    goto rdt_preinit_error2;
  }

  ret = pqos_cap_get_type(g_rdt->pqos_cap, PQOS_CAP_TYPE_MON, &g_rdt->cap_mon);
  if (ret == PQOS_RETVAL_PARAM) {
    ERROR(RDT_PLUGIN ": Error retrieving monitoring capabilities.");
    goto rdt_preinit_error2;
  }

  if (g_rdt->cap_mon == NULL) {
    ERROR(
        RDT_PLUGIN
        ": Monitoring capability not detected. Nothing to do for the plugin.");
    goto rdt_preinit_error2;
  }

  /* Reset pqos monitoring groups registers */
  pqos_mon_reset();

  return 0;

rdt_preinit_error2:
  pqos_fini();

rdt_preinit_error1:

  sfree(g_rdt);

  return -1;
}

static int rdt_config(oconfig_item_t *ci) {
  if (rdt_preinit() != 0) {
    g_state = CONFIGURATION_ERROR;
    /* if we return -1 at this point collectd
      reports a failure in configuration and
      aborts
    */
    return (0);
  }

  for (int i = 0; i < ci->children_num; i++) {
    oconfig_item_t *child = ci->children + i;

    if (strcasecmp("Cores", child->key) == 0) {
      if (rdt_config_cgroups(child) != 0) {
        g_state = CONFIGURATION_ERROR;
        /* if we return -1 at this point collectd
           reports a failure in configuration and
           aborts
         */
        return (0);
      }

#if COLLECT_DEBUG
      rdt_dump_cgroups();
#endif /* COLLECT_DEBUG */
    } else {
      ERROR(RDT_PLUGIN ": Unknown configuration parameter \"%s\".", child->key);
    }
  }

  return 0;
}

static void rdt_submit_derive(const char *cgroup, const char *type,
                              const char *type_instance, derive_t value) {
  value_list_t vl = VALUE_LIST_INIT;

  vl.values = &(value_t){.derive = value};
  vl.values_len = 1;

  sstrncpy(vl.plugin, RDT_PLUGIN, sizeof(vl.plugin));
  snprintf(vl.plugin_instance, sizeof(vl.plugin_instance), "%s", cgroup);
  sstrncpy(vl.type, type, sizeof(vl.type));
  if (type_instance)
    sstrncpy(vl.type_instance, type_instance, sizeof(vl.type_instance));

  plugin_dispatch_values(&vl);
}
Ejemplo n.º 9
0
int
pqos_l3ca_reset(const struct pqos_cap *cap,
                const struct pqos_cpuinfo *cpu)
{
        unsigned *sockets = NULL;
        unsigned sockets_num = 0, sockets_num_ret = 0;
        const struct pqos_capability *item = NULL;
        int ret = PQOS_RETVAL_OK;
        unsigned j;

        ASSERT(cap != NULL && cpu != NULL);
        if (cap == NULL || cpu == NULL)
                return PQOS_RETVAL_PARAM;

        ret = pqos_cap_get_type(cap, PQOS_CAP_TYPE_L3CA, &item);
        if (ret != PQOS_RETVAL_OK)
                return ret;                           /**< no L3CA capability */
        ASSERT(item != NULL);

        /**
         * Figure out number of sockets in the system
         * - allocate enough memory to accommodate all socket id's
         * - use stack frame allocator for it (not heap)
         * - get list of socket id's through another API
         * - validate that number of socket id's obtained in
         *   two different ways match
         */
        sockets_num = __get_num_sockets(cpu);
        if (sockets_num == 0)
                return PQOS_RETVAL_RESOURCE;

        sockets = alloca(sockets_num * sizeof(sockets[0]));
        if (sockets == NULL)
                return PQOS_RETVAL_RESOURCE;

        ret = pqos_cpu_get_sockets(cpu, sockets_num, &sockets_num_ret, sockets);
        if (ret != PQOS_RETVAL_OK)
                return ret;
        ASSERT(sockets_num_ret == sockets_num);
        if (sockets_num != sockets_num_ret)
                return PQOS_RETVAL_ERROR;

        /**
         * Change COS definition on all sockets
         * so that each COS allows for access to all cache ways
         */
        for (j = 0; j < sockets_num; j++) {
                const uint64_t ways_mask = (1ULL<<item->u.l3ca->num_ways)-1ULL;
                unsigned i;

                for (i = 0; i < item->u.l3ca->num_classes; i++) {
                        struct pqos_l3ca cos;

                        cos.cdp = 0;
                        cos.class_id = i;
                        cos.ways_mask = ways_mask;
                        ret = pqos_l3ca_set(sockets[j], 1, &cos);
                        if (ret != PQOS_RETVAL_OK)
                                return ret;
                }
        }

        /**
         * Associate all cores with COS0
         */
        for (j = 0; j < cpu->num_cores; j++) {
                ret = pqos_l3ca_assoc_set(cpu->cores[j].lcore, 0);
                if (ret != PQOS_RETVAL_OK)
                        return ret;
        }

        return ret;
}
Ejemplo n.º 10
0
int main(int argc, char **argv)
{
        struct pqos_config cfg;
        const struct pqos_cpuinfo *p_cpu = NULL;
        const struct pqos_cap *p_cap = NULL;
        const struct pqos_capability *cap_mon = NULL, *cap_l3ca = NULL;
        unsigned sock_count, sockets[PQOS_MAX_SOCKETS];
        int cmd, ret, exit_val = EXIT_SUCCESS;
        int opt_index = 0;

        m_cmd_name = argv[0];
        print_warning();

        while ((cmd = getopt_long(argc, argv,
                                  "Hhf:i:m:Tt:l:o:u:e:c:a:p:S:srvVR",
                                  long_cmd_opts, &opt_index)) != -1) {
                switch (cmd) {
                case 'h':
                        print_help(1);
                        return EXIT_SUCCESS;
                case 'H':
                        profile_l3ca_list(stdout);
                        return EXIT_SUCCESS;
                case 'S':
                        selfn_set_config(optarg);
                        break;
                case 'f':
                        if (sel_config_file != NULL) {
                                printf("Only one config file argument is "
                                       "accepted!\n");
                                return EXIT_FAILURE;
                        }
                        selfn_strdup(&sel_config_file, optarg);
                        parse_config_file(sel_config_file);
                        break;
                case 'i':
                        selfn_monitor_interval(optarg);
                        break;
                case 'p':
		        selfn_monitor_pids(optarg);
                        break;
                case 'm':
                        selfn_monitor_cores(optarg);
                        break;
                case 't':
                        selfn_monitor_time(optarg);
                        break;
                case 'T':
                        selfn_monitor_top_like(NULL);
                        break;
                case 'l':
                        selfn_log_file(optarg);
                        break;
                case 'o':
                        selfn_monitor_file(optarg);
                        break;
                case 'u':
                        selfn_monitor_file_type(optarg);
                        break;
                case 'e':
                        selfn_allocation_class(optarg);
                        break;
                case 'r':
                        sel_free_in_use_rmid = 1;
                        break;
                case 'R':
                        selfn_reset_cat(NULL);
                        break;
                case 'a':
                        selfn_allocation_assoc(optarg);
                        break;
                case 'c':
                        selfn_allocation_select(optarg);
                        break;
                case 's':
                        selfn_show_allocation(NULL);
                        break;
                case 'v':
                        selfn_verbose_mode(NULL);
                        break;
                case 'V':
                        selfn_super_verbose_mode(NULL);
                        break;
                default:
                        printf("Unsupported option: -%c. "
                               "See option -h for help.\n", optopt);
                        return EXIT_FAILURE;
                        break;
                case '?':
                        print_help(0);
                        return EXIT_SUCCESS;
                        break;
                }
        }

        memset(&cfg, 0, sizeof(cfg));
        cfg.verbose = sel_verbose_mode;
        cfg.free_in_use_rmid = sel_free_in_use_rmid;
        cfg.cdp_cfg = selfn_cdp_config;

        /**
         * Set up file descriptor for message log
         */
        if (sel_log_file == NULL) {
                cfg.fd_log = STDOUT_FILENO;
        } else {
                cfg.fd_log = open(sel_log_file, O_WRONLY|O_CREAT,
                                  S_IRUSR|S_IWUSR);
                if (cfg.fd_log == -1) {
                        printf("Error opening %s log file!\n", sel_log_file);
                        exit_val = EXIT_FAILURE;
                        goto error_exit_2;
                }
        }

        ret = pqos_init(&cfg);
        if (ret != PQOS_RETVAL_OK) {
                printf("Error initializing PQoS library!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit_1;
        }

        ret = pqos_cap_get(&p_cap, &p_cpu);
        if (ret != PQOS_RETVAL_OK) {
                printf("Error retrieving PQoS capabilities!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit_2;
        }

        ret = pqos_cpu_get_sockets(p_cpu, PQOS_MAX_SOCKETS,
                                   &sock_count,
                                   sockets);
        if (ret != PQOS_RETVAL_OK) {
                printf("Error retrieving CPU socket information!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit_2;
        }

        ret = pqos_cap_get_type(p_cap, PQOS_CAP_TYPE_MON, &cap_mon);
        if (ret == PQOS_RETVAL_PARAM) {
                printf("Error retrieving monitoring capabilities!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit_2;
        }

        ret = pqos_cap_get_type(p_cap, PQOS_CAP_TYPE_L3CA, &cap_l3ca);
        if (ret == PQOS_RETVAL_PARAM) {
                printf("Error retrieving allocation capabilities!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit_2;
        }

        if (sel_reset_CAT) {
                /**
                 * Reset CAT configuration to after-reset state and exit
                 */
                if (pqos_l3ca_reset(p_cap, p_cpu) != PQOS_RETVAL_OK) {
                        exit_val = EXIT_FAILURE;
                        printf("CAT reset failed!\n");
                } else
                        printf("CAT reset successful\n");
                goto allocation_exit;
        }

        if (sel_show_allocation_config) {
                /**
                 * Show info about allocation config and exit
                 */
		alloc_print_config(cap_mon, cap_l3ca, sock_count,
                                   sockets, p_cpu);
                goto allocation_exit;
        }

        if (sel_allocation_profile != NULL) {
                if (profile_l3ca_apply(sel_allocation_profile, cap_l3ca) != 0) {
                        exit_val = EXIT_FAILURE;
                        goto error_exit_2;
                }
        }

        switch (alloc_apply(cap_l3ca, sock_count, sockets)) {
        case 0: /* nothing to apply */
                break;
        case 1: /* new allocation config applied and all is good */
                goto allocation_exit;
                break;
        case -1: /* something went wrong */
        default:
                exit_val = EXIT_FAILURE;
                goto error_exit_2;
                break;
        }

        /**
         * Just monitoring option left on the table now
         */
        if (cap_mon == NULL) {
                printf("Monitoring capability not detected!\n");
                exit_val = EXIT_FAILURE;
                goto error_exit_2;
        }

        if (monitor_setup(p_cpu, cap_mon) != 0) {
                exit_val = EXIT_FAILURE;
                goto error_exit_2;
        }
        monitor_loop(p_cap);
        monitor_stop();

 allocation_exit:
 error_exit_2:
        ret = pqos_fini();
        ASSERT(ret == PQOS_RETVAL_OK);
        if (ret != PQOS_RETVAL_OK)
                printf("Error shutting down PQoS library!\n");

 error_exit_1:
        monitor_cleanup();

        /**
         * Close file descriptor for message log
         */
        if (cfg.fd_log > 0 && cfg.fd_log != STDOUT_FILENO)
                close(cfg.fd_log);

        /**
         * Free allocated memory
         */
        if (sel_allocation_profile != NULL)
                free(sel_allocation_profile);
        if (sel_log_file != NULL)
                free(sel_log_file);
        if (sel_config_file != NULL)
                free(sel_config_file);

        return exit_val;
}
Ejemplo n.º 11
0
static int rdt_preinit(void) {
  int ret;

  if (g_rdt != NULL) {
    /* already initialized if config callback was called before init callback */
    return (0);
  }

  g_rdt = calloc(1, sizeof(*g_rdt));
  if (g_rdt == NULL) {
    ERROR(RDT_PLUGIN ": Failed to allocate memory for rdt context.");
    return (-ENOMEM);
  }

  struct pqos_config pqos = {.fd_log = -1,
                             .callback_log = rdt_pqos_log,
                             .context_log = NULL,
                             .verbose = 0};

  ret = pqos_init(&pqos);
  if (ret != PQOS_RETVAL_OK) {
    ERROR(RDT_PLUGIN ": Error initializing PQoS library!");
    goto rdt_preinit_error1;
  }

  ret = pqos_cap_get(&g_rdt->pqos_cap, &g_rdt->pqos_cpu);
  if (ret != PQOS_RETVAL_OK) {
    ERROR(RDT_PLUGIN ": Error retrieving PQoS capabilities.");
    goto rdt_preinit_error2;
  }

  ret = pqos_cap_get_type(g_rdt->pqos_cap, PQOS_CAP_TYPE_MON, &g_rdt->cap_mon);
  if (ret == PQOS_RETVAL_PARAM) {
    ERROR(RDT_PLUGIN ": Error retrieving monitoring capabilities.");
    goto rdt_preinit_error2;
  }

  if (g_rdt->cap_mon == NULL) {
    ERROR(
        RDT_PLUGIN
        ": Monitoring capability not detected. Nothing to do for the plugin.");
    goto rdt_preinit_error2;
  }

  /* Reset pqos monitoring groups registers */
  pqos_mon_reset();

  return (0);

rdt_preinit_error2:
  pqos_fini();

rdt_preinit_error1:

  sfree(g_rdt);

  return (-1);
}

static int rdt_config(oconfig_item_t *ci) {
  int ret = 0;

  ret = rdt_preinit();
  if (ret != 0) {
    g_state = CONFIGURATION_ERROR;
    /* if we return -1 at this point collectd
      reports a failure in configuration and
      aborts
    */
    goto exit;
  }

  for (int i = 0; i < ci->children_num; i++) {
    oconfig_item_t *child = ci->children + i;

    if (strcasecmp("Cores", child->key) == 0) {

      ret = rdt_config_cgroups(child);
      if (ret != 0) {
        g_state = CONFIGURATION_ERROR;
        /* if we return -1 at this point collectd
           reports a failure in configuration and
           aborts
         */
        goto exit;
      }

#if COLLECT_DEBUG
      rdt_dump_cgroups();
#endif /* COLLECT_DEBUG */

    } else {
      ERROR(RDT_PLUGIN ": Unknown configuration parameter \"%s\".", child->key);
    }
  }

exit:
  return (0);
}
Ejemplo n.º 12
0
int
hw_alloc_reset(const enum pqos_cdp_config l3_cdp_cfg)
{
        unsigned *sockets = NULL;
        unsigned sockets_num = 0;
        unsigned *l2ids = NULL;
        unsigned l2id_num = 0;
        const struct pqos_capability *alloc_cap = NULL;
        const struct pqos_cap_l3ca *l3_cap = NULL;
        const struct pqos_cap_l2ca *l2_cap = NULL;
        const struct pqos_cap_mba *mba_cap = NULL;
        int ret = PQOS_RETVAL_OK;
        unsigned max_l3_cos = 0;
        unsigned j;

        if (l3_cdp_cfg != PQOS_REQUIRE_CDP_ON &&
            l3_cdp_cfg != PQOS_REQUIRE_CDP_OFF &&
            l3_cdp_cfg != PQOS_REQUIRE_CDP_ANY) {
                LOG_ERROR("Unrecognized L3 CDP configuration setting %d!\n",
                          l3_cdp_cfg);
                return PQOS_RETVAL_PARAM;
        }

        /* Get L3 CAT capabilities */
        (void) pqos_cap_get_type(m_cap, PQOS_CAP_TYPE_L3CA, &alloc_cap);
        if (alloc_cap != NULL)
                l3_cap = alloc_cap->u.l3ca;

        /* Get L2 CAT capabilities */
        alloc_cap = NULL;
        (void) pqos_cap_get_type(m_cap, PQOS_CAP_TYPE_L2CA, &alloc_cap);
        if (alloc_cap != NULL)
                l2_cap = alloc_cap->u.l2ca;

        /* Get MBA capabilities */
        alloc_cap = NULL;
        (void) pqos_cap_get_type(m_cap, PQOS_CAP_TYPE_MBA, &alloc_cap);
        if (alloc_cap != NULL)
                mba_cap = alloc_cap->u.mba;

        /* Check if either L2 CAT, L3 CAT or MBA is supported */
        if (l2_cap == NULL && l3_cap == NULL && mba_cap == NULL) {
                LOG_ERROR("L2 CAT/L3 CAT/MBA not present!\n");
                ret = PQOS_RETVAL_RESOURCE; /* no L2/L3 CAT present */
                goto pqos_alloc_reset_exit;
        }
        /* Check L3 CDP requested while not present */
        if (l3_cap == NULL && l3_cdp_cfg != PQOS_REQUIRE_CDP_ANY) {
                LOG_ERROR("L3 CDP setting requested but no L3 CAT present!\n");
                ret = PQOS_RETVAL_RESOURCE;
                goto pqos_alloc_reset_exit;
        }
        if (l3_cap != NULL) {
                /* Check against erroneous CDP request */
                if (l3_cdp_cfg == PQOS_REQUIRE_CDP_ON && !l3_cap->cdp) {
                        LOG_ERROR("CAT/CDP requested but not supported by the "
                                  "platform!\n");
                        ret = PQOS_RETVAL_PARAM;
                        goto pqos_alloc_reset_exit;
                }

                /* Get maximum number of L3 CAT classes */
                max_l3_cos = l3_cap->num_classes;
                if (l3_cap->cdp && l3_cap->cdp_on)
                        max_l3_cos = max_l3_cos * 2;
        }

        /**
         * Get number & list of sockets in the system
         */
        sockets = pqos_cpu_get_sockets(m_cpu, &sockets_num);
        if (sockets == NULL || sockets_num == 0)
                goto pqos_alloc_reset_exit;

        if (l3_cap != NULL) {
                /**
                 * Change L3 COS definition on all sockets
                 * so that each COS allows for access to all cache ways
                 */

                for (j = 0; j < sockets_num; j++) {
                        unsigned core = 0;

                        ret = pqos_cpu_get_one_core(m_cpu, sockets[j], &core);
                        if (ret != PQOS_RETVAL_OK)
                                goto pqos_alloc_reset_exit;

                        const uint64_t ways_mask =
                                (1ULL << l3_cap->num_ways) - 1ULL;

                        ret = alloc_cos_reset(PQOS_MSR_L3CA_MASK_START,
                                              max_l3_cos, core, ways_mask);
                        if (ret != PQOS_RETVAL_OK)
                                goto pqos_alloc_reset_exit;
                }
        }

        if (l2_cap != NULL) {
                /**
                 * Get number & list of L2ids in the system
                 * Then go through all L2 ids and reset L2 classes on them
                 */
                l2ids = pqos_cpu_get_l2ids(m_cpu, &l2id_num);
                if (l2ids == NULL || l2id_num == 0)
                        goto pqos_alloc_reset_exit;

                for (j = 0; j < l2id_num; j++) {
                        const uint64_t ways_mask =
                                (1ULL << l2_cap->num_ways) - 1ULL;
                        unsigned core = 0;

                        ret = pqos_cpu_get_one_by_l2id(m_cpu, l2ids[j], &core);
                        if (ret != PQOS_RETVAL_OK)
                                goto pqos_alloc_reset_exit;

                        ret = alloc_cos_reset(PQOS_MSR_L2CA_MASK_START,
                                              l2_cap->num_classes, core,
                                              ways_mask);
                        if (ret != PQOS_RETVAL_OK)
                                goto pqos_alloc_reset_exit;
                }
        }

        if (mba_cap != NULL) {
                /**
                 * Go through all sockets and reset MBA class defintions
                 * 0 is the default MBA COS value in linear mode.
                 */

                for (j = 0; j < sockets_num; j++) {
                        unsigned core = 0;

                        ret = pqos_cpu_get_one_core(m_cpu, sockets[j], &core);
                        if (ret != PQOS_RETVAL_OK)
                                goto pqos_alloc_reset_exit;

                        ret = alloc_cos_reset(PQOS_MSR_MBA_MASK_START,
                                              mba_cap->num_classes, core, 0);
                        if (ret != PQOS_RETVAL_OK)
                                goto pqos_alloc_reset_exit;
                }
        }

        /**
         * Associate all cores with COS0
         */
        ret = alloc_assoc_reset();
        if (ret != PQOS_RETVAL_OK)
                goto pqos_alloc_reset_exit;

        /**
         * Turn L3 CDP ON or OFF upon the request
         */
        if (l3_cap != NULL) {
                if (l3_cdp_cfg == PQOS_REQUIRE_CDP_ON && !l3_cap->cdp_on) {
                        /**
                         * Turn on CDP
                         */
                        LOG_INFO("Turning CDP ON ...\n");
                        ret = cdp_enable(sockets_num, sockets, 1);
                        if (ret != PQOS_RETVAL_OK) {
                                LOG_ERROR("CDP enable error!\n");
                                goto pqos_alloc_reset_exit;
                        }
                        _pqos_cap_l3cdp_change(l3_cap->cdp_on, 1);
                }

                if (l3_cdp_cfg == PQOS_REQUIRE_CDP_OFF &&
                    l3_cap->cdp_on && l3_cap->cdp) {
                        /**
                         * Turn off CDP
                         */
                        LOG_INFO("Turning CDP OFF ...\n");
                        ret = cdp_enable(sockets_num, sockets, 0);
                        if (ret != PQOS_RETVAL_OK) {
                                LOG_ERROR("CDP disable error!\n");
                                goto pqos_alloc_reset_exit;
                        }
                        _pqos_cap_l3cdp_change(l3_cap->cdp_on, 0);
                }
        }

 pqos_alloc_reset_exit:
        if (sockets != NULL)
                free(sockets);
        if (l2ids != NULL)
                free(l2ids);
        return ret;
}
Ejemplo n.º 13
0
int hw_mba_set(const unsigned socket,
               const unsigned num_cos,
               const struct pqos_mba *requested,
               struct pqos_mba *actual)
{
        int ret = PQOS_RETVAL_OK;
        unsigned i = 0, count = 0, core = 0, step = 0;
        const struct pqos_capability *mba_cap = NULL;

        if (requested == NULL || num_cos == 0)
                return PQOS_RETVAL_PARAM;

        /**
         * Check if MBA is supported
         */
        ASSERT(m_cap != NULL);
        ret = pqos_cap_get_type(m_cap, PQOS_CAP_TYPE_MBA, &mba_cap);
        if (ret != PQOS_RETVAL_OK)
                return PQOS_RETVAL_RESOURCE; /* MBA not supported */

        count = mba_cap->u.mba->num_classes;
        step = mba_cap->u.mba->throttle_step;

        /**
         * Non-linear mode not currently supported
         */
        if (!mba_cap->u.mba->is_linear) {
                LOG_ERROR("MBA non-linear mode not currently supported!\n");
                return PQOS_RETVAL_RESOURCE;
        }
        /**
         * Check if MBA rate and class
         * id's are within allowed range.
         */
        for (i = 0; i < num_cos; i++) {
                if (requested[i].mb_rate == 0 || requested[i].mb_rate > 100) {
                        LOG_ERROR("MBA COS%u rate out of range (from 1-100)!\n",
                                  requested[i].class_id);
                        return PQOS_RETVAL_PARAM;
                }
                if (requested[i].class_id >= count) {
                        LOG_ERROR("MBA COS%u is out of range (COS%u is max)!\n",
                                  requested[i].class_id, count - 1);
                        return PQOS_RETVAL_PARAM;
                }
        }

        ASSERT(m_cpu != NULL);
        ret = pqos_cpu_get_one_core(m_cpu, socket, &core);
        if (ret != PQOS_RETVAL_OK)
                return ret;

        for (i = 0; i < num_cos; i++) {
                const uint32_t reg =
                        requested[i].class_id + PQOS_MSR_MBA_MASK_START;
                uint64_t val = PQOS_MBA_LINEAR_MAX -
                        (((requested[i].mb_rate + (step/2)) / step) * step);
                int retval = MACHINE_RETVAL_OK;

                if (val > mba_cap->u.mba->throttle_max)
                        val = mba_cap->u.mba->throttle_max;

                retval = msr_write(core, reg, val);
                if (retval != MACHINE_RETVAL_OK)
                        return PQOS_RETVAL_ERROR;

                /**
                 * If table to store actual values set is passed,
                 * read MSR values and store in table
                 */
                if (actual == NULL)
                        continue;

                retval = msr_read(core, reg, &val);
                if (retval != MACHINE_RETVAL_OK)
                        return PQOS_RETVAL_ERROR;

                actual[i] = requested[i];
                actual[i].mb_rate = (PQOS_MBA_LINEAR_MAX - val);
        }

        return ret;
}