Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
X
xv6-public
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
问题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
银宸时代
OS Lab Group
奖励实验
xv6-public
提交
3e6c70a4
提交
3e6c70a4
3月 02, 2012
创建
作者:
Nickolai Zeldovich
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
initial radix tree and VM
上级
7eea37c9
隐藏空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
135 行增加
和
11 行删除
+135
-11
markptr.hh
include/markptr.hh
+17
-1
vm.hh
include/vm.hh
+19
-1
Makefrag
kernel/Makefrag
+1
-0
kmalloc.cc
kernel/kmalloc.cc
+1
-0
proc.cc
kernel/proc.cc
+14
-1
vm.cc
kernel/vm.cc
+83
-8
没有找到文件。
include/markptr.hh
浏览文件 @
3e6c70a4
...
@@ -42,7 +42,7 @@ class markptr {
...
@@ -42,7 +42,7 @@ class markptr {
template
<
class
T
>
template
<
class
T
>
class
markptr_ptr
:
private
markptr
<
T
>
{
class
markptr_ptr
:
private
markptr
<
T
>
{
public
:
public
:
void
operator
=
(
T
*
p
)
{
void
operator
=
(
T
*
p
)
{
uptr
p0
,
p1
;
uptr
p0
,
p1
;
do
{
do
{
p0
=
markptr
<
T
>::
_p
.
load
();
p0
=
markptr
<
T
>::
_p
.
load
();
...
@@ -50,6 +50,22 @@ class markptr_ptr : private markptr<T> {
...
@@ -50,6 +50,22 @@ class markptr_ptr : private markptr<T> {
}
while
(
!
markptr
<
T
>::
_p
.
compare_exchange_weak
(
p0
,
p1
));
}
while
(
!
markptr
<
T
>::
_p
.
compare_exchange_weak
(
p0
,
p1
));
}
}
bool
cmpxch_update
(
T
**
expected
,
T
*
desired
)
{
uptr
p0
,
p1
;
do
{
p0
=
markptr
<
T
>::
_p
.
load
();
p1
=
(
p0
&
1
)
|
(
uptr
)
desired
;
T
*
cur
=
(
T
*
)
(
p0
&
~
1
);
if
(
cur
!=
*
expected
)
{
*
expected
=
cur
;
return
false
;
}
}
while
(
!
markptr
<
T
>::
_p
.
compare_exchange_weak
(
p0
,
p1
));
return
true
;
}
T
*
load
()
const
{
T
*
load
()
const
{
return
(
T
*
)
(
markptr
<
T
>::
_p
.
load
()
&
~
1
);
return
(
T
*
)
(
markptr
<
T
>::
_p
.
load
()
&
~
1
);
}
}
...
...
include/vm.hh
浏览文件 @
3e6c70a4
...
@@ -2,9 +2,13 @@
...
@@ -2,9 +2,13 @@
#include "atomic.hh"
#include "atomic.hh"
#include "crange_arch.hh"
#include "crange_arch.hh"
#include "crange.hh"
#include "crange.hh"
#include "radix.hh"
#include "cpputil.hh"
#include "cpputil.hh"
#include "hwvm.hh"
#include "hwvm.hh"
#define VM_CRANGE 0
#define VM_RADIX 1
using
std
::
atomic
;
using
std
::
atomic
;
// A memory object (physical pages or inode).
// A memory object (physical pages or inode).
...
@@ -34,7 +38,14 @@ struct vmnode {
...
@@ -34,7 +38,14 @@ struct vmnode {
// a specific memory object.
// a specific memory object.
enum
vmatype
{
PRIVATE
,
COW
};
enum
vmatype
{
PRIVATE
,
COW
};
struct
vma
:
public
range
{
struct
vma
#if VM_CRANGE
:
public
range
#endif
#if VM_RADIX
:
public
radix_elem
#endif
{
const
uptr
vma_start
;
// start of mapping
const
uptr
vma_start
;
// start of mapping
const
uptr
vma_end
;
// one past the last byte
const
uptr
vma_end
;
// one past the last byte
const
enum
vmatype
va_type
;
const
enum
vmatype
va_type
;
...
@@ -50,7 +61,14 @@ struct vma : public range {
...
@@ -50,7 +61,14 @@ struct vma : public range {
// An address space: a set of vmas plus h/w page table.
// An address space: a set of vmas plus h/w page table.
// The elements of e[] are not ordered by address.
// The elements of e[] are not ordered by address.
struct
vmap
{
struct
vmap
{
#if VM_CRANGE
struct
crange
cr
;
struct
crange
cr
;
#endif
#if VM_RADIX
struct
radix
rx
;
#endif
atomic
<
u64
>
ref
;
atomic
<
u64
>
ref
;
pgmap
*
const
pml4
;
// Page table
pgmap
*
const
pml4
;
// Page table
char
*
const
kshared
;
char
*
const
kshared
;
...
...
kernel/Makefrag
浏览文件 @
3e6c70a4
...
@@ -30,6 +30,7 @@ OBJS = \
...
@@ -30,6 +30,7 @@ OBJS = \
pipe.o \
pipe.o \
proc.o \
proc.o \
gc.o \
gc.o \
radix.o \
rnd.o \
rnd.o \
sampler.o \
sampler.o \
sched.o \
sched.o \
...
...
kernel/kmalloc.cc
浏览文件 @
3e6c70a4
...
@@ -68,6 +68,7 @@ bucket(u64 nbytes)
...
@@ -68,6 +68,7 @@ bucket(u64 nbytes)
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
11
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
12
,
};
};
assert
(
nbytes
<=
PGSIZE
);
assert
(
nbytes
<=
PGSIZE
);
...
...
kernel/proc.cc
浏览文件 @
3e6c70a4
...
@@ -298,9 +298,14 @@ growproc(int n)
...
@@ -298,9 +298,14 @@ growproc(int n)
// sbrk() would start to use the next region (e.g. the stack).
// sbrk() would start to use the next region (e.g. the stack).
uptr
newstart
=
PGROUNDUP
(
curbrk
);
uptr
newstart
=
PGROUNDUP
(
curbrk
);
s64
newn
=
PGROUNDUP
(
n
+
curbrk
-
newstart
);
s64
newn
=
PGROUNDUP
(
n
+
curbrk
-
newstart
);
#if VM_CRANGE
range
*
prev
=
0
;
range
*
prev
=
0
;
auto
span
=
m
->
cr
.
search_lock
(
newstart
,
newn
+
PGSIZE
);
auto
span
=
m
->
cr
.
search_lock
(
newstart
,
newn
+
PGSIZE
);
for
(
range
*
r
:
span
)
{
#endif
#if VM_RADIX
auto
span
=
m
->
rx
.
search_lock
(
newstart
,
newn
+
PGSIZE
);
#endif
for
(
auto
r
:
span
)
{
vma
*
e
=
(
vma
*
)
r
;
vma
*
e
=
(
vma
*
)
r
;
if
(
e
->
vma_start
<=
newstart
)
{
if
(
e
->
vma_start
<=
newstart
)
{
...
@@ -311,7 +316,9 @@ growproc(int n)
...
@@ -311,7 +316,9 @@ growproc(int n)
newn
-=
e
->
vma_end
-
newstart
;
newn
-=
e
->
vma_end
-
newstart
;
newstart
=
e
->
vma_end
;
newstart
=
e
->
vma_end
;
#if VM_CRANGE
prev
=
e
;
prev
=
e
;
#endif
}
else
{
}
else
{
cprintf
(
"growproc: overlap with existing mapping; brk %lx n %d
\n
"
,
cprintf
(
"growproc: overlap with existing mapping; brk %lx n %d
\n
"
,
curbrk
,
n
);
curbrk
,
n
);
...
@@ -332,7 +339,13 @@ growproc(int n)
...
@@ -332,7 +339,13 @@ growproc(int n)
return
-
1
;
return
-
1
;
}
}
#if VM_CRANGE
span
.
replace
(
prev
,
repl
);
span
.
replace
(
prev
,
repl
);
#endif
#if VM_RADIX
span
.
replace
(
newstart
,
newn
,
repl
);
#endif
myproc
()
->
brk
+=
n
;
myproc
()
->
brk
+=
n
;
return
0
;
return
0
;
...
...
kernel/vm.cc
浏览文件 @
3e6c70a4
...
@@ -118,8 +118,10 @@ vmnode::demand_load()
...
@@ -118,8 +118,10 @@ vmnode::demand_load()
* vma
* vma
*/
*/
vma
::
vma
(
vmap
*
vmap
,
uptr
start
,
uptr
end
,
enum
vmatype
vtype
,
vmnode
*
vmn
)
vma
::
vma
(
vmap
*
vmap
,
uptr
start
,
uptr
end
,
enum
vmatype
vtype
,
vmnode
*
vmn
)
:
:
range
(
&
vmap
->
cr
,
start
,
end
-
start
),
#if VM_CRANGE
range
(
&
vmap
->
cr
,
start
,
end
-
start
),
#endif
vma_start
(
start
),
vma_end
(
end
),
va_type
(
vtype
),
n
(
vmn
)
vma_start
(
start
),
vma_end
(
end
),
va_type
(
vtype
),
n
(
vmn
)
{
{
if
(
n
)
if
(
n
)
...
@@ -136,8 +138,14 @@ vma::~vma()
...
@@ -136,8 +138,14 @@ vma::~vma()
* vmap
* vmap
*/
*/
vmap
::
vmap
()
vmap
::
vmap
()
:
:
cr
(
10
),
ref
(
1
),
pml4
(
setupkvm
()),
kshared
((
char
*
)
ksalloc
(
slab_kshared
))
#if VM_CRANGE
cr
(
10
),
#endif
#if VM_RADIX
rx
(
PGSHIFT
),
#endif
ref
(
1
),
pml4
(
setupkvm
()),
kshared
((
char
*
)
ksalloc
(
slab_kshared
))
{
{
if
(
pml4
==
0
)
{
if
(
pml4
==
0
)
{
cprintf
(
"vmap_alloc: setupkvm out of memory
\n
"
);
cprintf
(
"vmap_alloc: setupkvm out of memory
\n
"
);
...
@@ -181,12 +189,24 @@ vmap::decref()
...
@@ -181,12 +189,24 @@ vmap::decref()
bool
bool
vmap
::
replace_vma
(
vma
*
a
,
vma
*
b
)
vmap
::
replace_vma
(
vma
*
a
,
vma
*
b
)
{
{
#if VM_CRANGE
auto
span
=
cr
.
search_lock
(
a
->
vma_start
,
a
->
vma_end
-
a
->
vma_start
);
auto
span
=
cr
.
search_lock
(
a
->
vma_start
,
a
->
vma_end
-
a
->
vma_start
);
#endif
#if VM_RADIX
auto
span
=
rx
.
search_lock
(
a
->
vma_start
,
a
->
vma_end
-
a
->
vma_start
);
#endif
if
(
a
->
deleted
())
if
(
a
->
deleted
())
return
false
;
return
false
;
for
(
auto
e
:
span
)
for
(
auto
e
:
span
)
assert
(
a
==
e
);
assert
(
a
==
e
);
#if VM_CRANGE
span
.
replace
(
b
);
span
.
replace
(
b
);
#endif
#if VM_RADIX
span
.
replace
(
a
->
vma_start
,
b
->
vma_start
-
a
->
vma_start
,
0
);
span
.
replace
(
b
->
vma_start
,
b
->
vma_end
-
b
->
vma_start
,
b
);
span
.
replace
(
b
->
vma_end
,
a
->
vma_end
-
b
->
vma_end
,
0
);
#endif
return
true
;
return
true
;
}
}
...
@@ -197,7 +217,14 @@ vmap::copy(int share)
...
@@ -197,7 +217,14 @@ vmap::copy(int share)
if
(
nm
==
0
)
if
(
nm
==
0
)
return
0
;
return
0
;
for
(
range
*
r
:
cr
)
{
#if VM_CRANGE
for
(
auto
r
:
cr
)
{
#endif
#if VM_RADIX
for
(
auto
r
:
rx
)
{
if
(
!
r
)
continue
;
#endif
vma
*
e
=
(
vma
*
)
r
;
vma
*
e
=
(
vma
*
)
r
;
struct
vma
*
ne
;
struct
vma
*
ne
;
...
@@ -231,10 +258,27 @@ vmap::copy(int share)
...
@@ -231,10 +258,27 @@ vmap::copy(int share)
goto
err
;
goto
err
;
}
}
#if VM_CRANGE
auto
span
=
nm
->
cr
.
search_lock
(
ne
->
vma_start
,
ne
->
vma_end
-
ne
->
vma_start
);
auto
span
=
nm
->
cr
.
search_lock
(
ne
->
vma_start
,
ne
->
vma_end
-
ne
->
vma_start
);
for
(
auto
x
__attribute__
((
unused
))
:
span
)
#endif
#if VM_RADIX
auto
span
=
nm
->
rx
.
search_lock
(
ne
->
vma_start
,
ne
->
vma_end
-
ne
->
vma_start
);
#endif
for
(
auto
x
__attribute__
((
unused
))
:
span
)
{
#if VM_RADIX
if
(
!
x
)
continue
;
#endif
cprintf
(
"non-empty span: %p (orig 0x%lx--0x%lx)
\n
"
,
x
,
ne
->
vma_start
,
ne
->
vma_end
);
assert
(
0
);
/* span must be empty */
assert
(
0
);
/* span must be empty */
}
#if VM_CRANGE
span
.
replace
(
ne
);
span
.
replace
(
ne
);
#endif
#if VM_RADIX
span
.
replace
(
ne
->
vma_start
,
ne
->
vma_end
-
ne
->
vma_start
,
ne
);
#endif
}
}
if
(
share
)
if
(
share
)
...
@@ -259,7 +303,13 @@ vmap::lookup(uptr start, uptr len)
...
@@ -259,7 +303,13 @@ vmap::lookup(uptr start, uptr len)
if
(
start
+
len
<
start
)
if
(
start
+
len
<
start
)
panic
(
"vmap::lookup bad len"
);
panic
(
"vmap::lookup bad len"
);
range
*
r
=
cr
.
search
(
start
,
len
);
#if VM_CRANGE
auto
r
=
cr
.
search
(
start
,
len
);
#endif
#if VM_RADIX
assert
(
len
<=
PGSIZE
);
auto
r
=
rx
.
search
(
start
);
#endif
if
(
r
!=
0
)
{
if
(
r
!=
0
)
{
vma
*
e
=
(
vma
*
)
r
;
vma
*
e
=
(
vma
*
)
r
;
if
(
e
->
vma_end
<=
e
->
vma_start
)
if
(
e
->
vma_end
<=
e
->
vma_start
)
...
@@ -282,10 +332,20 @@ vmap::insert(vmnode *n, uptr vma_start, int dotlb)
...
@@ -282,10 +332,20 @@ vmap::insert(vmnode *n, uptr vma_start, int dotlb)
{
{
// new scope to release the search lock before tlbflush
// new scope to release the search lock before tlbflush
u64
len
=
n
->
npages
*
PGSIZE
;
u64
len
=
n
->
npages
*
PGSIZE
;
#if VM_CRANGE
auto
span
=
cr
.
search_lock
(
vma_start
,
len
);
auto
span
=
cr
.
search_lock
(
vma_start
,
len
);
#endif
#if VM_RADIX
auto
span
=
rx
.
search_lock
(
vma_start
,
len
);
#endif
for
(
auto
r
:
span
)
{
for
(
auto
r
:
span
)
{
#if VM_RADIX
if
(
!
r
)
continue
;
#endif
vma
*
rvma
=
(
vma
*
)
r
;
vma
*
rvma
=
(
vma
*
)
r
;
cprintf
(
"vmap::insert: overlap with 0x%lx--0x%lx
\n
"
,
rvma
->
vma_start
,
rvma
->
vma_end
);
cprintf
(
"vmap::insert: overlap with %p: 0x%lx--0x%lx
\n
"
,
rvma
,
rvma
->
vma_start
,
rvma
->
vma_end
);
return
-
1
;
return
-
1
;
}
}
...
@@ -297,7 +357,12 @@ vmap::insert(vmnode *n, uptr vma_start, int dotlb)
...
@@ -297,7 +357,12 @@ vmap::insert(vmnode *n, uptr vma_start, int dotlb)
return
-
1
;
return
-
1
;
}
}
#if VM_CRANGE
span
.
replace
(
e
);
span
.
replace
(
e
);
#endif
#if VM_RADIX
span
.
replace
(
e
->
vma_start
,
e
->
vma_end
-
e
->
vma_start
,
e
);
#endif
}
}
bool
needtlb
=
false
;
bool
needtlb
=
false
;
...
@@ -327,7 +392,12 @@ vmap::remove(uptr vma_start, uptr len)
...
@@ -327,7 +392,12 @@ vmap::remove(uptr vma_start, uptr len)
// new scope to release the search lock before tlbflush
// new scope to release the search lock before tlbflush
uptr
vma_end
=
vma_start
+
len
;
uptr
vma_end
=
vma_start
+
len
;
#if VM_CRANGE
auto
span
=
cr
.
search_lock
(
vma_start
,
len
);
auto
span
=
cr
.
search_lock
(
vma_start
,
len
);
#endif
#if VM_RADIX
auto
span
=
rx
.
search_lock
(
vma_start
,
len
);
#endif
for
(
auto
r
:
span
)
{
for
(
auto
r
:
span
)
{
vma
*
rvma
=
(
vma
*
)
r
;
vma
*
rvma
=
(
vma
*
)
r
;
if
(
rvma
->
vma_start
<
vma_start
||
rvma
->
vma_end
>
vma_end
)
{
if
(
rvma
->
vma_start
<
vma_start
||
rvma
->
vma_end
>
vma_end
)
{
...
@@ -338,7 +408,12 @@ vmap::remove(uptr vma_start, uptr len)
...
@@ -338,7 +408,12 @@ vmap::remove(uptr vma_start, uptr len)
// XXX handle partial unmap
// XXX handle partial unmap
#if VM_CRANGE
span
.
replace
(
0
);
span
.
replace
(
0
);
#endif
#if VM_RADIX
span
.
replace
(
vma_start
,
len
,
0
);
#endif
}
}
bool
needtlb
=
false
;
bool
needtlb
=
false
;
...
...
编写
预览
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论