From 656dc9db887fbf9624ca9123f3c08f96841a1c20 Mon Sep 17 00:00:00 2001 From: Mark Syms Date: Thu, 23 Nov 2023 11:07:53 +0000 Subject: [PATCH] CP-46757: advertise feature-flush-cache Windows guests do not request BLKIF_OP_WRITE_BARRIER and only support BLKIF_OP_FLUSH_DISKCACHE, so advertise and support that to allow for explicit cache and data integrity management. Signed-off-by: Mark Syms --- drivers/td-ctx.c | 10 ++++++---- drivers/td-req.c | 10 +++++++--- tapback/frontend.c | 7 +++++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/td-ctx.c b/drivers/td-ctx.c index a1da30f6..7706c468 100644 --- a/drivers/td-ctx.c +++ b/drivers/td-ctx.c @@ -230,7 +230,8 @@ __xenio_blkif_get_requests(struct td_xenblkif * const blkif, xenio_blkif_get_request(blkif, dst, rc); - if (unlikely(dst->operation == BLKIF_OP_WRITE_BARRIER)) + if (unlikely(dst->operation == BLKIF_OP_WRITE_BARRIER || + dst->operation == BLKIF_OP_FLUSH_DISKCACHE)) barrier = true; } @@ -278,7 +279,8 @@ xenio_blkif_get_requests(struct td_xenblkif * const blkif, n += __xenio_blkif_get_requests(blkif, reqs + n, count - n); - if (unlikely(n && reqs[(n - 1)]->operation == BLKIF_OP_WRITE_BARRIER)) + if (unlikely(n && (reqs[(n - 1)]->operation == BLKIF_OP_WRITE_BARRIER || + reqs[(n - 1)]->operation == BLKIF_OP_FLUSH_DISKCACHE))) break; } while (1); @@ -327,8 +329,8 @@ tapdisk_xenio_ctx_process_ring(struct td_xenblkif *blkif, limit -= n_reqs; final = 1; - if (unlikely(reqs[(n_reqs - 1)]->operation == - BLKIF_OP_WRITE_BARRIER)) { + if (unlikely(reqs[(n_reqs - 1)]->operation == BLKIF_OP_WRITE_BARRIER || + reqs[(n_reqs - 1)]->operation == BLKIF_OP_FLUSH_DISKCACHE)) { ASSERT(!blkif->barrier.msg); blkif->barrier.msg = reqs[(n_reqs - 1)]; blkif->barrier.io_done = false; diff --git a/drivers/td-req.c b/drivers/td-req.c index ce176354..1ae4befc 100644 --- a/drivers/td-req.c +++ b/drivers/td-req.c @@ -467,8 +467,9 @@ tapdisk_xenblkif_complete_request(struct td_xenblkif * const blkif, depth++; - processing_barrier_message = - tapreq->msg.operation == BLKIF_OP_WRITE_BARRIER; + processing_barrier_message = ( + tapreq->msg.operation == BLKIF_OP_WRITE_BARRIER || + tapreq->msg.operation == BLKIF_OP_FLUSH_DISKCACHE); /* * If a barrier request completes, check whether it's an I/O completion @@ -770,6 +771,8 @@ tapdisk_xenblkif_make_vbd_request(struct td_xenblkif * const blkif, tapreq->prot = PROT_READ; vreq->op = TD_OP_WRITE; break; + case BLKIF_OP_FLUSH_DISKCACHE: + break; default: RING_ERR(blkif, "req %lu: invalid request type %d\n", tapreq->msg.id, tapreq->msg.operation); @@ -783,7 +786,8 @@ tapdisk_xenblkif_make_vbd_request(struct td_xenblkif * const blkif, * Check that the number of segments is sane. */ if (unlikely((tapreq->msg.nr_segments == 0 && - tapreq->msg.operation != BLKIF_OP_WRITE_BARRIER) || + (tapreq->msg.operation != BLKIF_OP_WRITE_BARRIER && + tapreq->msg.operation != BLKIF_OP_FLUSH_DISKCACHE)) || tapreq->msg.nr_segments > BLKIF_MMAX_SEGMENTS_PER_REQUEST)) { RING_ERR(blkif, "req %lu: bad number of segments in request (%d)\n", tapreq->msg.id, tapreq->msg.nr_segments); diff --git a/tapback/frontend.c b/tapback/frontend.c index e086813e..3c88c0d2 100644 --- a/tapback/frontend.c +++ b/tapback/frontend.c @@ -300,6 +300,13 @@ connect_frontend(vbd_t *device) { break; } + /* this may need to conditional as above */ + if ((err = tapback_device_printf(device, xst, "feature-flush-cache", true, + "%d", 1))) { + WARN(device, "failed to write feature-flush-cache: %s\n", strerror(-err)); + break; + } + if ((err = tapback_device_printf(device, xst, "sector-size", true, "%u", device->sector_size))) { WARN(device, "failed to write sector-size: %s\n", strerror(-err));