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) {