debuggers.hg
changeset 16812:80e177b12fd2
minios: add blkfront testing
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
Signed-off-by: Samuel Thibault <samuel.thibault@eu.citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Tue Jan 22 09:46:33 2008 +0000 (2008-01-22) |
parents | 623d668b3029 |
children | cc5bb500df5f |
files | extras/mini-os/Makefile extras/mini-os/include/blkfront.h extras/mini-os/kernel.c |
line diff
1.1 --- a/extras/mini-os/Makefile Tue Jan 22 09:46:15 2008 +0000 1.2 +++ b/extras/mini-os/Makefile Tue Jan 22 09:46:33 2008 +0000 1.3 @@ -57,6 +57,9 @@ endif 1.4 # Include common mini-os makerules. 1.5 include minios.mk 1.6 1.7 +# Set tester flags 1.8 +# CFLAGS += -DBLKTEST_WRITE 1.9 + 1.10 # Define some default flags for linking. 1.11 LDLIBS := 1.12 LDARCHLIB := -L$(TARGET_ARCH_DIR) -l$(ARCH_LIB_NAME)
2.1 --- a/extras/mini-os/include/blkfront.h Tue Jan 22 09:46:15 2008 +0000 2.2 +++ b/extras/mini-os/include/blkfront.h Tue Jan 22 09:46:33 2008 +0000 2.3 @@ -15,7 +15,9 @@ struct blkfront_aiocb 2.4 void (*aio_cb)(struct blkfront_aiocb *aiocb, int ret); 2.5 }; 2.6 struct blkfront_dev *init_blkfront(char *nodename, uint64_t *sectors, unsigned *sector_size, int *mode); 2.7 +#ifdef HAVE_LIBC 2.8 int blkfront_open(struct blkfront_dev *dev); 2.9 +#endif 2.10 void blkfront_aio(struct blkfront_aiocb *aiocbp, int write); 2.11 void blkfront_aio_read(struct blkfront_aiocb *aiocbp); 2.12 void blkfront_aio_write(struct blkfront_aiocb *aiocbp);
3.1 --- a/extras/mini-os/kernel.c Tue Jan 22 09:46:15 2008 +0000 3.2 +++ b/extras/mini-os/kernel.c Tue Jan 22 09:46:33 2008 +0000 3.3 @@ -38,7 +38,10 @@ 3.4 #include <xenbus.h> 3.5 #include <gnttab.h> 3.6 #include <netfront.h> 3.7 +#include <blkfront.h> 3.8 #include <fs.h> 3.9 +#include <xmalloc.h> 3.10 +#include <fcntl.h> 3.11 #include <xen/features.h> 3.12 #include <xen/version.h> 3.13 3.14 @@ -86,6 +89,178 @@ static void netfront_thread(void *p) 3.15 init_netfront(NULL, NULL, NULL); 3.16 } 3.17 3.18 +#define RAND_MIX 2654435769 3.19 + 3.20 +/* Should be random enough for this use */ 3.21 +static int rand(void) 3.22 +{ 3.23 + static unsigned int previous; 3.24 + struct timeval tv; 3.25 + gettimeofday(&tv, NULL); 3.26 + previous += tv.tv_sec + tv.tv_usec; 3.27 + previous *= RAND_MIX; 3.28 + return previous; 3.29 +} 3.30 + 3.31 +static struct blkfront_dev *blk_dev; 3.32 +static uint64_t blk_sectors; 3.33 +static unsigned blk_sector_size; 3.34 +static int blk_mode; 3.35 +static uint64_t blk_size_read; 3.36 +static uint64_t blk_size_write; 3.37 + 3.38 +struct blk_req { 3.39 + struct blkfront_aiocb aiocb; 3.40 + int rand_value; 3.41 + struct blk_req *next; 3.42 +}; 3.43 + 3.44 +#ifdef BLKTEST_WRITE 3.45 +static struct blk_req *blk_to_read; 3.46 +#endif 3.47 + 3.48 +static struct blk_req *blk_alloc_req(uint64_t sector) 3.49 +{ 3.50 + struct blk_req *req = xmalloc(struct blk_req); 3.51 + req->aiocb.aio_dev = blk_dev; 3.52 + req->aiocb.aio_buf = _xmalloc(blk_sector_size, blk_sector_size); 3.53 + req->aiocb.aio_nbytes = blk_sector_size; 3.54 + req->aiocb.aio_offset = sector * blk_sector_size; 3.55 + req->aiocb.data = req; 3.56 + req->next = NULL; 3.57 + return req; 3.58 +} 3.59 + 3.60 +static void blk_read_completed(struct blkfront_aiocb *aiocb, int ret) 3.61 +{ 3.62 + struct blk_req *req = aiocb->data; 3.63 + if (ret) 3.64 + printk("got error code %d when reading at offset %ld\n", ret, aiocb->aio_offset); 3.65 + else 3.66 + blk_size_read += blk_sector_size; 3.67 + free(aiocb->aio_buf); 3.68 + free(req); 3.69 +} 3.70 + 3.71 +static void blk_read_sector(uint64_t sector) 3.72 +{ 3.73 + struct blk_req *req; 3.74 + 3.75 + req = blk_alloc_req(sector); 3.76 + req->aiocb.aio_cb = blk_read_completed; 3.77 + 3.78 + blkfront_aio_read(&req->aiocb); 3.79 +} 3.80 + 3.81 +#ifdef BLKTEST_WRITE 3.82 +static void blk_write_read_completed(struct blkfront_aiocb *aiocb, int ret) 3.83 +{ 3.84 + struct blk_req *req = aiocb->data; 3.85 + int rand_value; 3.86 + int i; 3.87 + int *buf; 3.88 + 3.89 + if (ret) { 3.90 + printk("got error code %d when reading back at offset %ld\n", ret, aiocb->aio_offset); 3.91 + free(aiocb->aio_buf); 3.92 + free(req); 3.93 + return; 3.94 + } 3.95 + blk_size_read += blk_sector_size; 3.96 + buf = (int*) aiocb->aio_buf; 3.97 + rand_value = req->rand_value; 3.98 + for (i = 0; i < blk_sector_size / sizeof(int); i++) { 3.99 + if (buf[i] != rand_value) { 3.100 + printk("bogus data at offset %ld\n", aiocb->aio_offset + i); 3.101 + break; 3.102 + } 3.103 + rand_value *= RAND_MIX; 3.104 + } 3.105 + free(aiocb->aio_buf); 3.106 + free(req); 3.107 +} 3.108 + 3.109 +static void blk_write_completed(struct blkfront_aiocb *aiocb, int ret) 3.110 +{ 3.111 + struct blk_req *req = aiocb->data; 3.112 + if (ret) { 3.113 + printk("got error code %d when writing at offset %ld\n", ret, aiocb->aio_offset); 3.114 + free(aiocb->aio_buf); 3.115 + free(req); 3.116 + return; 3.117 + } 3.118 + blk_size_write += blk_sector_size; 3.119 + /* Push write check */ 3.120 + req->next = blk_to_read; 3.121 + blk_to_read = req; 3.122 +} 3.123 + 3.124 +static void blk_write_sector(uint64_t sector) 3.125 +{ 3.126 + struct blk_req *req; 3.127 + int rand_value; 3.128 + int i; 3.129 + int *buf; 3.130 + 3.131 + req = blk_alloc_req(sector); 3.132 + req->aiocb.aio_cb = blk_write_completed; 3.133 + req->rand_value = rand_value = rand(); 3.134 + 3.135 + buf = (int*) req->aiocb.aio_buf; 3.136 + for (i = 0; i < blk_sector_size / sizeof(int); i++) { 3.137 + buf[i] = rand_value; 3.138 + rand_value *= RAND_MIX; 3.139 + } 3.140 + 3.141 + blkfront_aio_write(&req->aiocb); 3.142 +} 3.143 +#endif 3.144 + 3.145 +static void blkfront_thread(void *p) 3.146 +{ 3.147 + time_t lasttime = 0; 3.148 + blk_dev = init_blkfront(NULL, &blk_sectors, &blk_sector_size, &blk_mode); 3.149 + if (!blk_dev) 3.150 + return; 3.151 + 3.152 +#ifdef BLKTEST_WRITE 3.153 + if (blk_mode == O_RDWR) { 3.154 + blk_write_sector(0); 3.155 + blk_write_sector(blk_sectors-1); 3.156 + } else 3.157 +#endif 3.158 + { 3.159 + blk_read_sector(0); 3.160 + blk_read_sector(blk_sectors-1); 3.161 + } 3.162 + 3.163 + while (1) { 3.164 + uint64_t sector = rand() % blk_sectors; 3.165 + struct timeval tv; 3.166 +#ifdef BLKTEST_WRITE 3.167 + if (blk_mode == O_RDWR) 3.168 + blk_write_sector(sector); 3.169 + else 3.170 +#endif 3.171 + blk_read_sector(sector); 3.172 + blkfront_aio_poll(blk_dev); 3.173 + gettimeofday(&tv, NULL); 3.174 + if (tv.tv_sec > lasttime + 10) { 3.175 + printk("%llu read, %llu write\n", blk_size_read, blk_size_write); 3.176 + lasttime = tv.tv_sec; 3.177 + } 3.178 + 3.179 +#ifdef BLKTEST_WRITE 3.180 + while (blk_to_read) { 3.181 + struct blk_req *req = blk_to_read; 3.182 + blk_to_read = blk_to_read->next; 3.183 + req->aiocb.aio_cb = blk_write_read_completed; 3.184 + blkfront_aio_read(&req->aiocb); 3.185 + } 3.186 +#endif 3.187 + } 3.188 +} 3.189 + 3.190 static void fs_thread(void *p) 3.191 { 3.192 init_fs_frontend(); 3.193 @@ -98,6 +273,7 @@ static void fs_thread(void *p) 3.194 create_thread("xenbus_tester", xenbus_tester, si); 3.195 create_thread("periodic_thread", periodic_thread, si); 3.196 create_thread("netfront", netfront_thread, si); 3.197 + create_thread("blkfront", blkfront_thread, si); 3.198 create_thread("fs-frontend", fs_thread, si); 3.199 return 0; 3.200 }