Introduce alloc3_desc and UsedArea to make code easier to read

This commit is contained in:
Frans Kaashoek 2019-07-01 08:20:35 -04:00
parent a8305b7318
commit af6c35e14b
3 changed files with 40 additions and 33 deletions

2
.gitignore vendored
View file

@ -12,4 +12,6 @@ initcode
initcode.out initcode.out
kernelmemfs kernelmemfs
mkfs mkfs
kernel/kernel
user/usys.S
.gdbinit .gdbinit

View file

@ -43,6 +43,10 @@
#define VIRTIO_RING_F_INDIRECT_DESC 28 #define VIRTIO_RING_F_INDIRECT_DESC 28
#define VIRTIO_RING_F_EVENT_IDX 29 #define VIRTIO_RING_F_EVENT_IDX 29
// this many virtio descriptors.
// must be a power of two.
#define NUM 8
struct VRingDesc { struct VRingDesc {
uint64 addr; uint64 addr;
uint32 len; uint32 len;
@ -60,3 +64,9 @@ struct VRingUsedElem {
// for disk ops // for disk ops
#define VIRTIO_BLK_T_IN 0 // read the disk #define VIRTIO_BLK_T_IN 0 // read the disk
#define VIRTIO_BLK_T_OUT 1 // write the disk #define VIRTIO_BLK_T_OUT 1 // write the disk
struct UsedArea {
uint16 flags;
uint16 id;
struct VRingUsedElem elems[NUM];
};

View file

@ -22,10 +22,6 @@
struct spinlock virtio_disk_lock; struct spinlock virtio_disk_lock;
// this many virtio descriptors.
// must be a power of two.
#define NUM 8
// memory for virtio descriptors &c for queue 0. // memory for virtio descriptors &c for queue 0.
// this is a global instead of allocated because it has // this is a global instead of allocated because it has
// to be multiple contiguous pages, which kalloc() // to be multiple contiguous pages, which kalloc()
@ -34,7 +30,7 @@ __attribute__ ((aligned (PGSIZE)))
static char pages[2*PGSIZE]; static char pages[2*PGSIZE];
static struct VRingDesc *desc; static struct VRingDesc *desc;
static uint16 *avail; static uint16 *avail;
static char *used; static struct UsedArea *used;
// our own book-keeping. // our own book-keeping.
static char free[NUM]; // is a descriptor free? static char free[NUM]; // is a descriptor free?
@ -106,7 +102,7 @@ virtio_disk_init(void)
desc = (struct VRingDesc *) pages; desc = (struct VRingDesc *) pages;
avail = (uint16*)(((char*)desc) + NUM*sizeof(struct VRingDesc)); avail = (uint16*)(((char*)desc) + NUM*sizeof(struct VRingDesc));
used = pages + PGSIZE; used = (struct UsedArea *) (pages + PGSIZE);
for(int i = 0; i < NUM; i++) for(int i = 0; i < NUM; i++)
free[i] = 1; free[i] = 1;
@ -153,6 +149,21 @@ free_chain(int i)
} }
} }
static int
alloc3_desc(int *idx)
{
for(int i = 0; i < 3; i++){
idx[i] = alloc_desc();
if(idx[i] < 0){
for(int j = 0; j < i; j++)
free_desc(idx[j]);
return -1;
break;
}
}
return 0;
}
void void
virtio_disk_rw(struct buf *b) virtio_disk_rw(struct buf *b)
{ {
@ -167,21 +178,12 @@ virtio_disk_rw(struct buf *b)
// allocate the three descriptors. // allocate the three descriptors.
int idx[3]; int idx[3];
while(1){ while(1){
int done = 1; if(alloc3_desc(idx) == 0) {
for(int i = 0; i < 3; i++){
idx[i] = alloc_desc();
if(idx[i] < 0){
for(int j = 0; j < i; j++)
free_desc(idx[j]);
done = 0;
break;
}
}
if(done)
break; break;
}
sleep(&free[0], &virtio_disk_lock); sleep(&free[0], &virtio_disk_lock);
} }
// format the three descriptors. // format the three descriptors.
// qemu's virtio-blk.c reads them. // qemu's virtio-blk.c reads them.
@ -242,28 +244,21 @@ virtio_disk_rw(struct buf *b)
void void
virtio_disk_intr() virtio_disk_intr()
{ {
// the used area is:
// uint16 flags
// uint16 idx
// array of VRingUsedElem
volatile uint16 *idxp = (uint16 *)(used + 2);
volatile struct VRingUsedElem *e0 = (struct VRingUsedElem *)(used + 4);
acquire(&virtio_disk_lock); acquire(&virtio_disk_lock);
while((used_idx % NUM) != (*idxp % NUM)){ while((used_idx % NUM) != (used->id % NUM)){
volatile struct VRingUsedElem *ue = &e0[used_idx]; int id = used->elems[used_idx].id;
if(info[ue->id].status != 0) if(info[id].status != 0)
panic("virtio_disk_intr status"); panic("virtio_disk_intr status");
info[ue->id].b->flags |= B_VALID; info[id].b->flags |= B_VALID;
info[ue->id].b->flags &= ~B_DIRTY; info[id].b->flags &= ~B_DIRTY;
wakeup(info[ue->id].b); wakeup(info[id].b);
info[ue->id].b = 0; info[id].b = 0;
free_chain(ue->id); free_chain(id);
used_idx = (used_idx + 1) % NUM; used_idx = (used_idx + 1) % NUM;
} }