commit 0a915aabe88ff98786a88f30d2e062ef34d0826c Author: Nathan Zimmer Date: Mon Apr 15 09:53:36 2013 -0500 blktrace blkreplay: convert to use a dynamic cpu_set_t Some distros have changed CPU_SETSIZE in glibc to 4096 since that matches the NR_CPUS in the linux kernel config file. Some distros have decided to leave CPU_SETSIZE at 1024. This is a problem if you want to run that distro on a very large machine. CPU_SETSIZE is use by the struct cpu_set_t. This means you to deal with cpus greater the 1024 you must use the dynamic cpu sets, which involves converting from things like CPU_SET to CPU_SET_S. Cc: Jens Axboe Modified by Jens to fix the CPU_{SET,ZERO}_S pointer mixup. Signed-off-by: Nathan Zimmer Signed-off-by: Jens Axboe commit 67313d8f411fe08f3f8a0c94ad2cf45bf569f0f8 Author: Nathan Zimmer Date: Mon Apr 15 09:53:35 2013 -0500 blktrace: use number of configured cpus instead of online cpus We want to run on all online processors. However is there is a hole in the online cpumask this won't happen. We need the number of configured processors instead of online. Cc: Jens Axboe Signed-off-by: Nathan Zimmer Signed-off-by: Jens Axboe commit fb69749415ae2bd7c3180605d01a5a39f3bd988f Author: Nathan Zimmer Date: Mon Apr 15 09:53:34 2013 -0500 btreplay: use sysconf to get the number of configured cpus We should use the standard methods for getting the number of cpus in the system when they are available. It is good practice to leave the old ways in place for people stuck on older systems. Cc: Jens Axboe Signed-off-by: Nathan Zimmer Signed-off-by: Jens Axboe commit 80c4041b2e7a7d5afb75df563bf51bb27773c095 Author: Abutalib Aghayev Date: Tue Feb 9 08:17:50 2016 -0700 blktrace: Use number of online CPUs Currently, blktrace uses _SC_NPROCESSORS_CONF to find out the number of CPUs. This is a problem, because if you reduce the number of online CPUs by passing kernel parameter maxcpus, then blktrace fails to start with the error: FAILED to start thread on CPU 4: 22/Invalid argument FAILED to start thread on CPU 5: 22/Invalid argument ... The attached patch fixes it to use _SC_NPROCESSORS_ONLN. Signed-off-by: Jens Axboe commit f6541f75f2822252b057f08e9f5f0c40d4079a8c Author: Roman Pen Date: Sat Apr 23 13:44:08 2016 +0200 btreplay: fix memory corruption caused by CPU_ZERO_S Size should be provided, not cpus number. Signed-off-by: Roman Pen Cc: Jens Axboe Cc: Signed-off-by: Jens Axboe Index: blktrace-1.0.5/blktrace.c =================================================================== --- blktrace-1.0.5.orig/blktrace.c +++ blktrace-1.0.5/blktrace.c @@ -621,13 +621,19 @@ static void dpp_free(struct devpath *dpp static int lock_on_cpu(int cpu) { - cpu_set_t cpu_mask; - - CPU_ZERO(&cpu_mask); - CPU_SET(cpu, &cpu_mask); - if (sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask) < 0) + cpu_set_t * cpu_mask; + size_t size; + cpu_mask = CPU_ALLOC(ncpus); + size = CPU_ALLOC_SIZE(ncpus); + + CPU_ZERO_S(size, cpu_mask); + CPU_SET_S(cpu, size, cpu_mask); + if (sched_setaffinity(0, size, cpu_mask) < 0) { + CPU_FREE(cpu_mask); return errno; + } + CPU_FREE(cpu_mask); return 0; } Index: blktrace-1.0.5/btreplay/btreplay.c =================================================================== --- blktrace-1.0.5.orig/btreplay/btreplay.c +++ blktrace-1.0.5/btreplay/btreplay.c @@ -502,19 +502,34 @@ static inline void start_iter(void) */ static void get_ncpus(void) { - cpu_set_t cpus; - - if (sched_getaffinity(getpid(), sizeof(cpus), &cpus)) { +#ifdef _SC_NPROCESSORS_ONLN + ncpus = sysconf(_SC_NPROCESSORS_ONLN); +#else + int nrcpus = 4096; + cpu_set_t * cpus; + +realloc: + cpus = CPU_ALLOC(nrcpus); + size = CPU_ALLOC_SIZE(nrcpus); + CPU_ZERO_S(size, cpus); + + if (sched_getaffinity(getpid(), size, cpus)) { + if( errno == EINVAL && nrcpus < (4096<<4) ) { + CPU_FREE(cpus); + nrcpus <= 1; + goto realloc; + } fatal("sched_getaffinity", ERR_SYSCALL, "Can't get CPU info\n"); /*NOTREACHED*/ } - /* - * XXX This assumes (perhaps wrongly) that there are no /holes/ - * XXX in the mask. - */ - for (ncpus = 0; ncpus < CPU_SETSIZE && CPU_ISSET(ncpus, &cpus); ncpus++) - ; + ncpus = -1; + for (last_cpu = 0; last_cpu < CPU_SETSIZE && CPU_ISSET(last_cpu, &cpus); last_cpu++) + if (CPU_ISSET( last_cpu, &cpus) ) + ncpus = last_cpu; + ncpus++; + CPU_FREE(cpus); +#endif if (ncpus == 0) { fatal(NULL, ERR_SYSCALL, "Insufficient number of CPUs\n"); /*NOTREACHED*/ @@ -527,25 +542,29 @@ static void get_ncpus(void) */ static void pin_to_cpu(struct thr_info *tip) { - cpu_set_t cpus; + cpu_set_t *cpus; + size_t size; + + cpus = CPU_ALLOC(ncpus); + size = CPU_ALLOC_SIZE(ncpus); assert(0 <= tip->cpu && tip->cpu < ncpus); - CPU_ZERO(&cpus); - CPU_SET(tip->cpu, &cpus); - if (sched_setaffinity(getpid(), sizeof(cpus), &cpus)) { + CPU_ZERO_S(size, cpus); + CPU_SET_S(tip->cpu, size, cpus); + if (sched_setaffinity(getpid(), size, cpus)) { fatal("sched_setaffinity", ERR_SYSCALL, "Failed to pin CPU\n"); /*NOTREACHED*/ } if (verbose > 1) { int i; - cpu_set_t now; + cpu_set_t *now = CPU_ALLOC(ncpus); - (void)sched_getaffinity(getpid(), sizeof(now), &now); + (void)sched_getaffinity(getpid(), size, now); fprintf(tip->vfp, "Pinned to CPU %02d ", tip->cpu); for (i = 0; i < ncpus; i++) - fprintf(tip->vfp, "%1d", CPU_ISSET(i, &now)); + fprintf(tip->vfp, "%1d", CPU_ISSET_S(i, size, now)); fprintf(tip->vfp, "\n"); } } Index: blktrace-1.0.5/verify_blkparse.c =================================================================== --- blktrace-1.0.5.orig/verify_blkparse.c +++ blktrace-1.0.5/verify_blkparse.c @@ -3,18 +3,33 @@ #include #include #include - -#define MAX_CPUS (512) +#include int main(int argc, char *argv[]) { double this_time, last_time; char line[256], last_line[256], *p; int major, minor, cpu, nr, alias; + long MAX_CPUS; unsigned long long total_entries; - unsigned int last_seq[MAX_CPUS], seq; + unsigned int *last_seq; + unsigned int seq; FILE *f; +#ifdef _SC_NPROCESSORS_ONLN + MAX_CPUS = sysconf(_SC_NPROCESSORS_ONLN); + if (MAX_CPUS < 1) + { + fprintf(stderr, "Could not determine number of CPUs online:\n%s\n", + strerror (errno)); + fprintf(stderr, "Assuming 1024\n"); + MAX_CPUS = 1024; + } +#else + MAX_CPUS = CPU_SETSIZE; +#endif + + last_seq = malloc( sizeof(unsigned int) * MAX_CPUS ); for (nr = 0; nr < MAX_CPUS; nr++) last_seq[nr] = -1; @@ -33,7 +48,7 @@ int main(int argc, char *argv[]) alias = nr = 0; total_entries = 0; while ((p = fgets(line, sizeof(line), f)) != NULL) { - if (sscanf(p, "%3d,%3d %2d %8d %lf", &major, &minor, &cpu, &seq, &this_time) != 5) + if (sscanf(p, "%3d,%3d %5d %8d %lf", &major, &minor, &cpu, &seq, &this_time) != 5) break; if (this_time < last_time) {