From: Sergei Shtepa <sergei.shtepa@linux.dev>
To: axboe@kernel.dk, hch@infradead.org, corbet@lwn.net, snitzer@kernel.org
Cc: mingo@redhat.com, peterz@infradead.org, juri.lelli@redhat.com,
vincent.guittot@linaro.org, mgorman@suse.de, vschneid@redhat.com,
viro@zeniv.linux.org.uk, brauner@kernel.org,
linux-block@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
Sergei Shtepa <sergei.shtepa@veeam.com>
Subject: [PATCH v6 08/11] blksnap: event queue from the difference storage
Date: Fri, 24 Nov 2023 17:38:33 +0100 [thread overview]
Message-ID: <20231124163836.27256-9-sergei.shtepa@linux.dev> (raw)
In-Reply-To: <20231124163836.27256-1-sergei.shtepa@linux.dev>
From: Sergei Shtepa <sergei.shtepa@veeam.com>
Events are used to immediately notify the user land of a change in the
snapshot state. For example, if an error occurred while snapshot holding
when reading data from the original block device or from the difference
storage.
Co-developed-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Sergei Shtepa <sergei.shtepa@veeam.com>
---
drivers/block/blksnap/event_queue.c | 81 +++++++++++++++++++++++++++++
drivers/block/blksnap/event_queue.h | 64 +++++++++++++++++++++++
2 files changed, 145 insertions(+)
create mode 100644 drivers/block/blksnap/event_queue.c
create mode 100644 drivers/block/blksnap/event_queue.h
diff --git a/drivers/block/blksnap/event_queue.c b/drivers/block/blksnap/event_queue.c
new file mode 100644
index 000000000000..2256167b631b
--- /dev/null
+++ b/drivers/block/blksnap/event_queue.c
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2023 Veeam Software Group GmbH */
+#define pr_fmt(fmt) KBUILD_MODNAME "-event_queue: " fmt
+
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include "event_queue.h"
+
+void event_queue_init(struct event_queue *event_queue)
+{
+ INIT_LIST_HEAD(&event_queue->list);
+ spin_lock_init(&event_queue->lock);
+ init_waitqueue_head(&event_queue->wq_head);
+}
+
+void event_queue_done(struct event_queue *event_queue)
+{
+ struct event *event;
+
+ spin_lock(&event_queue->lock);
+ while (!list_empty(&event_queue->list)) {
+ event = list_first_entry(&event_queue->list, struct event,
+ link);
+ list_del(&event->link);
+ event_free(event);
+ }
+ spin_unlock(&event_queue->lock);
+}
+
+int event_gen(struct event_queue *event_queue, gfp_t flags, int code,
+ const void *data, int data_size)
+{
+ struct event *event;
+
+ event = kzalloc(sizeof(struct event) + data_size + 1, flags);
+ if (!event)
+ return -ENOMEM;
+
+ event->time = ktime_get();
+ event->code = code;
+ event->data_size = data_size;
+ memcpy(event->data, data, data_size);
+
+ pr_debug("Generate event: time=%lld code=%d data_size=%d\n",
+ event->time, event->code, event->data_size);
+
+ spin_lock(&event_queue->lock);
+ list_add_tail(&event->link, &event_queue->list);
+ spin_unlock(&event_queue->lock);
+
+ wake_up(&event_queue->wq_head);
+ return 0;
+}
+
+struct event *event_wait(struct event_queue *event_queue,
+ unsigned long timeout_ms)
+{
+ int ret;
+
+ ret = wait_event_interruptible_timeout(event_queue->wq_head,
+ !list_empty(&event_queue->list), timeout_ms);
+ if (ret >= 0) {
+ struct event *event = ERR_PTR(-ENOENT);
+
+ spin_lock(&event_queue->lock);
+ if (!list_empty(&event_queue->list)) {
+ event = list_first_entry(&event_queue->list,
+ struct event, link);
+ list_del(&event->link);
+ }
+ spin_unlock(&event_queue->lock);
+ return event;
+ }
+ if (ret == -ERESTARTSYS) {
+ pr_debug("event waiting interrupted\n");
+ return ERR_PTR(-EINTR);
+ }
+
+ pr_err("Failed to wait event. errno=%d\n", abs(ret));
+ return ERR_PTR(ret);
+}
diff --git a/drivers/block/blksnap/event_queue.h b/drivers/block/blksnap/event_queue.h
new file mode 100644
index 000000000000..c919eee3ed96
--- /dev/null
+++ b/drivers/block/blksnap/event_queue.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* Copyright (C) 2023 Veeam Software Group GmbH */
+#ifndef __BLKSNAP_EVENT_QUEUE_H
+#define __BLKSNAP_EVENT_QUEUE_H
+
+#include <linux/types.h>
+#include <linux/ktime.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+#include <linux/wait.h>
+
+/**
+ * struct event - An event to be passed to the user space.
+ * @link:
+ * The list header allows to combine events from the queue.
+ * @time:
+ * A timestamp indicates when an event occurred.
+ * @code:
+ * Event code.
+ * @data_size:
+ * The number of bytes in the event data array.
+ * @data:
+ * An array of event data.
+ *
+ * Events can be different, so they contain different data. The size of the
+ * data array is not defined exactly, but it has limitations. The size of
+ * the event structure is limited by the PAGE_SIZE (4096 bytes).
+ */
+struct event {
+ struct list_head link;
+ ktime_t time;
+ int code;
+ int data_size;
+ char data[];
+};
+
+/**
+ * struct event_queue - A queue of &struct event.
+ * @list:
+ * Linked list for storing events.
+ * @lock:
+ * Spinlock allows to guarantee safety of the linked list.
+ * @wq_head:
+ * A wait queue allows to put a user thread in a waiting state until
+ * an event appears in the linked list.
+ */
+struct event_queue {
+ struct list_head list;
+ spinlock_t lock;
+ struct wait_queue_head wq_head;
+};
+
+void event_queue_init(struct event_queue *event_queue);
+void event_queue_done(struct event_queue *event_queue);
+
+int event_gen(struct event_queue *event_queue, gfp_t flags, int code,
+ const void *data, int data_size);
+struct event *event_wait(struct event_queue *event_queue,
+ unsigned long timeout_ms);
+static inline void event_free(struct event *event)
+{
+ kfree(event);
+};
+#endif /* __BLKSNAP_EVENT_QUEUE_H */
--
2.20.1
next prev parent reply other threads:[~2023-11-24 16:39 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-24 16:38 [PATCH v6 00/11] blksnap - block devices snapshots module Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 01/11] documentation: Block Device Filtering Mechanism Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 02/11] block: " Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 03/11] documentation: Block Devices Snapshots Module Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 04/11] blksnap: header file of the module interface Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 05/11] blksnap: module management interface functions Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 06/11] blksnap: handling and tracking I/O units Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 07/11] blksnap: difference storage and chunk Sergei Shtepa
2023-11-24 16:38 ` Sergei Shtepa [this message]
2023-11-24 16:38 ` [PATCH v6 09/11] blksnap: snapshot and snapshot image block device Sergei Shtepa
2023-11-24 16:38 ` [PATCH v6 10/11] blksnap: Kconfig and Makefile Sergei Shtepa
-- strict thread matches above, loose matches on Subject: below --
2023-11-24 16:59 [PATCH v6 00/11] blksnap - block devices snapshots module Sergei Shtepa
2023-11-24 16:59 ` [PATCH v6 08/11] blksnap: event queue from the difference storage Sergei Shtepa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231124163836.27256-9-sergei.shtepa@linux.dev \
--to=sergei.shtepa@linux.dev \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=corbet@lwn.net \
--cc=hch@infradead.org \
--cc=juri.lelli@redhat.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mgorman@suse.de \
--cc=mingo@redhat.com \
--cc=peterz@infradead.org \
--cc=sergei.shtepa@veeam.com \
--cc=snitzer@kernel.org \
--cc=vincent.guittot@linaro.org \
--cc=viro@zeniv.linux.org.uk \
--cc=vschneid@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).