From 08f353e6770a73fe85438c24bfdb304793a4f370 Mon Sep 17 00:00:00 2001
From: Asias He <asias@cloudius-systems.com>
Date: Mon, 23 Dec 2013 17:10:19 +0800
Subject: [PATCH] tests: Wait until all bio are done in bdev-write test.

I saw this Abort:

35.159 Mb/s
50.230 Mb/s
46.648 Mb/s
68.850 Mb/s
Wrote 613.418 MB in 10.00 s
Aborted

The backtrace says:

  (gdb) bt
  #0  0x000000000035bb82 in halt_no_interrupts () at
  /home/asias/src/cloudius-systems/osv/arch/x64/processor.hh:241
  #1  osv::halt () at
  /home/asias/src/cloudius-systems/osv/core/power.cc:28
  #2  0x0000000000218142 in abort (msg=msg@entry=0x55197f "Aborted\n") at
  /home/asias/src/cloudius-systems/osv/runtime.cc:89
  #3  0x000000000021816e in abort () at
  /home/asias/src/cloudius-systems/osv/runtime.cc:79
  #4  0x000000000039eaa2 in osv::generate_signal (siginfo=...,
  ef=0xffffc0003eb56008) at
  /home/asias/src/cloudius-systems/osv/libc/signal.cc:58
  #5  0x000000000039eb0c in osv::handle_segmentation_fault
  (addr=<optimized out>, ef=<optimized out>) at
  /home/asias/src/cloudius-systems/osv/libc/signal.cc:73
  #6  0x000000000030b45c in mmu::vm_sigsegv
  (addr=addr@entry=17592186060800, ef=ef@entry=0xffffc0003eb56008) at
  /home/asias/src/cloudius-systems/osv/core/mmu.cc:763
  #7  0x000000000030b54b in mmu::vm_fault (addr=<optimized out>,
  addr@entry=17592186061840, ef=ef@entry=0xffffc0003eb56008)
      at /home/asias/src/cloudius-systems/osv/core/mmu.cc:773
  #8  0x000000000032bff5 in page_fault (ef=0xffffc0003eb56008) at
  /home/asias/src/cloudius-systems/osv/arch/x64/mmu.cc:35
  #9  <signal handler called>
  #10 0x0000100000004410 in ?? ()
  #11 0x000000000031e5fd in virtio::blk::req_done
  (this=0xffffc0003eddb800) at
  /home/asias/src/cloudius-systems/osv/drivers/virtio-blk.

Wait until all the bio are done to fix this use after free.

This patch also make the test to measure completed writes instead of
submitted writes.

Reviewed-by: Tomasz Grabiec <tgrabiec@gmail.com>
Signed-off-by: Asias He <asias@cloudius-systems.com>
Signed-off-by: Pekka Enberg <penberg@cloudius-systems.com>
---
 tests/misc-bdev-write.cc | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/tests/misc-bdev-write.cc b/tests/misc-bdev-write.cc
index 324f7d5d8..b1be4699a 100644
--- a/tests/misc-bdev-write.cc
+++ b/tests/misc-bdev-write.cc
@@ -20,10 +20,15 @@
 
 static std::chrono::high_resolution_clock s_clock;
 
+std::atomic<int> bio_inflights(0);
+std::atomic<int> bytes_written(0);
+
 static void bio_done(struct bio* bio)
 {
+    bytes_written += bio->bio_bcount;
     free(bio->bio_data);
     destroy_bio(bio);
+    bio_inflights--;
 }
 
 int main(int argc, char const *argv[])
@@ -41,8 +46,6 @@ int main(int argc, char const *argv[])
 
     const std::chrono::seconds test_duration(10);
     const int buf_size = 4*KB;
-
-    std::atomic<int> bytes_written(0);
     int total = 0;
     int offset = 0;
 
@@ -55,6 +58,7 @@ int main(int argc, char const *argv[])
 
     while (s_clock.now() < end_at) {
         auto bio = alloc_bio();
+        bio_inflights++;
         bio->bio_cmd = BIO_WRITE;
         bio->bio_dev = dev;
         bio->bio_data = malloc(buf_size);
@@ -62,16 +66,20 @@ int main(int argc, char const *argv[])
         bio->bio_bcount = buf_size;
         bio->bio_caller1 = bio;
         bio->bio_done = bio_done;
+
         dev->driver->devops->strategy(bio);
-        offset += buf_size;
 
-        bytes_written += buf_size;
+        offset += buf_size;
         total += buf_size;
     }
 
+    while (bio_inflights != 0) {
+        usleep(2000);
+    }
+
     auto test_end = s_clock.now();
     _stat_printer.stop();
 
     printf("Wrote %.3f MB in %.2f s\n", (float) total / MB, to_seconds(test_end - test_start));
     return 0;
-}
\ No newline at end of file
+}
-- 
GitLab