From patchwork Fri Nov 24 16:38:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sergei Shtepa X-Patchwork-Id: 169510 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:ce62:0:b0:403:3b70:6f57 with SMTP id o2csp1355878vqx; Fri, 24 Nov 2023 08:40:02 -0800 (PST) X-Google-Smtp-Source: AGHT+IHNQnVG4hFRxxSZlk0XQtT4RCtUA+EL7CDspRturo8YSYJsQ/HTygJhBBnDIxLJbn4jniaR X-Received: by 2002:a17:90b:4b10:b0:285:9ec0:892a with SMTP id lx16-20020a17090b4b1000b002859ec0892amr504986pjb.33.1700844002537; Fri, 24 Nov 2023 08:40:02 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1700844002; cv=none; d=google.com; s=arc-20160816; b=PjnMBQMZRGCpc73BvIJ5thb64aipA+UJDq89989/peEZRifjYwfBDvhLvoSitdVdFF YRtXSSgjJg4Yi5a0W5DZksq1RQgWeOVEq6NPV3O5Rz9RZksML5LMO4W7tmN+73Hj9qvN YklGbCcJrjakyA+3DA1YMe+terq0i0B4aqE/T1ayIjl6CKC47SrmAuphxI8GQUhvAVDD XKPReKLR1lRtWLga8oFnEra8sMHNDhbq0a1FqR4diBvoQXw/c72T4sF5vcYy/rvQwRTY pzixBLx9WbfwqO6b2+yw2g3FTbutyfFhVad72u4ynUoIHYbsckvXzG+7+NlXnVJ0s8/u U43Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=HWENQVeTzgUlxGLBDIpOkaJ8YTyPuR19yc5enxAnFIw=; fh=a9ApmeGvcCB6Trsutt5tt4NXJ5Ik8LZp8ymXtojMIXc=; b=jF+8EbmT0TW3lyd55sPErByR7SyEhJBkpOSnpnm/7cVWtW5pwApXi309+qf7PIcR3y 6SAiIaV+4uPaZPXm7NJ7+cDz2QlUxwcYq40G4gmMQOH0CXiOVlvvY5/JY7NxZV9lWdQ+ licY1w8aCULCiSKY6Itdw+3aSHZqD1BUNOQEj7zx5G0mrKR+fAyZrijkhV9WnU5yXKz+ 1CD5clsMrolHvUtof+Hac3RYCB9F3Mw5atoi3IbIugDEdIyXMwBs9uvV3aUEnRMlFl7e 9i4PBBvJPi2HK0syO5l/CYNgP4UpwRvxTjemyZ5cfI7exMAAUtqVGojUV1Yq/DXPMFWY tD2Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=cSL6VMmd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from pete.vger.email (pete.vger.email. [2620:137:e000::3:6]) by mx.google.com with ESMTPS id mt4-20020a17090b230400b0027762d380f7si4383826pjb.8.2023.11.24.08.40.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 24 Nov 2023 08:40:02 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) client-ip=2620:137:e000::3:6; Authentication-Results: mx.google.com; dkim=pass header.i=@linux.dev header.s=key1 header.b=cSL6VMmd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::3:6 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linux.dev Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by pete.vger.email (Postfix) with ESMTP id 0119B80C9A68; Fri, 24 Nov 2023 08:39:56 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at pete.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345799AbjKXQjp (ORCPT + 99 others); Fri, 24 Nov 2023 11:39:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37966 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232854AbjKXQj0 (ORCPT ); Fri, 24 Nov 2023 11:39:26 -0500 Received: from out-178.mta0.migadu.com (out-178.mta0.migadu.com [IPv6:2001:41d0:1004:224b::b2]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 829551FC0 for ; Fri, 24 Nov 2023 08:39:25 -0800 (PST) X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1700843964; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=HWENQVeTzgUlxGLBDIpOkaJ8YTyPuR19yc5enxAnFIw=; b=cSL6VMmd4lk4mO+zmOVocUKBEVY+XyRQeDv5LjrVzlqK796tHxXraC9PZN1dKNbkX/reza 37oHycqqkRI1ZZr+nQ3CgbvUk4Rbq8Yya7beEKXDUllghbvJMCkodoifVJ8gvT4ZqQGX+0 Se8p0n6aeKtgvy+fjnqX/lsHYSacobg= From: Sergei Shtepa 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 Subject: [PATCH v6 08/11] blksnap: event queue from the difference storage Date: Fri, 24 Nov 2023 17:38:33 +0100 Message-Id: <20231124163836.27256-9-sergei.shtepa@linux.dev> In-Reply-To: <20231124163836.27256-1-sergei.shtepa@linux.dev> References: <20231124163836.27256-1-sergei.shtepa@linux.dev> MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on pete.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (pete.vger.email [0.0.0.0]); Fri, 24 Nov 2023 08:39:56 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1783464201042185022 X-GMAIL-MSGID: 1783464201042185022 From: Sergei Shtepa 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 Signed-off-by: Christoph Hellwig Signed-off-by: Sergei Shtepa --- 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 +#include +#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 +#include +#include +#include +#include + +/** + * 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 */