Fix segfault race on exit for platforms that don't have disk util support
authorJens Axboe <axboe@kernel.dk>
Thu, 27 Sep 2012 09:31:50 +0000 (11:31 +0200)
committerJens Axboe <axboe@kernel.dk>
Thu, 27 Sep 2012 09:31:50 +0000 (11:31 +0200)
We still need to quisce the disk util thread, as it also functions
as the runtime ETA status printer.

Signed-off-by: Jens Axboe <axboe@kernel.dk>
backend.c
diskutil.c
diskutil.h

index c31d22a..b5501c6 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -67,6 +67,7 @@ unsigned int nr_thread = 0;
 int shm_id = 0;
 int temp_stall_ts;
 unsigned long done_secs = 0;
+volatile int disk_util_exit = 0;
 
 #define PAGE_ALIGN(buf)        \
        (char *) (((uintptr_t) (buf) + page_mask) & ~page_mask)
@@ -1610,6 +1611,13 @@ void wait_for_disk_thread_exit(void)
        fio_mutex_down(disk_thread_mutex);
 }
 
+static void free_disk_util(void)
+{
+       disk_util_start_exit();
+       wait_for_disk_thread_exit();
+       disk_util_prune_entries();
+}
+
 static void *disk_thread_main(void *data)
 {
        int ret = 0;
index d2c0b97..d98e39a 100644 (file)
@@ -15,7 +15,6 @@ static int last_majdev, last_mindev;
 static struct disk_util *last_du;
 
 static struct fio_mutex *disk_util_mutex;
-static int disk_util_exit;
 
 FLIST_HEAD(disk_list);
 
@@ -539,16 +538,13 @@ static void aggregate_slaves_stats(struct disk_util *masterdu)
                agg->max_util.u.f = 100.0;
 }
 
-void free_disk_util(void)
+void disk_util_prune_entries(void)
 {
-       struct disk_util *du;
-
-       disk_util_exit = 1;
-       wait_for_disk_thread_exit();
-
        fio_mutex_down(disk_util_mutex);
 
        while (!flist_empty(&disk_list)) {
+               struct disk_util *du;
+
                du = flist_entry(disk_list.next, struct disk_util, list);
                flist_del(&du->list);
                disk_util_free(du);
index b223150..b89aacc 100644 (file)
@@ -3,6 +3,8 @@
 #include "json.h"
 #define FIO_DU_NAME_SZ         64
 
+extern volatile int disk_util_exit;
+
 /*
  * Disk utils as read in /sys/block/<dev>/stat
  */
@@ -102,20 +104,25 @@ extern void wait_for_disk_thread_exit(void);
 #ifdef FIO_HAVE_DISK_UTIL
 extern void print_disk_util(struct disk_util_stat *, struct disk_util_agg *, int terse);
 extern void show_disk_util(int terse, struct json_object *parent);
-extern void free_disk_util(void);
 extern void init_disk_util(struct thread_data *);
 extern int update_io_ticks(void);
 extern void setup_disk_util(void);
+extern void disk_util_prune_entries(void);
 #else
 #define print_disk_util(dus, agg, terse)
 #define show_disk_util(terse, parent)
-#define free_disk_util()
+#define disk_util_prune_entries()
 #define init_disk_util(td)
 #define setup_disk_util()
 static inline int update_io_ticks(void)
 {
-       return 0;
+       return disk_util_exit;
 }
 #endif
 
+static inline void disk_util_start_exit(void)
+{
+       disk_util_exit = 1;
+}
+
 #endif