block/write-threshold: don't use write notifiers

write-notifiers are used only for write-threshold. New code for such
purpose should create filters.

Let's better special-case write-threshold and drop write notifiers at
all. (Actually, write-threshold is special-cased anyway, as the only
user of write-notifiers)

So, create a new direct interface for bdrv_co_write_req_prepare() and
drop all write-notifier related logic from write-threshold.c.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20210506090621.11848-2-vsementsov@virtuozzo.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[mreitz: Adjusted comment as per Eric's suggestion]
Signed-off-by: Max Reitz <mreitz@redhat.com>
master
Vladimir Sementsov-Ogievskiy 2021-05-06 12:06:14 +03:00 committed by Max Reitz
parent ac4e14f5dc
commit 94783301b8
4 changed files with 27 additions and 58 deletions

View File

@ -30,6 +30,7 @@
#include "block/blockjob_int.h"
#include "block/block_int.h"
#include "block/coroutines.h"
#include "block/write-threshold.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
@ -2008,8 +2009,8 @@ bdrv_co_write_req_prepare(BdrvChild *child, int64_t offset, int64_t bytes,
} else {
assert(child->perm & BLK_PERM_WRITE);
}
return notifier_with_return_list_notify(&bs->before_write_notifiers,
req);
bdrv_write_threshold_check_write(bs, offset, bytes);
return 0;
case BDRV_TRACKED_TRUNCATE:
assert(child->perm & BLK_PERM_RESIZE);
return 0;

View File

@ -29,14 +29,6 @@ bool bdrv_write_threshold_is_set(const BlockDriverState *bs)
return bs->write_threshold_offset > 0;
}
static void write_threshold_disable(BlockDriverState *bs)
{
if (bdrv_write_threshold_is_set(bs)) {
notifier_with_return_remove(&bs->write_threshold_notifier);
bs->write_threshold_offset = 0;
}
}
uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
const BdrvTrackedRequest *req)
{
@ -51,55 +43,9 @@ uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
return 0;
}
static int coroutine_fn before_write_notify(NotifierWithReturn *notifier,
void *opaque)
{
BdrvTrackedRequest *req = opaque;
BlockDriverState *bs = req->bs;
uint64_t amount = 0;
amount = bdrv_write_threshold_exceeded(bs, req);
if (amount > 0) {
qapi_event_send_block_write_threshold(
bs->node_name,
amount,
bs->write_threshold_offset);
/* autodisable to avoid flooding the monitor */
write_threshold_disable(bs);
}
return 0; /* should always let other notifiers run */
}
static void write_threshold_register_notifier(BlockDriverState *bs)
{
bs->write_threshold_notifier.notify = before_write_notify;
bdrv_add_before_write_notifier(bs, &bs->write_threshold_notifier);
}
static void write_threshold_update(BlockDriverState *bs,
int64_t threshold_bytes)
{
bs->write_threshold_offset = threshold_bytes;
}
void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes)
{
if (bdrv_write_threshold_is_set(bs)) {
if (threshold_bytes > 0) {
write_threshold_update(bs, threshold_bytes);
} else {
write_threshold_disable(bs);
}
} else {
if (threshold_bytes > 0) {
/* avoid multiple registration */
write_threshold_register_notifier(bs);
write_threshold_update(bs, threshold_bytes);
}
/* discard bogus disable request */
}
bs->write_threshold_offset = threshold_bytes;
}
void qmp_block_set_write_threshold(const char *node_name,
@ -122,3 +68,17 @@ void qmp_block_set_write_threshold(const char *node_name,
aio_context_release(aio_context);
}
void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset,
int64_t bytes)
{
int64_t end = offset + bytes;
uint64_t wtr = bs->write_threshold_offset;
if (wtr > 0 && end > wtr) {
qapi_event_send_block_write_threshold(bs->node_name, end - wtr, wtr);
/* autodisable to avoid flooding the monitor */
bdrv_write_threshold_set(bs, 0);
}
}

View File

@ -959,7 +959,6 @@ struct BlockDriverState {
/* threshold limit for writes, in bytes. "High water mark". */
uint64_t write_threshold_offset;
NotifierWithReturn write_threshold_notifier;
/* Writing to the list requires the BQL _and_ the dirty_bitmap_mutex.
* Reading from the list can be done with either the BQL or the

View File

@ -59,4 +59,13 @@ bool bdrv_write_threshold_is_set(const BlockDriverState *bs);
uint64_t bdrv_write_threshold_exceeded(const BlockDriverState *bs,
const BdrvTrackedRequest *req);
/*
* bdrv_write_threshold_check_write
*
* Check whether the specified request exceeds the write threshold.
* If so, send a corresponding event and disable write threshold checking.
*/
void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset,
int64_t bytes);
#endif