]> git.sesse.net Git - bcachefs-tools-debian/commitdiff
Stop blkdev completion thread at process exit time, to make valgrind
authorJustin Husted <sigstop@gmail.com>
Sun, 3 Nov 2019 05:42:55 +0000 (22:42 -0700)
committerKent Overstreet <kent.overstreet@gmail.com>
Mon, 4 Nov 2019 04:17:43 +0000 (23:17 -0500)
happy.

Signed-off-by: Justin Husted <sigstop@gmail.com>
linux/blkdev.c

index 8139e18d3b95999d8604936b3b31c0471c9d75d5..370f08fc5596e0d877d73de3f82b60885a7f1b7e 100644 (file)
@@ -228,6 +228,8 @@ struct block_device *lookup_bdev(const char *path)
        return ERR_PTR(-EINVAL);
 }
 
+static atomic_t aio_thread_stop;
+
 static int aio_completion_thread(void *arg)
 {
        struct io_event events[8], *ev;
@@ -237,6 +239,9 @@ static int aio_completion_thread(void *arg)
                ret = io_getevents(aio_ctx, 1, ARRAY_SIZE(events),
                                   events, NULL);
 
+               if (atomic_read(&aio_thread_stop))
+                       break;
+
                if (ret < 0 && ret == -EINTR)
                        continue;
                if (ret < 0)
@@ -255,6 +260,8 @@ static int aio_completion_thread(void *arg)
        return 0;
 }
 
+static struct task_struct *aio_task = NULL;
+
 __attribute__((constructor(102)))
 static void blkdev_init(void)
 {
@@ -265,4 +272,39 @@ static void blkdev_init(void)
 
        p = kthread_run(aio_completion_thread, NULL, "aio_completion");
        BUG_ON(IS_ERR(p));
+
+       aio_task = p;
+}
+
+__attribute__((destructor(102)))
+static void blkdev_cleanup(void)
+{
+       struct task_struct *p = NULL;
+       swap(aio_task, p);
+
+       atomic_set(&aio_thread_stop, 1);
+
+       /* I mean, really?! IO_CMD_NOOP is even defined, but not implemented. */
+       int fds[2];
+       int ret = pipe(fds);
+       if (ret != 0)
+               die("pipe err: %s", strerror(ret));
+
+       /* Wake up the completion thread with spurious work. */
+       int junk = 0;
+       struct iocb iocb = {
+               .aio_lio_opcode = IO_CMD_PWRITE,
+               .aio_fildes = fds[1],
+               .u.c.buf = &junk,
+               .u.c.nbytes = 1,
+       }, *iocbp = &iocb;
+       ret = io_submit(aio_ctx, 1, &iocbp);
+       if (ret != 1)
+               die("io_submit cleanup err: %s", strerror(-ret));
+
+       ret = kthread_stop(p);
+       BUG_ON(ret);
+
+       close(fds[0]);
+       close(fds[1]);
 }