提交 59d5a46b 创建 作者: Nickolai Zeldovich's avatar Nickolai Zeldovich

Merge branch 'scale-amd64' of git+ssh://pdos.csail.mit.edu/home/am0/6.828/xv6 into scale-amd64

......@@ -23,7 +23,7 @@ OBJCOPY = $(TOOLPREFIX)objcopy
COMFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall \
-MD -ggdb -m64 -Werror -fms-extensions -mno-sse \
-mcmodel=large -mno-red-zone -I$(QEMUSRC) -fno-omit-frame-pointer \
-DHW_$(HW) -include param.h -include compiler.h
-DHW_$(HW) -include param.h -include compiler.h -DXV6
COMFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
CFLAGS := $(COMFLAGS) -std=c99
CXXFLAGS := $(COMFLAGS) -std=c++0x -Wno-sign-compare -fno-exceptions -fno-rtti
......@@ -48,6 +48,7 @@ OBJS = \
hwvm.o \
hz.o \
kalloc.o \
kernlet.o \
kmalloc.o \
kbd.o \
main.o \
......@@ -98,7 +99,8 @@ UPROGS= \
_sleep \
_dirbench \
_usertests \
_lockstat
_lockstat \
_preadtest
UPROGS := $(addprefix $(O)/, $(UPROGS))
all: $(O)/kernel
......
......@@ -122,6 +122,18 @@ setupkvm(void)
return pml4;
}
int
setupkshared(pml4e_t *pml4, char *kshared)
{
for (u64 off = 0; off < KSHAREDSIZE; off+=4096) {
pme_t *pte = walkpgdir(pml4, (void*)(KSHARED+off), 1);
if (pte == NULL)
panic("setupkshared: oops");
*pte = v2p(kshared+off) | PTE_P | PTE_U | PTE_W;
}
return 0;
}
// Switch h/w page table register to the kernel-only page table,
// for when no process is running.
void
......
struct ipcctl {
volatile char done;
volatile long result;
};
......@@ -28,6 +28,11 @@ static struct kmem slabmem[][NCPU] = {
.size = PERFSIZE,
.ninit = 1,
},
[slab_kshared][0 ... NCPU-1] = {
.name = " kshared",
.size = KSHAREDSIZE,
.ninit = CPUKSTACKS,
},
};
extern char end[]; // first address after kernel loaded from ELF file
......
......@@ -2,6 +2,7 @@
#include "lib.h"
#define KBASE 0xFFFFFF0000000000ull
#define KSHARED 0xFFFFF00000000000ull
#define USERTOP 0x0000800000000000ull
#define KCSEG (2<<3) /* kernel code segment */
......@@ -128,6 +129,7 @@ void gc_start(void);
// hwvm.c
void freevm(pml4e_t*);
pml4e_t* setupkvm(void);
int setupkshared(pml4e_t *pml4, char *kshared);
pme_t * walkpgdir(pml4e_t*, const void*, int);
// hz.c
......@@ -147,6 +149,7 @@ void ioapicenable(int irq, int cpu);
typedef enum {
slab_stack,
slab_perf,
slab_kshared,
} slab_t;
char* kalloc(void);
void kfree(void*);
......@@ -410,6 +413,8 @@ long sys_socket(int, int, int);
long sys_bind(int, void*, int);
long sys_listen(int, int);
long sys_accept(int, void*, void*);
long sys_pread(int fd, void *ubuf, size_t count, off_t offset);
long sys_kernlet(int, size_t, off_t);
// other exported/imported functions
void cmain(u64 mbmagic, u64 mbaddr);
......
#include "types.h"
#include "kernel.h"
#include "spinlock.h"
#include "condvar.h"
#include "cpu.h"
#include "proc.h"
#include "vm.h"
#include "fs.h"
#include "file.h"
#include "wq.h"
#include "ipc.h"
static void
pread_work(struct work *w, void *a0, void *a1, void *a2, void *a3)
{
struct inode *ip = a0;
void *kshared = a1;
struct ipcctl *ipc = kshared;
size_t count = (uptr)a2;
off_t off = (uptr)a3;
int r;
if (count > KSHAREDSIZE-PGSIZE)
panic("pread_work");
//cprintf("1: %p %p %lu %lu\n", ip, buf, count, off);
ilock(ip, 0);
r = readi(ip, kshared+PGSIZE, off, count);
iunlock(ip);
ipc->result = r;
barrier();
ipc->done = 1;
}
static struct work *
pread_allocwork(struct inode *ip, void *buf, size_t count, off_t off)
{
struct work *w = allocwork();
if (w == NULL)
return NULL;
//cprintf("0: %p %p %lu %lu\n", ip, buf, count, off);
w->rip = pread_work;
w->arg0 = ip;
w->arg1 = buf;
w->arg2 = (void*)count;
w->arg3 = (void*)off;
return w;
}
long
sys_kernlet(int fd, size_t count, off_t off)
{
struct file *f;
struct work *w;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1;
if(f->type != FD_INODE)
return -1;
w = pread_allocwork(f->ip, myproc()->vmap->kshared, count, off);
if (w == NULL)
return -1;
if (wq_push(w) < 0) {
freework(w);
return -1;
}
return 0;
}
......@@ -19,7 +19,7 @@ CXXFLAGS += -Ilwip/src/include -Inet -Ilwip/src/include/ipv4 -I. -DLWIP
LWIP_CFLAGS = -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall -MD -ggdb \
-m64 -Werror -std=c99 -fms-extensions -mno-sse -mcmodel=large -I$(QEMUSRC) \
-fno-omit-frame-pointer -DHW_$(HW) -include param.h -include compiler.h \
-Wno-attributes -Wno-address -Wno-char-subscripts \
-DXV6 -Wno-attributes -Wno-address -Wno-char-subscripts \
-Wno-unused-but-set-variable -Wno-format
LWIP_CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
......
......@@ -20,6 +20,7 @@
#define LOCKSTAT 0
#define VERIFYFREE LOCKSTAT
#define ALLOC_MEMSET 1
#define KSHAREDSIZE (32 << 10)
#define WQSHIFT 4
#if defined(HW_josmp)
#define NCPU 16 // maximum number of CPUs
......
#include "types.h"
#include "stat.h"
#include "fcntl.h"
#include "user.h"
#include "amd64.h"
#include "ipc.h"
// XXX(sbw) add a memlayout.h?
#define KSHARED 0xFFFFF00000000000ull
#define FSIZE (64 << 10)
#define BSIZE 4096
#define PSIZE (4*BSIZE)
static char buf[BSIZE];
struct ipcctl *ipcctl = (struct ipcctl*)KSHARED;
static void
kernlet_pread(int fd, size_t count, off_t off)
{
ipcctl->done = 0;
if (kernlet(fd, count, off) != 0)
die("kernlet");
}
int
main(int ac, char **av)
{
u64 t0, t1;
int i, k;
int fd;
fd = open("preadtest.x", O_CREATE|O_RDWR);
if (fd < 0)
die("open failed");
for (i = 0; i < FSIZE/BSIZE; i++)
if (write(fd, buf, BSIZE) != BSIZE)
die("write failed");
t0 = rdtsc();
for (k = 0; k < FSIZE; k+=PSIZE) {
kernlet_pread(fd, PSIZE, k);
while (ipcctl->done == 0)
nop_pause();
die("preadtest: %d\n", (int)ipcctl->result);
for (i = k; i < k+PSIZE; i+=BSIZE)
if (pread(fd, buf, BSIZE, i) != BSIZE)
die("pread failed");
}
t1 = rdtsc();
printf(1, "cycles %lu\n", t1 - t0);
exit();
}
......@@ -219,6 +219,7 @@ allocproc(void)
freeproc(p);
return 0;
}
sp = p->kstack + KSTACKSIZE;
// Leave room for trap frame.
......
......@@ -177,6 +177,8 @@ static long (*syscalls[])(u64, u64, u64, u64, u64, u64) = {
SYSCALL(bind),
SYSCALL(listen),
SYSCALL(accept),
SYSCALL(pread),
SYSCALL(kernlet),
};
void
......
......@@ -27,3 +27,5 @@
#define SYS_bind 26
#define SYS_listen 27
#define SYS_accept 28
#define SYS_pread 29
#define SYS_kernlet 30
......@@ -75,6 +75,27 @@ sys_read(void)
return fileread(f, p, n);
}
ssize_t
sys_pread(int fd, void *ubuf, size_t count, off_t offset)
{
struct file *f;
int r;
if(fd < 0 || fd >= NOFILE || (f=myproc()->ofile[fd]) == 0)
return -1;
// XXX(sbw) assuming ubuf is ok
if(f->type == file::FD_INODE){
ilock(f->ip, 0);
if(f->ip->type == 0)
panic("fileread");
r = readi(f->ip, (char*)ubuf, offset, count);
iunlock(f->ip);
return r;
}
return -1;
}
long
sys_write(void)
{
......
......@@ -12,3 +12,10 @@ typedef uptr paddr;
// Page Map Entry (refers to any entry in any level)
typedef u64 pme_t;
typedef pme_t pml4e_t;
#ifdef XV6
// POSIX types
typedef s64 ssize_t;
typedef u64 size_t;
typedef u64 off_t;
#endif
......@@ -26,6 +26,8 @@ int uptime(void);
int map(void *addr, int len);
int unmap(void *addr, int len);
void halt(void);
ssize_t pread(int, void*, size_t, off_t);
int kernlet(int, size_t, off_t);
}
// ulib.c
......
......@@ -36,3 +36,5 @@ SYSCALL(socket)
SYSCALL(bind)
SYSCALL(listen)
SYSCALL(accept)
SYSCALL(pread)
SYSCALL(kernlet)
......@@ -119,6 +119,14 @@ vmap_alloc(void)
kmfree(m);
return 0;
}
m->kshared = (char*)ksalloc(slab_kshared);
if (m->kshared == NULL || setupkshared(m->pml4, m->kshared)) {
cprintf("vmap_alloc: kshared out of memory\n");
freevm(m->pml4);
destroylock(&m->lock);
kmfree(m);
return 0;
}
#ifdef TREE
m->cr = crange_alloc(10);
if (m->cr == 0)
......@@ -332,6 +340,7 @@ vmap_free(void *p)
struct vmap *m = (struct vmap *) p;
crange_foreach(m->cr, vmap_free_vma, NULL);
crange_free(m->cr);
ksfree(slab_kshared, m->kshared);
freevm(m->pml4);
m->pml4 = 0;
m->alloc = 0;
......
......@@ -36,5 +36,6 @@ struct vmap {
u64 ref;
u64 alloc;
pml4e_t *pml4; // Page table
char *kshared;
char lockname[16];
};
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论