Example #1
0
int main()
{
    __ioprio_get(IOPRIO_WHO_USER, 0);
    //staptest// ioprio_get (IOPRIO_WHO_USER, 0) = NNNN

    __ioprio_set(IOPRIO_WHO_PROCESS, 0, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 7));
    //staptest// ioprio_set (IOPRIO_WHO_PROCESS, 0, IOPRIO_CLASS_BE|7) = NNNN

    /* Limits testing */

    __ioprio_get(-1, 0);
    //staptest// ioprio_get (-1, 0) = NNNN

    __ioprio_get(IOPRIO_WHO_PGRP, -1);
    //staptest// ioprio_get (IOPRIO_WHO_PGRP, -1) = NNNN

    __ioprio_set(-1, 0, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 7));
    //staptest// ioprio_set (-1, 0, IOPRIO_CLASS_BE|7) = NNNN

    __ioprio_set(IOPRIO_WHO_PROCESS, -1, IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 7));
    //staptest// ioprio_set (IOPRIO_WHO_PROCESS, -1, IOPRIO_CLASS_BE|7) = NNNN

    __ioprio_set(IOPRIO_WHO_PROCESS, 0, -1);
    //staptest// ioprio_set (IOPRIO_WHO_PROCESS, 0, 0x7ffff|NNNN) = NNNN

    return 0;
}
Example #2
0
int ionice_parse(const char* value) {

	if (!strcmp(value, "none"))
		return IOPRIO_CLASS_NONE;

	if (!strcmp(value, "idle"))
		return IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 7);

	char _class[13];
	int _data = 4;

	if (sscanf(value, "%12[^,],%d", &_class[0], &_data) < 1)
		fatal("Invalid ionice spec.\n");

	if ((_data < 0) || (_data > 7))
		fatal("Invalid ionice data value (must be between 0 and 7).\n");

	if (!strcmp(_class, "realtime") || !strcmp(_class, "rt"))
		return IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, _data);

	if (!strcmp(_class, "best-effort") || !strcmp(_class, "be"))
		return IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, _data);

	fatal("Invalid ionice spec.\n");
	return -1; /* avoid compiler warning */
}
Example #3
0
static void *scrub_one_dev(void *ctx)
{
	struct scrub_progress *sp = ctx;
	int ret;
	struct timeval tv;

	sp->stats.canceled = 0;
	sp->stats.duration = 0;
	sp->stats.finished = 0;

	ret = syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, 0,
		      IOPRIO_PRIO_VALUE(sp->ioprio_class,
					sp->ioprio_classdata));
	if (ret)
		fprintf(stderr,
			"WARNING: setting ioprio failed: %s (ignored).\n",
			strerror(errno));

	ret = ioctl(sp->fd, BTRFS_IOC_SCRUB, &sp->scrub_args);
	gettimeofday(&tv, NULL);
	sp->ret = ret;
	sp->stats.duration = tv.tv_sec - sp->stats.t_start;
	sp->stats.canceled = !!ret;
	sp->ioctl_errno = errno;
	ret = pthread_mutex_lock(&sp->progress_mutex);
	if (ret)
		return ERR_PTR(-ret);
	sp->stats.finished = 1;
	ret = pthread_mutex_unlock(&sp->progress_mutex);
	if (ret)
		return ERR_PTR(-ret);

	return NULL;
}
Example #4
0
static void set_priorities() {
  // Downgrade to lowest IO priority. We fork a process for each CPU, which
  // during parsing can slam the disk so hard that the system becomes
  // unresponsive. While it's unclear why the Linux IO scheduler can't deal with
  // this better, increasing our startup time in return for a usable system
  // while we start up is the right tradeoff. (Especially in Facebook's
  // configuration, where hh_server is often started up in the background well
  // before the user needs hh_client, so our startup time often doesn't matter
  // at all!)
  //
  // No need to check the return value, if we failed then whatever.
  #ifdef __linux__
  syscall(
    SYS_ioprio_set,
    IOPRIO_WHO_PROCESS,
    my_pid,
    IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 7)
  );
  #endif

  // Don't slam the CPU either, though this has much less tendency to make the
  // system totally unresponsive so we don't need to lower all the way.
  int dummy = nice(10);
  (void)dummy; // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509
}
Example #5
0
void set_real_time_priority()
{
#if defined __linux__ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,13)
  if (syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, getpid(), IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 7)) < 0)
    perror("ioprio_set");
#else
  fprintf(stderr, "warning: kernel does not support IO priority\n");
#endif

#if defined __linux__ && LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,18)
  struct sched_param sp;
  sp.sched_priority = sched_get_priority_min(SCHED_RR);

  if (sched_setscheduler(0, SCHED_RR, &sp) < 0)
    perror("sched_setscheduler");
#else
  fprintf(stderr, "warning: kernel does not support RT scheduler\n");
#endif

#if defined __linux__
  if (mlockall(MCL_CURRENT | MCL_FUTURE) < 0)
    perror("mlockall");
#else
  fprintf(stderr, "warning: kernel cannot lock application in memory\n");
#endif
}
Example #6
0
static void ioprio_setpid(pid_t pid, int ioclass, int data)
{
	int rc = ioprio_set(IOPRIO_WHO_PROCESS, pid,
			    IOPRIO_PRIO_VALUE(ioclass, data));

	if (rc == -1 && !tolerant)
		err(EXIT_FAILURE, _("ioprio_set failed"));
}
Example #7
0
static void ioprio_setid(int which, int ioclass, int data, int who)
{
	int rc = ioprio_set(who, which,
			    IOPRIO_PRIO_VALUE(ioclass, data));

	if (rc == -1 && !tolerant)
		err(EXIT_FAILURE, _("ioprio_set failed"));
}
Example #8
0
void
maximize_priority(void)
{
	if (skip_rt) {
		cl_log(LOG_INFO, "Not elevating to realtime (-R specified).");
		return;
	}

        sbd_make_realtime(0, 256, 256);

	if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(),
			IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT, 1)) != 0) {
		cl_perror("ioprio_set() call failed.");
	}
}
/*
 * A wrapper around ioprio_set(); sets process I/O priority.
 * ioclass can be either IOPRIO_CLASS_RT, IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE
 * or 0. iodata goes from 0 to 7 depending on ioclass specified.
 */
static PyObject*
linux_ioprio_set(PyObject* self, PyObject* args)
{
    long pid;
    int ioprio, ioclass, iodata;
    int retval;

    if (! PyArg_ParseTuple(args, "lii", &pid, &ioclass, &iodata)) {
        return NULL;
    }
    ioprio = IOPRIO_PRIO_VALUE(ioclass, iodata);
    retval = ioprio_set(IOPRIO_WHO_PROCESS, pid, ioprio);
    if (retval == -1) {
        return PyErr_SetFromErrno(PyExc_OSError);
    }
    Py_INCREF(Py_None);
    return Py_None;
}
Example #10
0
value hh_set_priorities(value cpu_prio_val, value io_prio_val) {
  CAMLparam2(cpu_prio_val, io_prio_val);
  int cpu_prio = Long_val(cpu_prio_val);
  int io_prio = Long_val(io_prio_val);

  // No need to check the return value, if we failed then whatever.
  #ifdef __linux__
  syscall(
    SYS_ioprio_set,
    IOPRIO_WHO_PROCESS,
    getpid(),
    IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, io_prio)
  );
  #endif

  #ifdef _WIN32
  SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
  // One might also try: PROCESS_MODE_BACKGROUND_BEGIN
  #else
  int dummy = nice(cpu_prio);
  (void)dummy; // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509
  #endif
  CAMLreturn(Val_unit);
}
Example #11
0
static struct request *nvme_nvm_alloc_request(struct request_queue *q,
					      struct nvm_rq *rqd,
					      struct nvme_nvm_command *cmd)
{
	struct nvme_ns *ns = q->queuedata;
	struct request *rq;

	nvme_nvm_rqtocmd(rqd, ns, cmd);

	rq = nvme_alloc_request(q, (struct nvme_command *)cmd, 0, NVME_QID_ANY);
	if (IS_ERR(rq))
		return rq;

	rq->cmd_flags &= ~REQ_FAILFAST_DRIVER;

	if (rqd->bio) {
		blk_init_request_from_bio(rq, rqd->bio);
	} else {
		rq->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, IOPRIO_NORM);
		rq->__data_len = 0;
	}

	return rq;
}
Example #12
0
int main(int argc, char **argv)
{
	char *buffer;
	int i, c, retval, groupcount, groupsize;
	uint32_t sectorsize;
	uint64_t numblocks;
	off64_t offset;
	struct timespec rqtp;
	float rands[RANDNUM], times[RANDNUM];
	char *devname = NULL;

	/* Allocate buffer aligned in memory */
	if (posix_memalign((void **) &buffer, sysconf(_SC_PAGESIZE), sizeof(char)*2*BLOCKNUM)) {
		printf("Failed to posix_memalign buffer size.\n");
		exit(EXIT_FAILURE);
	}

	out[0] = inp[0] = '\0';

	while (1) {
		int option_index = 0;
		
		c = getopt_long(argc, argv, "w:dhvp:i:o:c:t:s:S:P:Z:", long_options,
						&option_index);
		if (c == -1)
			break;
		
		switch (c) {
			case 'w': /* -w or --workload */
				if (!strcmp(optarg,"RAND") || !strcmp(optarg,"0"))
					workload = RANDWKLD;
				else if (!strcmp(optarg,"SEQL") || !strcmp(optarg,"1"))
					workload = SEQLWKLD;
				else if (!strcmp(optarg,"SCRUB") || !strcmp(optarg,"2"))
					workload = SCRUBDEV;
				else if (!strcmp(optarg,"CACHE") || !strcmp(optarg,"3"))
					workload = TESTCACHE;
				break;
			case 'c': /* -c or --count */
				maxcount = atoi(optarg);
				if (maxcount < 0) {
					fprintf(stderr, "bad argument to '--count'\n");
					exit(EXIT_FAILURE);
				}
				break;
			case 't': /* -t or --runtime */
				runtime = atoi(optarg);
				if (runtime < 0) {
					fprintf(stderr, "bad argument to '--runtime'\n");
					exit(EXIT_FAILURE);
				}
				break;
			case 'd': /* -d or --direct */
				direct = 1;
				break;
			case 'h': /* -h or --help */
			case '?':
				usage();
				exit(EXIT_SUCCESS);
			case 'v': /* -v or --verbose */
				++verbose;
				break;
			case 'p': /* -p or --priority */
				if (!strcmp(optarg,"IDLE") || !strcmp(optarg,"0"))
					priority = IDLEPRIO;
				else if (!strcmp(optarg,"DEF") || !strcmp(optarg,"1"))
					priority = DEFPRIO;
				else if (!strcmp(optarg,"RT") || !strcmp(optarg,"2"))
					priority = RTPRIO;
				break;
			case 'i': /* -i or --input */
				if (optarg == NULL) {
					fprintf(stderr, "bad argument to '--input'\n");
					exit(EXIT_FAILURE);
				}
				strcpy(inp, optarg);
				break;
			case 'o': /* -o or --output */
				if (optarg == NULL) {
					fprintf(stderr, "bad argument to '--output'\n");
					exit(EXIT_FAILURE);
				}
				strcpy(out, optarg);
				break;
			case 's': /* -s or --seed */
				seed = atoi(optarg);
				if (seed < 0) {
					fprintf(stderr, "bad argument to '--seed'\n");
					exit(EXIT_FAILURE);
				}
				break;
			case 'S': /* -S or --sectors */
				sectorcount = (uint64_t) atoi(optarg);
				break;
			case 'P': /* -P or --start */
				sectorstart = (uint64_t) atoi(optarg);
				break;
			case 'Z': /* -Z or --thinktime */
				thinkprob = atof(optarg);
				if (thinkprob < 0.0) {
					fprintf(stderr, "bad argument to '--thinktime'\n");
					exit(EXIT_FAILURE);
				}
				break;
			default:
				fprintf(stderr, "unrecognised option code 0x%x ??\n", c);
				usage();
				exit(EXIT_FAILURE);
		}
	}

	if (optind < argc) {
		if (NULL == devname) {
			devname = argv[optind];
			++optind;
		}
		if (optind < argc) {
			for (; optind < argc; ++optind)
				fprintf(stderr, "Unexpected extra argument: %s\n", argv[optind]);
			usage();
			exit(EXIT_FAILURE);
		}
	}

	if (devname == NULL) {
		fprintf(stderr, "no device specified\n");
		usage();
		exit(EXIT_FAILURE);
	}

	/* Set the seed to a specific value */
	srand(seed);

	/* Set the I/O scheduling class and priority for the scrubber */
	if (priority == IDLEPRIO) {
		retval = ioprio_set(IOPRIO_WHO_PROCESS, (int) getpid(),
				IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE,0));
		handle("ioprio_set", retval < 0);
	} else if (priority == RTPRIO) {
		retval = ioprio_set(IOPRIO_WHO_PROCESS, (int) getpid(),
				IOPRIO_PRIO_VALUE(IOPRIO_CLASS_RT,0));
		handle("ioprio_set", retval < 0);
	}

	setvbuf(stdout, NULL, _IONBF, 0);

	if (inp[0] != '\0') {
		inpf = fopen(inp, "r");
		if (inpf == NULL) {
			fprintf(stderr, "failed to open input file '%s'\n", inp);
			exit(EXIT_FAILURE);
		}
	}

	if (out[0] != '\0') {
		outf = fopen(out, "w");
		if (outf == NULL) {
			fprintf(stderr, "failed to open output file '%s'\n", out);
			exit(EXIT_FAILURE);
		}
	}

	if (inpf != NULL) {
		for (num=0; num<RANDNUM; num++)
			fscanf(inpf, "%f", &times[num]);
	} /* else {
		for (num=0; num<RANDNUM; num++)
			times[num] = rand() / (float) RAND_MAX;
	} */

	if (direct)
		dev = open(devname, O_RDONLY|O_DIRECT);
	else
		dev = open(devname, O_RDONLY);
	handle("open", dev < 0);

	/* Retrieve device's size in *sectors* */
	retval = ioctl(dev, BLKGETSIZE, &numblocks);
	handle("ioctl (devsize)", retval == -1);
	if (sectorcount && (sectorstart + sectorcount) < numblocks)
		numblocks = sectorcount;

	/* Retrieve sector size in *bytes* -- most probably 512b */
	retval = ioctl(dev, BLKSSZGET, &sectorsize);
	handle("ioctl (sector)", retval == -1);

	/* Convert number of blocks to number of *requests* */
	numblocks = numblocks / (BLOCKNUM / sectorsize);
	//fprintf(stderr, "Number of blocks = %lu (sector = %u)\n", numblocks, sectorsize);
	handle("numblocks <= 0", numblocks <= 0);

	if (verbose)
		printf("Benchmarking %s [%luMB], press Ctrl-C to terminate.\n",
		       devname, numblocks * BLOCKNUM / (1024*1024));

	/* Start timing program execution */
	gettimeofday(&start, NULL);
	//signal(SIGALRM, &update);
	signal(SIGINT, &done);
	//alarm(1);

	num = 0;
	offset = 0;
	total = 0.0;

	/* Group count and size for CLUST workload */
	groupcount = 0;
	//groupsize = (int) (50 * (rand() / (float) RAND_MAX));
	groupsize = (int) 128;

	/* lap0 and lap1 make sure think time is included when recording */
	lap0.tv_sec = start.tv_sec;
	lap0.tv_usec = start.tv_usec;

	if (workload == TESTCACHE) {
		/* Test whether the cache is on */
		struct timeval ra, rb;
		int k;
		long double total1 = 0.0, total2 = 0.0;

		for (k = 0; k < 16384; k++)
			retval = segread(dev, buffer, sysconf(_SC_PAGESIZE),
					k * sysconf(_SC_PAGESIZE), 1, 0);

		for (k = 0; k < 50; k++) {
			retval = segread(dev, buffer, sysconf(_SC_PAGESIZE),
					testblks[k], 1, 1);
			testtimes1[k] = timediff(ra, rb);
			total1 += testtimes1[k];
		}

		for (k = 0; k < 50; k++) {
			retval = segread(dev, buffer, sysconf(_SC_PAGESIZE),
					testblks[k] + sysconf(_SC_PAGESIZE), 1, 1);
			testtimes2[k] = timediff(ra, rb);
			total2 += testtimes2[k];
		}

		for (k = 0; k < 50; k++) {
			fprintf(stdout, "Sector: %lu -- Self=%Lf, Next=%Lf\n",
				testblks[k], testtimes1[k], testtimes2[k]);
		}

		total1 /= 50.0;
		total2 /= 50.0;
		fprintf(stdout, "\nAverage:: Self=%Lf, Next=%Lf\n", total1, total2);
	} else {
		for (;;) {
			long delay;

			/* Only enter this code block when you're about to think */
			if (thinkprob && (rand() / (float) RAND_MAX) <= thinkprob) {
				//gettimeofday(&lap1, NULL);
				rqtp.tv_sec = 0;
				/* Introduce a delay analogous to the disk's rotational latency */
				delay = times[num++] * 10000000;
				if (num >= 199990) num = 0;
				if (delay >= 1000000000)
					rqtp.tv_nsec = 999999999;
				else
					rqtp.tv_nsec = delay;
				//if (VERBOSE)
				//	printf("Delaying work for %ld.\n", rqtp.tv_nsec);
				//total += timediff(lap0, lap1);
				nanosleep(&rqtp,NULL);
				//gettimeofday(&lap0, NULL);
			}

			/* If the workload is RAND, then choose the next sector in a uniform random manner */
			if (workload == RANDWKLD)
				offset = (off64_t) (numblocks * (rand() / (float) RAND_MAX));
			/* If the workload is CLUST, choose next consequent sector or pick a random one if
			   the group has been read */
			else if (workload == SEQLWKLD) {
				if (groupcount == groupsize) {
					offset = (off64_t) (numblocks * (rand() / (float) RAND_MAX));
					//groupsize = (int) (50 * (rand() / (float) RAND_MAX));
					groupcount = 0;
				} else groupcount++;
			}

			/* Convert offset from request no. to *bytes* and issue the read() */
			retval = segread(dev, buffer, BLOCKNUM, offset * BLOCKNUM, direct, 1);

			/* Keep the output in bytes as well, for readability */
			if (outf != NULL)
				/* fprintf(outf, "%lu\t%Lf\n", offset * BLOCKNUM, timediff(reqa, reqb)); */
				fprintf(outf, "%Lf\n", timediff(reqa, reqb));
			totaltime += timediff(reqa, reqb);

			handle("segread", retval < 0);
			if ((maxcount && count >= maxcount) || (num >= RANDNUM-3))
				done();
			count++;

			if (workload == SEQLWKLD || workload == SCRUBDEV)
				offset = (off64_t) (offset + 1) % numblocks;
		}
	}
	/* notreached */
}
Example #13
0
static int replay(const char *root) {
        _cleanup_close_ int inotify_fd = -1;
        _cleanup_free_ char *pack_fn = NULL;
        _cleanup_fclose_ FILE *pack = NULL;
        bool on_ssd, ready = false;
        char line[LINE_MAX];
        int prio, c;

        assert(root);

        if (asprintf(&pack_fn, "%s/.readahead", root) < 0)
                return log_oom();

        pack = fopen(pack_fn, "re");
        if (!pack) {
                if (errno == ENOENT) {
                        log_debug("No pack file found.");
                        return 0;
                }

                log_error("Failed to open pack file: %m");
                return -errno;
        }

        posix_fadvise(fileno(pack), 0, 0, POSIX_FADV_WILLNEED);

        inotify_fd = open_inotify();
        if (inotify_fd < 0)
                return inotify_fd;

        if (!fgets(line, sizeof(line), pack)) {
                log_error("Premature end of pack file.");
                return -EIO;
        }

        char_array_0(line);

        if (!streq(line, CANONICAL_HOST READAHEAD_PACK_FILE_VERSION)) {
                log_debug("Pack file host or version type mismatch.");
                goto done;
        }

        c = getc(pack);
        if (c == EOF) {
                log_debug("Premature end of pack file.");
                return -EIO;
        }

        /* We do not retest SSD here, so that we can start replaying
         * before udev is up.*/
        on_ssd = c == 'S';
        log_debug("On SSD: %s", yes_no(on_ssd));

        if (on_ssd)
                prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
        else
                /* We are not using RT here, since we'd starve IO that
                we didn't record (which is for example blkid, since
                its disk accesses go directly to the block device and
                are thus not visible in fallocate) to death. However,
                we do ask for an IO prio that is slightly higher than
                the default (which is BE. 4) */
                prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 2);

        if (ioprio_set(IOPRIO_WHO_PROCESS, getpid(), prio) < 0)
                log_warning("Failed to set IDLE IO priority class: %m");

        sd_notify(0, "STATUS=Replaying readahead data");

        log_debug("Replaying...");

        if (access("/run/systemd/readahead/noreplay", F_OK) >= 0) {
                log_debug("Got termination request");
                goto done;
        }

        while (!feof(pack) && !ferror(pack)) {
                uint8_t inotify_buffer[sizeof(struct inotify_event) + FILENAME_MAX];
                int k;
                ssize_t n;

                n = read(inotify_fd, &inotify_buffer, sizeof(inotify_buffer));
                if (n < 0) {
                        if (errno != EINTR && errno != EAGAIN) {
                                log_error("Failed to read inotify event: %m");
                                return -errno;
                        }
                } else {
                        struct inotify_event *e = (struct inotify_event*) inotify_buffer;

                        while (n > 0) {
                                size_t step;

                                if ((e->mask & IN_CREATE) && streq(e->name, "noreplay")) {
                                        log_debug("Got termination request");
                                        goto done;
                                }

                                step = sizeof(struct inotify_event) + e->len;
                                assert(step <= (size_t) n);

                                e = (struct inotify_event*) ((uint8_t*) e + step);
                                n -= step;
                        }
                }

                k = unpack_file(pack);
                if (k < 0)
                        return k;

                if (!ready) {
                        /* We delay the ready notification until we
                         * queued at least one read */
                        sd_notify(0, "READY=1");
                        ready = true;
                }
        }

done:
        if (ferror(pack)) {
                log_error("Failed to read pack file.");
                return -EIO;
        }

        if (!ready)
                sd_notify(0, "READY=1");

        log_debug("Done.");
        return 0;
}