ia64/xen-unstable

changeset 16829:80e177b12fd2

minios: add blkfront testing

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  }