Beispiel #1
0
static void
cv_resched(struct rumpuser_mtx *mtx, int nlocks)
{

	/* see rumpuser(3) */
	if ((mtx->flags & (RUMPUSER_MTX_KMUTEX | RUMPUSER_MTX_SPIN)) ==
	    (RUMPUSER_MTX_KMUTEX | RUMPUSER_MTX_SPIN)) {
		rumpkern_sched(nlocks, mtx);
		rumpuser_mutex_enter_nowrap(mtx);
	} else {
		rumpuser_mutex_enter_nowrap(mtx);
		rumpkern_sched(nlocks, mtx);
	}
}
Beispiel #2
0
int
rumpuser_sp_anonmmap(void *arg, size_t howmuch, void **addr)
{
	struct spclient *spc = arg;
	void *resp, *rdata = NULL; /* XXXuninit */
	int nlocks, rv;

	rumpkern_unsched(&nlocks, NULL);

	rv = anonmmap_req(spc, howmuch, &rdata);
	if (rv) {
		rv = EFAULT;
		goto out;
	}

	resp = *(void **)rdata;
	free(rdata);

	if (resp == NULL) {
		rv = ENOMEM;
	}

	*addr = resp;

 out:
	rumpkern_sched(nlocks, NULL);
	ET(rv);
}
Beispiel #3
0
void
rumpuser_component_schedule(void *cookie)
{
	int nlocks = (int)(intptr_t)cookie;

	rumpkern_sched(nlocks, NULL);
}
int
rumpuser_iovwrite(int fd, const struct rumpuser_iovec *ruiov, size_t iovlen,
	int64_t roff, size_t *retp)
{
	const struct iovec *iov = (const struct iovec *)ruiov;
	off_t off = (off_t)roff;
	ssize_t nn;
	int rv;

	if (off == RUMPUSER_IOV_NOSEEK) {
		KLOCK_WRAP(nn = writev(fd, iov, iovlen));
	} else {
		int nlocks;

		rumpkern_unsched(&nlocks, NULL);
		if (lseek(fd, off, SEEK_SET) == off) {
			nn = writev(fd, iov, iovlen);
		} else {
			nn = -1;
		}
		rumpkern_sched(nlocks, NULL);
	}

	if (nn == -1) {
		rv = errno;
	} else {
		*retp = (size_t)nn;
		rv = 0;
	}

	ET(rv);
}
Beispiel #5
0
int
rumpuser_clock_sleep(int enum_rumpclock, int64_t sec, long nsec)
{
	enum rumpclock rclk = enum_rumpclock;
	struct timespec rqt, rmt;
	int nlocks;
	int rv;

	rumpkern_unsched(&nlocks, NULL);

	/*LINTED*/
	rqt.tv_sec = sec;
	/*LINTED*/
	rqt.tv_nsec = nsec;

	switch (rclk) {
	case RUMPUSER_CLOCK_RELWALL:
		do {
			rv = nanosleep(&rqt, &rmt);
			rqt = rmt;
		} while (rv == -1 && errno == EINTR);
		if (rv == -1) {
			rv = errno;
		}
		break;
	case RUMPUSER_CLOCK_ABSMONO:
		do {
#ifdef HAVE_CLOCK_NANOSLEEP
			rv = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME,
			    &rqt, NULL);
#else
			/* le/la/der/die/das sigh. timevalspec tailspin */
			struct timespec ts, tsr;
			clock_gettime(CLOCK_REALTIME, &ts);
			if (ts.tv_sec == rqt.tv_sec ?
			    ts.tv_nsec > rqt.tv_nsec : ts.tv_sec > rqt.tv_sec) {
				rv = 0;
			} else {
				tsr.tv_sec = rqt.tv_sec - ts.tv_sec;
				tsr.tv_nsec = rqt.tv_nsec - ts.tv_nsec;
				if (tsr.tv_nsec < 0) {
					tsr.tv_sec--;
					tsr.tv_nsec += 1000*1000*1000;
				}
				rv = nanosleep(&tsr, NULL);
			}
#endif
		} while (rv == -1 && errno == EINTR);
		if (rv == -1) {
			rv = errno;
		}
		break;
	default:
		abort();
	}

	rumpkern_sched(nlocks, NULL);

	ET(rv);
}
Beispiel #6
0
void
VIFHYPER_SEND(struct virtif_user *viu,
	struct iovec *iov, size_t iovlen)
{
	size_t tlen, i;
	int nlocks;
	void *d;
	char *d0;

	rumpkern_unsched(&nlocks, NULL);
	/*
	 * netfront doesn't do scatter-gather, so just simply
	 * copy the data into one lump here.
	 */
	if (iovlen == 1) {
		d = iov->iov_base;
		tlen = iov->iov_len;
	} else {
		for (i = 0, tlen = 0; i < iovlen; i++) {
			tlen += iov[i].iov_len;
		}
		d = d0 = malloc(tlen);
		for (i = 0; i < iovlen; i++) {
			memcpy(d0, iov[i].iov_base, iov[i].iov_len);
			d0 += iov[i].iov_len;
		}
	}

	netfront_xmit(viu->viu_dev, d, tlen);

	if (iovlen != 1)
		free(d);

	rumpkern_sched(nlocks, NULL);
}
Beispiel #7
0
static int
devopen(int num)
{
	int devnum = 768 + (num<<6);
	char buf[32];
	int nlocks;

	if (blkopen[num]) {
		blkopen[num]++;
		return 1;
	}

	snprintf(buf, sizeof(buf), "device/vbd/%d", devnum);

	rumpkern_unsched(&nlocks, NULL);
	blkdevs[num] = init_blkfront(buf, &blkinfos[num]);
	rumpkern_sched(nlocks, NULL);

	if (blkdevs[num] != NULL) {
		blkopen[num] = 1;
		return 0;
	} else {
		return EIO; /* guess something */
	}
}
Beispiel #8
0
int
rumpuser_clock_sleep(int enum_rumpclock, int64_t sec, long nsec)
{
	enum rumpclock rclk = enum_rumpclock;
	struct thread *thread;
	uint32_t msec;
	int nlocks;

	rumpkern_unsched(&nlocks, NULL);
	switch (rclk) {
	case RUMPUSER_CLOCK_RELWALL:
		msec = sec * 1000 + nsec / (1000*1000UL);
		msleep(msec);
		break;
	case RUMPUSER_CLOCK_ABSMONO:
		thread = get_current();
		thread->wakeup_time = sec * (1000*1000*1000ULL) + nsec;
		clear_runnable(thread);
		schedule();
		break;
	}
	rumpkern_sched(nlocks, NULL);

	return 0;
}
Beispiel #9
0
void
rumpuser_mutex_enter(struct rumpuser_mtx *mtx)
{
	int nlocks;

	if (rumpuser_mutex_tryenter(mtx) != 0) {
		rumpkern_unsched(&nlocks, NULL);
		while (rumpuser_mutex_tryenter(mtx) != 0)
			wait(&mtx->waiters, BMK_SCHED_BLOCK_INFTIME);
		rumpkern_sched(nlocks, NULL);
	}
}
Beispiel #10
0
int
rumpuser_close(int fd)
{
	int nlocks;

	rumpkern_unsched(&nlocks, NULL);
	fsync(fd);
	close(fd);
	rumpkern_sched(nlocks, NULL);

	ET(0);
}
Beispiel #11
0
int
rumpuser_sp_raise(void *arg, int signo)
{
	struct spclient *spc = arg;
	int rv, nlocks;

	rumpkern_unsched(&nlocks, NULL);
	rv = send_raise_req(spc, signo);
	rumpkern_sched(nlocks, NULL);

	return rv;
}
Beispiel #12
0
static int
sp_copyout(void *arg, const void *laddr, void *raddr, size_t dlen)
{
	struct spclient *spc = arg;
	int nlocks, rv;

	rumpkern_unsched(&nlocks, NULL);
	rv = send_copyout_req(spc, raddr, laddr, dlen);
	rumpkern_sched(nlocks, NULL);

	if (rv)
		rv = EFAULT;
	ET(rv);
}
Beispiel #13
0
void
rumpuser_bio(int fd, int op, void *data, size_t dlen, int64_t off,
	rump_biodone_fn biodone, void *donearg)
{
	static int bio_inited;
	struct biocb *bio = memalloc(sizeof(*bio), 0);
	struct blkfront_aiocb *aiocb = &bio->bio_aiocb;
	int nlocks;
	int num = fd - BLKFDOFF;

	rumpkern_unsched(&nlocks, NULL);

	if (!bio_inited) {
		rumpuser_mutex_enter_nowrap(bio_mtx);
		if (!bio_inited) {
			bio_inited = 1;
			rumpuser_mutex_exit(bio_mtx);
			create_thread("biopoll", biothread, NULL);
		} else {
			rumpuser_mutex_exit(bio_mtx);
		}
	}

	bio->bio_done = biodone;
	bio->bio_arg = donearg;
	bio->bio_num = num;

	aiocb->aio_dev = blkdevs[num];
	aiocb->aio_buf = data;
	aiocb->aio_nbytes = dlen;
	aiocb->aio_offset = off;
	aiocb->aio_cb = biocomp;
	aiocb->data  = bio;

	if (op & RUMPUSER_BIO_READ)
		blkfront_aio_read(aiocb);
	else
		blkfront_aio_write(aiocb);

	rumpuser_mutex_enter(bio_mtx);
	bio_outstanding_total++;
	blkdev_outstanding[num]++;
	rumpuser_cv_signal(bio_cv);
	rumpuser_mutex_exit(bio_mtx);

	rumpkern_sched(nlocks, NULL);
}
Beispiel #14
0
static void
biocomp(struct blkfront_aiocb *aiocb, int ret)
{
	struct biocb *bio = aiocb->data;
	int dummy, num;

	rumpkern_sched(0, NULL);
	if (ret)
		bio->bio_done(bio->bio_arg, 0, EIO);
	else
		bio->bio_done(bio->bio_arg, bio->bio_aiocb.aio_nbytes, 0);
	rumpkern_unsched(&dummy, NULL);
	num = bio->bio_num;
	xfree(bio);

	rumpuser_mutex_enter_nowrap(bio_mtx);
	bio_outstanding_total--;
	blkdev_outstanding[num]--;
	rumpuser_mutex_exit(bio_mtx);
}
Beispiel #15
0
static int
sp_copyin(void *arg, const void *raddr, void *laddr, size_t *len, int wantstr)
{
	struct spclient *spc = arg;
	void *rdata = NULL; /* XXXuninit */
	int rv, nlocks;

	rumpkern_unsched(&nlocks, NULL);

	rv = copyin_req(spc, raddr, len, wantstr, &rdata);
	if (rv)
		goto out;

	memcpy(laddr, rdata, *len);
	free(rdata);

 out:
	rumpkern_sched(nlocks, NULL);
	if (rv)
		rv = EFAULT;
	ET(rv);
}
Beispiel #16
0
void
rumpuser_rw_enter(int enum_rumprwlock, struct rumpuser_rw *rw)
{
	enum rumprwlock lk = enum_rumprwlock;
	struct waithead *w = NULL;
	int nlocks;

	switch (lk) {
	case RUMPUSER_RW_WRITER:
		w = &rw->wwait;
		break;
	case RUMPUSER_RW_READER:
		w = &rw->rwait;
		break;
	}

	if (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0) {
		rumpkern_unsched(&nlocks, NULL);
		while (rumpuser_rw_tryenter(enum_rumprwlock, rw) != 0)
			wait(w, BMK_SCHED_BLOCK_INFTIME);
		rumpkern_sched(nlocks, NULL);
	}
}
Beispiel #17
0
int
VIFHYPER_CREATE(int devnum, struct virtif_sc *vif_sc, uint8_t *enaddr,
	struct virtif_user **viup)
{
	struct virtif_user *viu = NULL;
	int rv, nlocks;

	rumpkern_unsched(&nlocks, NULL);

	viu = malloc(sizeof(*viu));
	if (viu == NULL) {
		rv = ENOMEM;
		goto out;
	}
	memset(viu, 0, sizeof(*viu));
	viu->viu_vifsc = vif_sc;

	viu->viu_dev = init_netfront(NULL, myrecv, enaddr, NULL, viu);
	if (!viu->viu_dev) {
		rv = EINVAL; /* ? */
		free(viu);
		goto out;
	}

	if (create_thread("xenifp", pusher, viu) == NULL) {
		printk("fatal thread creation failure\n"); /* XXX */
		do_exit();
	}

	rv = 0;

 out:
	rumpkern_sched(nlocks, NULL);

	*viup = viu;
	return rv;
}