Blob Blame Raw
commit 0a915aabe88ff98786a88f30d2e062ef34d0826c
Author: Nathan Zimmer <nzimmer@sgi.com>
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 <axboe@kernel.dk>
    
    Modified by Jens to fix the CPU_{SET,ZERO}_S pointer mixup.
    
    Signed-off-by: Nathan Zimmer <nzimmer@sgi.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

commit 67313d8f411fe08f3f8a0c94ad2cf45bf569f0f8
Author: Nathan Zimmer <nzimmer@sgi.com>
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 <axboe@kernel.dk>
    Signed-off-by: Nathan Zimmer <nzimmer@sgi.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

commit fb69749415ae2bd7c3180605d01a5a39f3bd988f
Author: Nathan Zimmer <nzimmer@sgi.com>
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 <axboe@kernel.dk>
    Signed-off-by: Nathan Zimmer <nzimmer@sgi.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>

commit 80c4041b2e7a7d5afb75df563bf51bb27773c095
Author: Abutalib Aghayev <agayev@gmail.com>
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 <axboe@fb.com>

commit f6541f75f2822252b057f08e9f5f0c40d4079a8c
Author: Roman Pen <r.peniaev@gmail.com>
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 <r.peniaev@gmail.com>
    Cc: Jens Axboe <axboe@fb.com>
    Cc: <linux-btrace@vger.kernel.org>
    Signed-off-by: Jens Axboe <axboe@fb.com>

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 <fcntl.h>
 #include <string.h>
 #include <unistd.h>
-
-#define MAX_CPUS	(512)
+#include <errno.h>
 
 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) {