[Devel] [PATCH rh8 2/2] ploop: Check for activity being out of bio lists on destruction
Kirill Tkhai
ktkhai at virtuozzo.com
Wed Mar 11 17:26:27 MSK 2020
Queue ploop_inflight_bios_ref_switch() before flushing the queue
to make inflight activity appear on delayed lists. Check the lists
right after that.
Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
---
drivers/md/dm-ploop-cmd.c | 41 +++++++++++++++++++++++++++++++++++++++++
drivers/md/dm-ploop-target.c | 26 ++++++++------------------
drivers/md/dm-ploop.h | 1 +
3 files changed, 50 insertions(+), 18 deletions(-)
diff --git a/drivers/md/dm-ploop-cmd.c b/drivers/md/dm-ploop-cmd.c
index 30fea812b9c0..a6597f573151 100644
--- a/drivers/md/dm-ploop-cmd.c
+++ b/drivers/md/dm-ploop-cmd.c
@@ -1625,6 +1625,43 @@ static int ploop_push_backup_write(struct ploop *ploop, char *uuid,
return 0;
}
+static bool ploop_has_pending_activity(struct ploop *ploop)
+{
+ bool has;
+
+ spin_lock_irq(&ploop->deferred_lock);
+ has = ploop->deferred_cmd;
+ has |= !bio_list_empty(&ploop->deferred_bios);
+ has |= !bio_list_empty(&ploop->discard_bios);
+ has |= !bio_list_empty(&ploop->delta_cow_action_list);
+ spin_unlock_irq(&ploop->deferred_lock);
+
+ return has;
+}
+
+static void process_try_preflush(struct ploop *ploop, struct ploop_cmd *cmd)
+{
+ /* Make all inflight bios appear in pending activities */
+ cmd->retval = ploop_inflight_bios_ref_switch(ploop, true);
+ if (!cmd->retval)
+ cmd->retval = ploop_has_pending_activity(ploop);
+ complete(&cmd->comp); /* Last touch of cmd memory */
+}
+
+static int ploop_try_preflush(struct ploop *ploop)
+{
+ struct ploop_cmd cmd = { {0} };
+
+ cmd.type = PLOOP_CMD_TRY_PREFLUSH;
+ cmd.ploop = ploop;
+
+ init_completion(&cmd.comp);
+ ploop_queue_deferred_cmd(ploop, &cmd);
+ wait_for_completion(&cmd.comp);
+ return cmd.retval;
+
+}
+
/* Handle user commands requested via "message" interface */
void process_deferred_cmd(struct ploop *ploop, struct ploop_index_wb *piwb)
__releases(&ploop->deferred_lock)
@@ -1659,6 +1696,8 @@ void process_deferred_cmd(struct ploop *ploop, struct ploop_index_wb *piwb)
process_flip_upper_deltas(ploop, cmd);
} else if (cmd->type == PLOOP_CMD_SET_PUSH_BACKUP) {
process_set_push_backup(ploop, cmd);
+ } else if (cmd->type == PLOOP_CMD_TRY_PREFLUSH) {
+ process_try_preflush(ploop, cmd);
} else {
cmd->retval = -EINVAL;
complete(&cmd->comp);
@@ -1763,6 +1802,8 @@ int ploop_message(struct dm_target *ti, unsigned int argc, char **argv,
if (argc != 3 || sscanf(argv[2], "%llu:%llu", &val, &val2) != 2)
goto unlock;
ret = ploop_push_backup_write(ploop, argv[1], val, val2);
+ } else if (!strcmp(argv[0], "try_preflush")) {
+ ret = ploop_try_preflush(ploop);
} else {
ret = -ENOTSUPP;
}
diff --git a/drivers/md/dm-ploop-target.c b/drivers/md/dm-ploop-target.c
index 318048227f53..d36906793b9f 100644
--- a/drivers/md/dm-ploop-target.c
+++ b/drivers/md/dm-ploop-target.c
@@ -29,33 +29,23 @@ static void inflight_bios_ref_exit1(struct percpu_ref *ref)
complete(&ploop->inflight_bios_ref_comp);
}
-static bool ploop_has_pending_activity(struct ploop *ploop)
-{
- bool has;
-
- spin_lock_irq(&ploop->deferred_lock);
- has = ploop->deferred_cmd;
- has |= !bio_list_empty(&ploop->deferred_bios);
- has |= !bio_list_empty(&ploop->discard_bios);
- has |= !bio_list_empty(&ploop->delta_cow_action_list);
- spin_unlock_irq(&ploop->deferred_lock);
-
- return has;
-}
-
+/* This is called on final device destroy */
static void ploop_flush_workqueue(struct ploop *ploop)
{
+ char *argv[1] = {"try_preflush"};
bool again = true;
while (again) {
flush_workqueue(ploop->wq);
- again = ploop_has_pending_activity(ploop);
- if (again)
- schedule_timeout(HZ);
+ /*
+ * Normally, ploop_message("try_preflush") returns 0 or 1.
+ * In case of underlining bdev is hung, this finishes with
+ * error by timeout, and our caller (.dtr) never completes.
+ */
+ again = ploop_message(ploop->ti, 1, argv, NULL, 0);
}
}
-
static void ploop_destroy(struct ploop *ploop)
{
int i;
diff --git a/drivers/md/dm-ploop.h b/drivers/md/dm-ploop.h
index 3b0a96da837f..52b66440f066 100644
--- a/drivers/md/dm-ploop.h
+++ b/drivers/md/dm-ploop.h
@@ -46,6 +46,7 @@ struct ploop_cmd {
#define PLOOP_CMD_TRACKING_START 7
#define PLOOP_CMD_FLIP_UPPER_DELTAS 8
#define PLOOP_CMD_SET_PUSH_BACKUP 9
+#define PLOOP_CMD_TRY_PREFLUSH 10
struct completion comp;
struct ploop *ploop;
unsigned int type;
More information about the Devel
mailing list