From 530431045237d7ccbbc0bb65ed83309845c19893 Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Mon, 29 Jul 2019 17:33:16 -0400 Subject: Remove B_DIRTY Use refcnt to pin blocks into the cache Replace flags/B_VALID with a boolean field valid Use info[id].status to signal completion of disk interrupt Pass a read/write flag to virtio_disk_rw --- kernel/virtio_disk.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) (limited to 'kernel/virtio_disk.c') diff --git a/kernel/virtio_disk.c b/kernel/virtio_disk.c index 3ace5ef..df4473d 100644 --- a/kernel/virtio_disk.c +++ b/kernel/virtio_disk.c @@ -164,7 +164,7 @@ alloc3_desc(int *idx) } void -virtio_disk_rw(struct buf *b) +virtio_disk_rw(struct buf *b, int write) { uint64 sector = b->blockno * (BSIZE / 512); @@ -192,7 +192,7 @@ virtio_disk_rw(struct buf *b) uint64 sector; } buf0; - if(b->flags & B_DIRTY) + if(write) buf0.type = VIRTIO_BLK_T_OUT; // write the disk else buf0.type = VIRTIO_BLK_T_IN; // read the disk @@ -208,7 +208,7 @@ virtio_disk_rw(struct buf *b) desc[idx[1]].addr = (uint64) b->data; desc[idx[1]].len = BSIZE; - if(b->flags & B_DIRTY) + if(write) desc[idx[1]].flags = 0; // device reads b->data else desc[idx[1]].flags = VRING_DESC_F_WRITE; // device writes b->data @@ -235,7 +235,7 @@ virtio_disk_rw(struct buf *b) *R(VIRTIO_MMIO_QUEUE_NOTIFY) = 0; // value is queue number // Wait for virtio_disk_intr() to say request has finished. - while((b->flags & (B_VALID|B_DIRTY)) != B_VALID){ + while(info[idx[0]].status == 0) { sleep(b, &vdisk_lock); } @@ -253,9 +253,7 @@ virtio_disk_intr() if(info[id].status != 0) panic("virtio_disk_intr status"); - info[id].b->flags |= B_VALID; - info[id].b->flags &= ~B_DIRTY; - + info[id].status = 1; wakeup(info[id].b); info[id].b = 0; -- cgit v1.2.3 From f1bb53c690051994f5a2c43ee900f9e335bd019c Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Tue, 30 Jul 2019 08:13:03 -0400 Subject: The driver should free descriptors, not interrupt handler. This avoids handler freeing descriptors before driver sees that the request has completed. --- kernel/virtio_disk.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'kernel/virtio_disk.c') diff --git a/kernel/virtio_disk.c b/kernel/virtio_disk.c index df4473d..9ebe695 100644 --- a/kernel/virtio_disk.c +++ b/kernel/virtio_disk.c @@ -239,6 +239,9 @@ virtio_disk_rw(struct buf *b, int write) sleep(b, &vdisk_lock); } + info[idx[0]].b = 0; + free_chain(idx[0]); + release(&vdisk_lock); } @@ -256,9 +259,6 @@ virtio_disk_intr() info[id].status = 1; wakeup(info[id].b); - info[id].b = 0; - free_chain(id); - used_idx = (used_idx + 1) % NUM; } -- cgit v1.2.3 From 848d1906e81992c78bee9e9ce5a5d38e107265cc Mon Sep 17 00:00:00 2001 From: Frans Kaashoek Date: Tue, 30 Jul 2019 12:53:19 -0400 Subject: Track in buf if disk "owns" buffer --- kernel/virtio_disk.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'kernel/virtio_disk.c') diff --git a/kernel/virtio_disk.c b/kernel/virtio_disk.c index 9ebe695..14c718d 100644 --- a/kernel/virtio_disk.c +++ b/kernel/virtio_disk.c @@ -222,6 +222,7 @@ virtio_disk_rw(struct buf *b, int write) desc[idx[2]].next = 0; // record struct buf for virtio_disk_intr(). + b->disk = 1; info[idx[0]].b = b; // avail[0] is flags @@ -235,7 +236,7 @@ virtio_disk_rw(struct buf *b, int write) *R(VIRTIO_MMIO_QUEUE_NOTIFY) = 0; // value is queue number // Wait for virtio_disk_intr() to say request has finished. - while(info[idx[0]].status == 0) { + while(b->disk == 1) { sleep(b, &vdisk_lock); } @@ -255,8 +256,8 @@ virtio_disk_intr() if(info[id].status != 0) panic("virtio_disk_intr status"); - - info[id].status = 1; + + info[id].b->disk = 0; // disk is done with buf wakeup(info[id].b); used_idx = (used_idx + 1) % NUM; -- cgit v1.2.3