1e2462113SFrancesco Romani /* 2e2462113SFrancesco Romani * QEMU System Emulator block write threshold notification 3e2462113SFrancesco Romani * 4e2462113SFrancesco Romani * Copyright Red Hat, Inc. 2014 5e2462113SFrancesco Romani * 6e2462113SFrancesco Romani * Authors: 7e2462113SFrancesco Romani * Francesco Romani <fromani@redhat.com> 8e2462113SFrancesco Romani * 9e2462113SFrancesco Romani * This work is licensed under the terms of the GNU LGPL, version 2 or later. 10e2462113SFrancesco Romani * See the COPYING.LIB file in the top-level directory. 11e2462113SFrancesco Romani */ 12e2462113SFrancesco Romani 1380c71a24SPeter Maydell #include "qemu/osdep.h" 14e2c1c34fSMarkus Armbruster #include "block/block-io.h" 15e2462113SFrancesco Romani #include "block/block_int.h" 16e2462113SFrancesco Romani #include "block/write-threshold.h" 17e688df6bSMarkus Armbruster #include "qapi/error.h" 189af23989SMarkus Armbruster #include "qapi/qapi-commands-block-core.h" 199af23989SMarkus Armbruster #include "qapi/qapi-events-block-core.h" 20e2462113SFrancesco Romani 21e2462113SFrancesco Romani uint64_t bdrv_write_threshold_get(const BlockDriverState *bs) 22e2462113SFrancesco Romani { 23e2462113SFrancesco Romani return bs->write_threshold_offset; 24e2462113SFrancesco Romani } 25e2462113SFrancesco Romani 26e2462113SFrancesco Romani void bdrv_write_threshold_set(BlockDriverState *bs, uint64_t threshold_bytes) 27e2462113SFrancesco Romani { 2894783301SVladimir Sementsov-Ogievskiy bs->write_threshold_offset = threshold_bytes; 29e2462113SFrancesco Romani } 30e2462113SFrancesco Romani 31e2462113SFrancesco Romani void qmp_block_set_write_threshold(const char *node_name, 32e2462113SFrancesco Romani uint64_t threshold_bytes, 33e2462113SFrancesco Romani Error **errp) 34e2462113SFrancesco Romani { 35e2462113SFrancesco Romani BlockDriverState *bs; 36e2462113SFrancesco Romani AioContext *aio_context; 37e2462113SFrancesco Romani 38e2462113SFrancesco Romani bs = bdrv_find_node(node_name); 39e2462113SFrancesco Romani if (!bs) { 406ec46ad5SMarkus Armbruster error_setg(errp, "Device '%s' not found", node_name); 41e2462113SFrancesco Romani return; 42e2462113SFrancesco Romani } 43e2462113SFrancesco Romani 44e2462113SFrancesco Romani aio_context = bdrv_get_aio_context(bs); 45e2462113SFrancesco Romani aio_context_acquire(aio_context); 46e2462113SFrancesco Romani 47e2462113SFrancesco Romani bdrv_write_threshold_set(bs, threshold_bytes); 48e2462113SFrancesco Romani 49e2462113SFrancesco Romani aio_context_release(aio_context); 50e2462113SFrancesco Romani } 5194783301SVladimir Sementsov-Ogievskiy 5294783301SVladimir Sementsov-Ogievskiy void bdrv_write_threshold_check_write(BlockDriverState *bs, int64_t offset, 5394783301SVladimir Sementsov-Ogievskiy int64_t bytes) 5494783301SVladimir Sementsov-Ogievskiy { 5594783301SVladimir Sementsov-Ogievskiy int64_t end = offset + bytes; 5694783301SVladimir Sementsov-Ogievskiy uint64_t wtr = bs->write_threshold_offset; 5794783301SVladimir Sementsov-Ogievskiy 5894783301SVladimir Sementsov-Ogievskiy if (wtr > 0 && end > wtr) { 5994783301SVladimir Sementsov-Ogievskiy qapi_event_send_block_write_threshold(bs->node_name, end - wtr, wtr); 6094783301SVladimir Sementsov-Ogievskiy 6194783301SVladimir Sementsov-Ogievskiy /* autodisable to avoid flooding the monitor */ 6294783301SVladimir Sementsov-Ogievskiy bdrv_write_threshold_set(bs, 0); 6394783301SVladimir Sementsov-Ogievskiy } 6494783301SVladimir Sementsov-Ogievskiy } 65