提交 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 ...@@ -23,7 +23,7 @@ OBJCOPY = $(TOOLPREFIX)objcopy
COMFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall \ COMFLAGS := -fno-pic -static -fno-builtin -fno-strict-aliasing -O2 -Wall \
-MD -ggdb -m64 -Werror -fms-extensions -mno-sse \ -MD -ggdb -m64 -Werror -fms-extensions -mno-sse \
-mcmodel=large -mno-red-zone -I$(QEMUSRC) -fno-omit-frame-pointer \ -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) COMFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
CFLAGS := $(COMFLAGS) -std=c99 CFLAGS := $(COMFLAGS) -std=c99
CXXFLAGS := $(COMFLAGS) -std=c++0x -Wno-sign-compare -fno-exceptions -fno-rtti CXXFLAGS := $(COMFLAGS) -std=c++0x -Wno-sign-compare -fno-exceptions -fno-rtti
...@@ -48,6 +48,7 @@ OBJS = \ ...@@ -48,6 +48,7 @@ OBJS = \
hwvm.o \ hwvm.o \
hz.o \ hz.o \
kalloc.o \ kalloc.o \
kernlet.o \
kmalloc.o \ kmalloc.o \
kbd.o \ kbd.o \
main.o \ main.o \
...@@ -98,7 +99,8 @@ UPROGS= \ ...@@ -98,7 +99,8 @@ UPROGS= \
_sleep \ _sleep \
_dirbench \ _dirbench \
_usertests \ _usertests \
_lockstat _lockstat \
_preadtest
UPROGS := $(addprefix $(O)/, $(UPROGS)) UPROGS := $(addprefix $(O)/, $(UPROGS))
all: $(O)/kernel all: $(O)/kernel
......
...@@ -122,6 +122,18 @@ setupkvm(void) ...@@ -122,6 +122,18 @@ setupkvm(void)
return pml4; 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, // Switch h/w page table register to the kernel-only page table,
// for when no process is running. // for when no process is running.
void void
......
struct ipcctl {
volatile char done;
volatile long result;
};
...@@ -28,6 +28,11 @@ static struct kmem slabmem[][NCPU] = { ...@@ -28,6 +28,11 @@ static struct kmem slabmem[][NCPU] = {
.size = PERFSIZE, .size = PERFSIZE,
.ninit = 1, .ninit = 1,
}, },
[slab_kshared][0 ... NCPU-1] = {
.name = " kshared",
.size = KSHAREDSIZE,
.ninit = CPUKSTACKS,
},
}; };
extern char end[]; // first address after kernel loaded from ELF file extern char end[]; // first address after kernel loaded from ELF file
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
#include "lib.h" #include "lib.h"
#define KBASE 0xFFFFFF0000000000ull #define KBASE 0xFFFFFF0000000000ull
#define KSHARED 0xFFFFF00000000000ull
#define USERTOP 0x0000800000000000ull #define USERTOP 0x0000800000000000ull
#define KCSEG (2<<3) /* kernel code segment */ #define KCSEG (2<<3) /* kernel code segment */
...@@ -128,6 +129,7 @@ void gc_start(void); ...@@ -128,6 +129,7 @@ void gc_start(void);
// hwvm.c // hwvm.c
void freevm(pml4e_t*); void freevm(pml4e_t*);
pml4e_t* setupkvm(void); pml4e_t* setupkvm(void);
int setupkshared(pml4e_t *pml4, char *kshared);
pme_t * walkpgdir(pml4e_t*, const void*, int); pme_t * walkpgdir(pml4e_t*, const void*, int);
// hz.c // hz.c
...@@ -147,6 +149,7 @@ void ioapicenable(int irq, int cpu); ...@@ -147,6 +149,7 @@ void ioapicenable(int irq, int cpu);
typedef enum { typedef enum {
slab_stack, slab_stack,
slab_perf, slab_perf,
slab_kshared,
} slab_t; } slab_t;
char* kalloc(void); char* kalloc(void);
void kfree(void*); void kfree(void*);
...@@ -410,6 +413,8 @@ long sys_socket(int, int, int); ...@@ -410,6 +413,8 @@ long sys_socket(int, int, int);
long sys_bind(int, void*, int); long sys_bind(int, void*, int);
long sys_listen(int, int); long sys_listen(int, int);
long sys_accept(int, void*, void*); 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 // other exported/imported functions
void cmain(u64 mbmagic, u64 mbaddr); 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 ...@@ -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 \ 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) \ -m64 -Werror -std=c99 -fms-extensions -mno-sse -mcmodel=large -I$(QEMUSRC) \
-fno-omit-frame-pointer -DHW_$(HW) -include param.h -include compiler.h \ -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 -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) LWIP_CFLAGS += $(shell $(CC) -fno-stack-protector -E -x c /dev/null >/dev/null 2>&1 && echo -fno-stack-protector)
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#define LOCKSTAT 0 #define LOCKSTAT 0
#define VERIFYFREE LOCKSTAT #define VERIFYFREE LOCKSTAT
#define ALLOC_MEMSET 1 #define ALLOC_MEMSET 1
#define KSHAREDSIZE (32 << 10)
#define WQSHIFT 4 #define WQSHIFT 4
#if defined(HW_josmp) #if defined(HW_josmp)
#define NCPU 16 // maximum number of CPUs #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) ...@@ -219,6 +219,7 @@ allocproc(void)
freeproc(p); freeproc(p);
return 0; return 0;
} }
sp = p->kstack + KSTACKSIZE; sp = p->kstack + KSTACKSIZE;
// Leave room for trap frame. // Leave room for trap frame.
......
...@@ -177,6 +177,8 @@ static long (*syscalls[])(u64, u64, u64, u64, u64, u64) = { ...@@ -177,6 +177,8 @@ static long (*syscalls[])(u64, u64, u64, u64, u64, u64) = {
SYSCALL(bind), SYSCALL(bind),
SYSCALL(listen), SYSCALL(listen),
SYSCALL(accept), SYSCALL(accept),
SYSCALL(pread),
SYSCALL(kernlet),
}; };
void void
......
...@@ -27,3 +27,5 @@ ...@@ -27,3 +27,5 @@
#define SYS_bind 26 #define SYS_bind 26
#define SYS_listen 27 #define SYS_listen 27
#define SYS_accept 28 #define SYS_accept 28
#define SYS_pread 29
#define SYS_kernlet 30
...@@ -75,6 +75,27 @@ sys_read(void) ...@@ -75,6 +75,27 @@ sys_read(void)
return fileread(f, p, n); 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 long
sys_write(void) sys_write(void)
{ {
......
...@@ -12,3 +12,10 @@ typedef uptr paddr; ...@@ -12,3 +12,10 @@ typedef uptr paddr;
// Page Map Entry (refers to any entry in any level) // Page Map Entry (refers to any entry in any level)
typedef u64 pme_t; typedef u64 pme_t;
typedef pme_t pml4e_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); ...@@ -26,6 +26,8 @@ int uptime(void);
int map(void *addr, int len); int map(void *addr, int len);
int unmap(void *addr, int len); int unmap(void *addr, int len);
void halt(void); void halt(void);
ssize_t pread(int, void*, size_t, off_t);
int kernlet(int, size_t, off_t);
} }
// ulib.c // ulib.c
......
...@@ -36,3 +36,5 @@ SYSCALL(socket) ...@@ -36,3 +36,5 @@ SYSCALL(socket)
SYSCALL(bind) SYSCALL(bind)
SYSCALL(listen) SYSCALL(listen)
SYSCALL(accept) SYSCALL(accept)
SYSCALL(pread)
SYSCALL(kernlet)
...@@ -119,6 +119,14 @@ vmap_alloc(void) ...@@ -119,6 +119,14 @@ vmap_alloc(void)
kmfree(m); kmfree(m);
return 0; 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 #ifdef TREE
m->cr = crange_alloc(10); m->cr = crange_alloc(10);
if (m->cr == 0) if (m->cr == 0)
...@@ -332,6 +340,7 @@ vmap_free(void *p) ...@@ -332,6 +340,7 @@ vmap_free(void *p)
struct vmap *m = (struct vmap *) p; struct vmap *m = (struct vmap *) p;
crange_foreach(m->cr, vmap_free_vma, NULL); crange_foreach(m->cr, vmap_free_vma, NULL);
crange_free(m->cr); crange_free(m->cr);
ksfree(slab_kshared, m->kshared);
freevm(m->pml4); freevm(m->pml4);
m->pml4 = 0; m->pml4 = 0;
m->alloc = 0; m->alloc = 0;
......
...@@ -36,5 +36,6 @@ struct vmap { ...@@ -36,5 +36,6 @@ struct vmap {
u64 ref; u64 ref;
u64 alloc; u64 alloc;
pml4e_t *pml4; // Page table pml4e_t *pml4; // Page table
char *kshared;
char lockname[16]; char lockname[16];
}; };
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论