int data_is_native = -1;
static int ndevs;
+static int max_cpus;
static int ncpus;
+static cpu_set_t *online_cpus;
static int pagesize;
static int act_mask = ~0U;
static int kill_running_trace;
{
cpu_set_t * cpu_mask;
size_t size;
- cpu_mask = CPU_ALLOC(ncpus);
- size = CPU_ALLOC_SIZE(ncpus);
+
+ cpu_mask = CPU_ALLOC(max_cpus);
+ size = CPU_ALLOC_SIZE(max_cpus);
CPU_ZERO_S(size, cpu_mask);
CPU_SET_S(cpu, size, cpu_mask);
strncpy(hdr.buts_name, buts_name, sizeof(hdr.buts_name));
hdr.buts_name[sizeof(hdr.buts_name) - 1] = '\0';
hdr.cpu = cpu;
- hdr.max_cpus = ncpus;
+ hdr.max_cpus = max_cpus;
hdr.len = len;
hdr.cl_id = getpid();
hdr.buf_size = buf_size;
static int open_client_connections(void)
{
int cpu;
+ size_t alloc_size = CPU_ALLOC_SIZE(max_cpus);
cl_fds = calloc(ncpus, sizeof(*cl_fds));
- for (cpu = 0; cpu < ncpus; cpu++) {
+ for (cpu = 0; cpu < max_cpus; cpu++) {
+ if (!CPU_ISSET_S(cpu, alloc_size, online_cpus))
+ continue;
cl_fds[cpu] = net_setup_client();
if (cl_fds[cpu] < 0)
goto err;
{
if (cl_fds) {
int cpu, *fdp;
+ size_t alloc_size = CPU_ALLOC_SIZE(max_cpus);
- for (cpu = 0, fdp = cl_fds; cpu < ncpus; cpu++, fdp++) {
+ for (cpu = 0, fdp = cl_fds; cpu < max_cpus; cpu++, fdp++) {
+ if (!CPU_ISSET_S(cpu, alloc_size, online_cpus))
+ continue;
if (*fdp >= 0) {
net_send_drops(*fdp);
net_close_connection(fdp);
buts.act_mask = act_mask;
if (ioctl(dpp->fd, BLKTRACESETUP, &buts) >= 0) {
- dpp->ncpus = ncpus;
+ dpp->ncpus = max_cpus;
dpp->buts_name = strdup(buts.name);
if (dpp->stats)
free(dpp->stats);
int cpu;
struct tracer_devpath_head *hd;
- for (cpu = 0, hd = dpp->heads; cpu < ncpus; cpu++, hd++) {
+ for (cpu = 0, hd = dpp->heads; cpu < max_cpus; cpu++, hd++) {
if (hd->prev)
free(hd->prev);
struct tracer_devpath_head *hd;
struct devpath *dpp = list_entry(p, struct devpath, head);
- dpp->heads = calloc(ncpus, sizeof(struct tracer_devpath_head));
- for (cpu = 0, hd = dpp->heads; cpu < ncpus; cpu++, hd++) {
+ dpp->heads = calloc(max_cpus, sizeof(struct tracer_devpath_head));
+ for (cpu = 0, hd = dpp->heads; cpu < max_cpus; cpu++, hd++) {
INIT_LIST_HEAD(&hd->head);
pthread_mutex_init(&hd->mutex, NULL);
hd->prev = NULL;
struct devpath *dpp = list_entry(p, struct devpath, head);
struct tracer_devpath_head *hd = dpp->heads;
- for (cpu = 0; cpu < ncpus; cpu++, hd++) {
+ for (cpu = 0; cpu < max_cpus; cpu++, hd++) {
pthread_mutex_lock(&hd->mutex);
if (list_empty(&hd->head)) {
pthread_mutex_unlock(&hd->mutex);
static void start_tracers(void)
{
- int cpu;
+ int cpu, started = 0;
struct list_head *p;
+ size_t alloc_size = CPU_ALLOC_SIZE(max_cpus);
- for (cpu = 0; cpu < ncpus; cpu++)
+ for (cpu = 0; cpu < max_cpus; cpu++) {
+ if (!CPU_ISSET_S(cpu, alloc_size, online_cpus))
+ continue;
if (start_tracer(cpu))
break;
+ started++;
+ }
- wait_tracers_ready(cpu);
+ wait_tracers_ready(started);
__list_for_each(p, &tracers) {
struct tracer *tp = list_entry(p, struct tracer, head);
return 0;
}
+static cpu_set_t *get_online_cpus(void)
+{
+ FILE *cpus;
+ cpu_set_t *set;
+ size_t alloc_size;
+ int cpuid, prevcpuid = -1;
+ char nextch;
+ int n, ncpu, curcpu = 0;
+ int *cpu_nums;
+
+ ncpu = sysconf(_SC_NPROCESSORS_CONF);
+ if (ncpu < 0)
+ return NULL;
+
+ cpu_nums = malloc(sizeof(int)*ncpu);
+ if (!cpu_nums) {
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ /*
+ * There is no way to easily get maximum CPU number. So we have to
+ * parse the file first to find it out and then create appropriate
+ * cpuset
+ */
+ cpus = my_fopen("/sys/devices/system/cpu/online", "r");
+ for (;;) {
+ n = fscanf(cpus, "%d%c", &cpuid, &nextch);
+ if (n <= 0)
+ break;
+ if (n == 2 && nextch == '-') {
+ prevcpuid = cpuid;
+ continue;
+ }
+ if (prevcpuid == -1)
+ prevcpuid = cpuid;
+ while (prevcpuid <= cpuid) {
+ /* More CPUs listed than configured? */
+ if (curcpu >= ncpu) {
+ errno = EINVAL;
+ return NULL;
+ }
+ cpu_nums[curcpu++] = prevcpuid++;
+ }
+ prevcpuid = -1;
+ }
+ fclose(cpus);
+
+ ncpu = curcpu;
+ max_cpus = cpu_nums[ncpu - 1] + 1;
+
+ /* Now that we have maximum cpu number, create a cpuset */
+ set = CPU_ALLOC(max_cpus);
+ if (!set) {
+ errno = ENOMEM;
+ return NULL;
+ }
+ alloc_size = CPU_ALLOC_SIZE(max_cpus);
+ CPU_ZERO_S(alloc_size, set);
+
+ for (curcpu = 0; curcpu < ncpu; curcpu++)
+ CPU_SET_S(cpu_nums[curcpu], alloc_size, set);
+
+ free(cpu_nums);
+
+ return set;
+}
+
int main(int argc, char *argv[])
{
int ret = 0;
setlocale(LC_NUMERIC, "en_US");
pagesize = getpagesize();
- ncpus = sysconf(_SC_NPROCESSORS_ONLN);
- if (ncpus < 0) {
- fprintf(stderr, "sysconf(_SC_NPROCESSORS_ONLN) failed %d/%s\n",
+ online_cpus = get_online_cpus();
+ if (!online_cpus) {
+ fprintf(stderr, "cannot get online cpus %d/%s\n",
errno, strerror(errno));
ret = 1;
goto out;
goto out;
}
+ ncpus = CPU_COUNT_S(CPU_ALLOC_SIZE(max_cpus), online_cpus);
if (ndevs > 1 && output_name && strcmp(output_name, "-") != 0) {
fprintf(stderr, "-o not supported with multiple devices\n");
ret = 1;