Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Emulated devices and other BlockBackend users wishing to take advantage of blk_register_buf() all have the same repetitive job: register RAMBlocks with the BlockBackend using RAMBlockNotifier. Add a BlockRAMRegistrar API to do this. A later commit will use this from hw/block/virtio-blk.c. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Stefano Garzarella <sgarzare@redhat.com> Message-id: 20221013185908.1297568-10-stefanha@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
- Loading branch information
1 parent
4fdd0a1
commit 7f9241d
Showing
4 changed files
with
97 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* BlockBackend RAM Registrar | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
||
#include "qemu/osdep.h" | ||
#include "sysemu/block-backend.h" | ||
#include "sysemu/block-ram-registrar.h" | ||
#include "qapi/error.h" | ||
|
||
static void ram_block_added(RAMBlockNotifier *n, void *host, size_t size, | ||
size_t max_size) | ||
{ | ||
BlockRAMRegistrar *r = container_of(n, BlockRAMRegistrar, notifier); | ||
Error *err = NULL; | ||
|
||
if (!r->ok) { | ||
return; /* don't try again if we've already failed */ | ||
} | ||
|
||
if (!blk_register_buf(r->blk, host, max_size, &err)) { | ||
error_report_err(err); | ||
ram_block_notifier_remove(&r->notifier); | ||
r->ok = false; | ||
} | ||
} | ||
|
||
static void ram_block_removed(RAMBlockNotifier *n, void *host, size_t size, | ||
size_t max_size) | ||
{ | ||
BlockRAMRegistrar *r = container_of(n, BlockRAMRegistrar, notifier); | ||
blk_unregister_buf(r->blk, host, max_size); | ||
} | ||
|
||
void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk) | ||
{ | ||
r->blk = blk; | ||
r->notifier = (RAMBlockNotifier){ | ||
.ram_block_added = ram_block_added, | ||
.ram_block_removed = ram_block_removed, | ||
|
||
/* | ||
* .ram_block_resized() is not necessary because we use the max_size | ||
* value that does not change across resize. | ||
*/ | ||
}; | ||
r->ok = true; | ||
|
||
ram_block_notifier_add(&r->notifier); | ||
} | ||
|
||
void blk_ram_registrar_destroy(BlockRAMRegistrar *r) | ||
{ | ||
if (r->ok) { | ||
ram_block_notifier_remove(&r->notifier); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* | ||
* BlockBackend RAM Registrar | ||
* | ||
* SPDX-License-Identifier: GPL-2.0-or-later | ||
*/ | ||
|
||
#ifndef BLOCK_RAM_REGISTRAR_H | ||
#define BLOCK_RAM_REGISTRAR_H | ||
|
||
#include "exec/ramlist.h" | ||
|
||
/** | ||
* struct BlockRAMRegistrar: | ||
* | ||
* Keeps RAMBlock memory registered with a BlockBackend using | ||
* blk_register_buf() including hotplugged memory. | ||
* | ||
* Emulated devices or other BlockBackend users initialize a BlockRAMRegistrar | ||
* with blk_ram_registrar_init() before submitting I/O requests with the | ||
* BDRV_REQ_REGISTERED_BUF flag set. | ||
*/ | ||
typedef struct { | ||
BlockBackend *blk; | ||
RAMBlockNotifier notifier; | ||
bool ok; | ||
} BlockRAMRegistrar; | ||
|
||
void blk_ram_registrar_init(BlockRAMRegistrar *r, BlockBackend *blk); | ||
void blk_ram_registrar_destroy(BlockRAMRegistrar *r); | ||
|
||
/* Have all RAMBlocks been registered successfully? */ | ||
static inline bool blk_ram_registrar_ok(BlockRAMRegistrar *r) | ||
{ | ||
return r->ok; | ||
} | ||
|
||
#endif /* BLOCK_RAM_REGISTRAR_H */ |