Skip to content

Commit 08a300d

Browse files
author
Geoffrey Challen
committed
Merge in 2.0.2.
1 parent cafa9f5 commit 08a300d

File tree

12 files changed

+2036
-714
lines changed

12 files changed

+2036
-714
lines changed

CHANGES

Lines changed: 1874 additions & 675 deletions
Large diffs are not rendered by default.

kern/arch/mips/vm/dumbvm.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,6 @@ free_kpages(vaddr_t addr)
126126
(void)addr;
127127
}
128128

129-
void
130-
vm_tlbshootdown_all(void)
131-
{
132-
panic("dumbvm tried to do tlb shootdown?!\n");
133-
}
134-
135129
void
136130
vm_tlbshootdown(const struct tlbshootdown *ts)
137131
{

kern/include/cpu.h

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -74,24 +74,21 @@ struct cpu {
7474
* Accessed by other cpus.
7575
* Protected by the IPI lock.
7676
*
77-
* If c_numshootdown is -1 (TLBSHOOTDOWN_ALL), all mappings
78-
* should be invalidated. This is used if more than
79-
* TLBSHOOTDOWN_MAX mappings are going to be invalidated at
80-
* once. TLBSHOOTDOWN_MAX is MD and chosen based on when it
81-
* becomes more efficient just to flush the whole TLB.
77+
* TLB shootdown requests made to this CPU are queued in
78+
* c_shootdown[], with c_numshootdown holding the number of
79+
* requests. TLBSHOOTDOWN_MAX is the maximum number that can
80+
* be queued at once, which is machine-dependent.
8281
*
83-
* struct tlbshootdown is machine-dependent and might
84-
* reasonably be either an address space and vaddr pair, or a
85-
* paddr, or something else.
82+
* The contents of struct tlbshootdown are also machine-
83+
* dependent and might reasonably be either an address space
84+
* and vaddr pair, or a paddr, or something else.
8685
*/
8786
uint32_t c_ipi_pending; /* One bit for each IPI number */
8887
struct tlbshootdown c_shootdown[TLBSHOOTDOWN_MAX];
89-
int c_numshootdown;
88+
unsigned c_numshootdown;
9089
struct spinlock c_ipi_lock;
9190
};
9291

93-
#define TLBSHOOTDOWN_ALL (-1)
94-
9592
/*
9693
* Initialization functions.
9794
*

kern/include/version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
* Leave this alone, so we can tell what version of the OS/161 base
3535
* code we gave you.
3636
*/
37-
#define BASE_VERSION "2.0.1"
37+
#define BASE_VERSION "2.0.2"
3838

3939
/*
4040
* Change this as you see fit in the course of hacking the system.

kern/include/vfs.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ int vfs_getcwd(struct uio *buf);
156156
* vfs_unmount - Unmount the filesystem presently mounted on the
157157
* specified device.
158158
*
159+
* vfs_swapon - Look up DEVNAME and mark it as a swap device,
160+
* returning a vnode. Similar to vfs_mount.
161+
*
162+
* vfs_swapoff - Unmark DEVNAME as a swap device. The vnode
163+
* previously returned by vfs_swapon should be
164+
* decref'd first. Similar to vfs_unmount.
165+
*
159166
* vfs_unmountall - Unmount all mounted filesystems.
160167
*/
161168

@@ -172,6 +179,8 @@ int vfs_mount(const char *devname, void *data,
172179
struct device *dev,
173180
struct fs **result));
174181
int vfs_unmount(const char *devname);
182+
int vfs_swapon(const char *devname, struct vnode **result);
183+
int vfs_swapoff(const char *devname);
175184
int vfs_unmountall(void);
176185

177186
/*

kern/include/vm.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ vaddr_t alloc_kpages(unsigned npages);
5656
void free_kpages(vaddr_t addr);
5757

5858
/* TLB shootdown handling called from interprocessor_interrupt */
59-
void vm_tlbshootdown_all(void);
6059
void vm_tlbshootdown(const struct tlbshootdown *);
6160

6261

kern/thread/thread.c

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ thread_make_runnable(struct thread *target, bool already_have_lock)
465465
target->t_state = S_READY;
466466
threadlist_addtail(&targetcpu->c_runqueue, target);
467467

468-
if (targetcpu->c_isidle) {
468+
if (targetcpu->c_isidle && targetcpu != curcpu->c_self) {
469469
/*
470470
* Other processor is idle; send interrupt to make
471471
* sure it unidles.
@@ -1106,6 +1106,9 @@ ipi_send(struct cpu *target, int code)
11061106
spinlock_release(&target->c_ipi_lock);
11071107
}
11081108

1109+
/*
1110+
* Send an IPI to all CPUs.
1111+
*/
11091112
void
11101113
ipi_broadcast(int code)
11111114
{
@@ -1120,16 +1123,28 @@ ipi_broadcast(int code)
11201123
}
11211124
}
11221125

1126+
/*
1127+
* Send a TLB shootdown IPI to the specified CPU.
1128+
*/
11231129
void
11241130
ipi_tlbshootdown(struct cpu *target, const struct tlbshootdown *mapping)
11251131
{
1126-
int n;
1132+
unsigned n;
11271133

11281134
spinlock_acquire(&target->c_ipi_lock);
11291135

11301136
n = target->c_numshootdown;
11311137
if (n == TLBSHOOTDOWN_MAX) {
1132-
target->c_numshootdown = TLBSHOOTDOWN_ALL;
1138+
/*
1139+
* If you have problems with this panic going off,
1140+
* consider: (1) increasing the maximum, (2) putting
1141+
* logic here to sleep until space appears (may
1142+
* interact awkwardly with VM system locking), (3)
1143+
* putting logic here to coalesce requests together,
1144+
* and/or (4) improving VM system state tracking to
1145+
* reduce the number of unnecessary shootdowns.
1146+
*/
1147+
panic("ipi_tlbshootdown: Too many shootdowns queued\n");
11331148
}
11341149
else {
11351150
target->c_shootdown[n] = *mapping;
@@ -1142,11 +1157,14 @@ ipi_tlbshootdown(struct cpu *target, const struct tlbshootdown *mapping)
11421157
spinlock_release(&target->c_ipi_lock);
11431158
}
11441159

1160+
/*
1161+
* Handle an incoming interprocessor interrupt.
1162+
*/
11451163
void
11461164
interprocessor_interrupt(void)
11471165
{
11481166
uint32_t bits;
1149-
int i;
1167+
unsigned i;
11501168

11511169
spinlock_acquire(&curcpu->c_ipi_lock);
11521170
bits = curcpu->c_ipi_pending;
@@ -1175,13 +1193,13 @@ interprocessor_interrupt(void)
11751193
*/
11761194
}
11771195
if (bits & (1U << IPI_TLBSHOOTDOWN)) {
1178-
if (curcpu->c_numshootdown == TLBSHOOTDOWN_ALL) {
1179-
vm_tlbshootdown_all();
1180-
}
1181-
else {
1182-
for (i=0; i<curcpu->c_numshootdown; i++) {
1183-
vm_tlbshootdown(&curcpu->c_shootdown[i]);
1184-
}
1196+
/*
1197+
* Note: depending on your VM system locking you might
1198+
* need to release the ipi lock while calling
1199+
* vm_tlbshootdown.
1200+
*/
1201+
for (i=0; i<curcpu->c_numshootdown; i++) {
1202+
vm_tlbshootdown(&curcpu->c_shootdown[i]);
11851203
}
11861204
curcpu->c_numshootdown = 0;
11871205
}

kern/vfs/vfslist.c

Lines changed: 103 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ struct knowndev {
8282
struct fs *kd_fs;
8383
};
8484

85+
/* A placeholder for kd_fs for devices used as swap */
86+
#define SWAP_FS ((struct fs *)-1)
87+
8588
DECLARRAY(knowndev, static __UNUSED inline);
8689
DEFARRAY(knowndev, static __UNUSED inline);
8790

@@ -160,7 +163,7 @@ vfs_sync(void)
160163
num = knowndevarray_num(knowndevs);
161164
for (i=0; i<num; i++) {
162165
dev = knowndevarray_get(knowndevs, i);
163-
if (dev->kd_fs != NULL) {
166+
if (dev->kd_fs != NULL && dev->kd_fs != SWAP_FS) {
164167
/*result =*/ FSOP_SYNC(dev->kd_fs);
165168
}
166169
}
@@ -195,7 +198,7 @@ vfs_getroot(const char *devname, struct vnode **ret)
195198
* and DEVNAME names the device, return ENXIO.
196199
*/
197200

198-
if (kd->kd_fs!=NULL) {
201+
if (kd->kd_fs != NULL && kd->kd_fs != SWAP_FS) {
199202
const char *volname;
200203
volname = FSOP_GETVOLNAME(kd->kd_fs);
201204

@@ -344,7 +347,7 @@ badnames(const char *n1, const char *n2, const char *n3)
344347
for (i=0; i<num; i++) {
345348
kd = knowndevarray_get(knowndevs, i);
346349

347-
if (kd->kd_fs) {
350+
if (kd->kd_fs != NULL && kd->kd_fs != SWAP_FS) {
348351
volname = FSOP_GETVOLNAME(kd->kd_fs);
349352
if (samestring3(volname, n1, n2, n3)) {
350353
return 1;
@@ -542,6 +545,7 @@ vfs_mount(const char *devname, void *data,
542545
}
543546

544547
KASSERT(fs != NULL);
548+
KASSERT(fs != SWAP_FS);
545549

546550
kd->kd_fs = fs;
547551

@@ -553,6 +557,59 @@ vfs_mount(const char *devname, void *data,
553557
return 0;
554558
}
555559

560+
/*
561+
* Like mount, but for attaching swap. Hands back the raw device
562+
* vnode. Unlike mount tolerates a trailing colon on the device name,
563+
* to avoid student-facing confusion.
564+
*/
565+
int
566+
vfs_swapon(const char *devname, struct vnode **ret)
567+
{
568+
char *myname = NULL;
569+
size_t len;
570+
struct knowndev *kd;
571+
int result;
572+
573+
len = strlen(devname);
574+
if (len > 0 && devname[len - 1] == ':') {
575+
/* tolerate trailing :, e.g. lhd0: rather than lhd0 */
576+
myname = kstrdup(devname);
577+
if (myname == NULL) {
578+
return ENOMEM;
579+
}
580+
myname[len - 1] = 0;
581+
devname = myname;
582+
}
583+
584+
vfs_biglock_acquire();
585+
586+
result = findmount(devname, &kd);
587+
if (result) {
588+
goto out;
589+
}
590+
591+
if (kd->kd_fs != NULL) {
592+
result = EBUSY;
593+
goto out;
594+
}
595+
KASSERT(kd->kd_rawname != NULL);
596+
KASSERT(kd->kd_device != NULL);
597+
598+
kprintf("vfs: Swap attached to %s\n", kd->kd_name);
599+
600+
kd->kd_fs = SWAP_FS;
601+
VOP_INCREF(kd->kd_vnode);
602+
*ret = kd->kd_vnode;
603+
604+
out:
605+
vfs_biglock_release();
606+
if (myname != NULL) {
607+
kfree(myname);
608+
}
609+
610+
return result;
611+
}
612+
556613
/*
557614
* Unmount a filesystem/device by name.
558615
* First calls FSOP_SYNC on the filesystem; then calls FSOP_UNMOUNT.
@@ -570,7 +627,7 @@ vfs_unmount(const char *devname)
570627
goto fail;
571628
}
572629

573-
if (kd->kd_fs == NULL) {
630+
if (kd->kd_fs == NULL || kd->kd_fs == SWAP_FS) {
574631
result = EINVAL;
575632
goto fail;
576633
}
@@ -600,6 +657,43 @@ vfs_unmount(const char *devname)
600657
return result;
601658
}
602659

660+
/*
661+
* Detach swap. Like unmount.
662+
*
663+
* (Provided for completeness; there is no real need to remove swap
664+
* explicitly prior to shutting down, except perhaps when swapping to
665+
* things that themselves want a clean shutdown, like RAIDs.)
666+
*/
667+
int
668+
vfs_swapoff(const char *devname)
669+
{
670+
struct knowndev *kd;
671+
int result;
672+
673+
vfs_biglock_acquire();
674+
675+
result = findmount(devname, &kd);
676+
if (result) {
677+
goto fail;
678+
}
679+
680+
if (kd->kd_fs != SWAP_FS) {
681+
result = EINVAL;
682+
goto fail;
683+
}
684+
685+
kprintf("vfs: Swap detached from %s:\n", kd->kd_name);
686+
687+
/* drop it */
688+
kd->kd_fs = NULL;
689+
690+
KASSERT(result==0);
691+
692+
fail:
693+
vfs_biglock_release();
694+
return result;
695+
}
696+
603697
/*
604698
* Global unmount function.
605699
*/
@@ -623,6 +717,11 @@ vfs_unmountall(void)
623717
/* not mounted */
624718
continue;
625719
}
720+
if (dev->kd_fs == SWAP_FS) {
721+
/* just drop it */
722+
dev->kd_fs = NULL;
723+
continue;
724+
}
626725

627726
kprintf("vfs: Unmounting %s:\n", dev->kd_name);
628727

kern/vfs/vnode.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,8 @@ vnode_decref(struct vnode *vn)
129129
void
130130
vnode_check(struct vnode *v, const char *opstr)
131131
{
132-
vfs_biglock_acquire();
132+
/* not safe, and not really needed to check constant fields */
133+
/*vfs_biglock_acquire();*/
133134

134135
if (v == NULL) {
135136
panic("vnode_check: vop_%s: null vnode\n", opstr);
@@ -173,5 +174,5 @@ vnode_check(struct vnode *v, const char *opstr)
173174
}
174175

175176
spinlock_release(&v->vn_countlock);
176-
vfs_biglock_release();
177+
/*vfs_biglock_release();*/
177178
}

mk/os161.config.mk

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@
9696
# the build. Default is $(WORKDIR)/tooldir.
9797
#
9898
# INSTALLTOP Staging directory for installation.
99-
# Default is $(WORKDIR)/install
99+
# Default is $(WORKDIR)/install.
100100
#
101101
# Probably the only reason to change these would be if you're short on
102102
# diskspace in $(WORKDIR).

0 commit comments

Comments
 (0)