vmbus: add infrastructure to save/load vmbus requests
This can be allow to include controller-specific data while saving/loading in-flight scsi requests of the vmbus scsi controller. Signed-off-by: Roman Kagan <rkagan@virtuozzo.com> Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com> Signed-off-by: Jon Doron <arilou@gmail.com> Message-Id: <20200424123444.3481728-7-arilou@gmail.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		@@ -1272,6 +1272,105 @@ void vmbus_free_req(void *req)
 | 
			
		||||
    g_free(req);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const VMStateDescription vmstate_sgent = {
 | 
			
		||||
    .name = "vmbus/sgentry",
 | 
			
		||||
    .version_id = 0,
 | 
			
		||||
    .minimum_version_id = 0,
 | 
			
		||||
    .fields = (VMStateField[]) {
 | 
			
		||||
        VMSTATE_UINT64(base, ScatterGatherEntry),
 | 
			
		||||
        VMSTATE_UINT64(len, ScatterGatherEntry),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct VMBusChanReqSave {
 | 
			
		||||
    uint16_t chan_idx;
 | 
			
		||||
    uint16_t pkt_type;
 | 
			
		||||
    uint32_t msglen;
 | 
			
		||||
    void *msg;
 | 
			
		||||
    uint64_t transaction_id;
 | 
			
		||||
    bool need_comp;
 | 
			
		||||
    uint32_t num;
 | 
			
		||||
    ScatterGatherEntry *sgl;
 | 
			
		||||
} VMBusChanReqSave;
 | 
			
		||||
 | 
			
		||||
static const VMStateDescription vmstate_vmbus_chan_req = {
 | 
			
		||||
    .name = "vmbus/vmbus_chan_req",
 | 
			
		||||
    .version_id = 0,
 | 
			
		||||
    .minimum_version_id = 0,
 | 
			
		||||
    .fields = (VMStateField[]) {
 | 
			
		||||
        VMSTATE_UINT16(chan_idx, VMBusChanReqSave),
 | 
			
		||||
        VMSTATE_UINT16(pkt_type, VMBusChanReqSave),
 | 
			
		||||
        VMSTATE_UINT32(msglen, VMBusChanReqSave),
 | 
			
		||||
        VMSTATE_VBUFFER_ALLOC_UINT32(msg, VMBusChanReqSave, 0, NULL, msglen),
 | 
			
		||||
        VMSTATE_UINT64(transaction_id, VMBusChanReqSave),
 | 
			
		||||
        VMSTATE_BOOL(need_comp, VMBusChanReqSave),
 | 
			
		||||
        VMSTATE_UINT32(num, VMBusChanReqSave),
 | 
			
		||||
        VMSTATE_STRUCT_VARRAY_POINTER_UINT32(sgl, VMBusChanReqSave, num,
 | 
			
		||||
                                             vmstate_sgent, ScatterGatherEntry),
 | 
			
		||||
        VMSTATE_END_OF_LIST()
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void vmbus_save_req(QEMUFile *f, VMBusChanReq *req)
 | 
			
		||||
{
 | 
			
		||||
    VMBusChanReqSave req_save;
 | 
			
		||||
 | 
			
		||||
    req_save.chan_idx = req->chan->subchan_idx;
 | 
			
		||||
    req_save.pkt_type = req->pkt_type;
 | 
			
		||||
    req_save.msglen = req->msglen;
 | 
			
		||||
    req_save.msg = req->msg;
 | 
			
		||||
    req_save.transaction_id = req->transaction_id;
 | 
			
		||||
    req_save.need_comp = req->need_comp;
 | 
			
		||||
    req_save.num = req->sgl.nsg;
 | 
			
		||||
    req_save.sgl = g_memdup(req->sgl.sg,
 | 
			
		||||
                            req_save.num * sizeof(ScatterGatherEntry));
 | 
			
		||||
 | 
			
		||||
    vmstate_save_state(f, &vmstate_vmbus_chan_req, &req_save, NULL);
 | 
			
		||||
 | 
			
		||||
    g_free(req_save.sgl);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size)
 | 
			
		||||
{
 | 
			
		||||
    VMBusChanReqSave req_save;
 | 
			
		||||
    VMBusChanReq *req = NULL;
 | 
			
		||||
    VMBusChannel *chan = NULL;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
 | 
			
		||||
    vmstate_load_state(f, &vmstate_vmbus_chan_req, &req_save, 0);
 | 
			
		||||
 | 
			
		||||
    if (req_save.chan_idx >= dev->num_channels) {
 | 
			
		||||
        error_report("%s: %u(chan_idx) > %u(num_channels)", __func__,
 | 
			
		||||
                     req_save.chan_idx, dev->num_channels);
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
    chan = &dev->channels[req_save.chan_idx];
 | 
			
		||||
 | 
			
		||||
    if (vmbus_channel_reserve(chan, 0, req_save.msglen)) {
 | 
			
		||||
        goto out;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    req = vmbus_alloc_req(chan, size, req_save.pkt_type, req_save.msglen,
 | 
			
		||||
                          req_save.transaction_id, req_save.need_comp);
 | 
			
		||||
    if (req_save.msglen) {
 | 
			
		||||
        memcpy(req->msg, req_save.msg, req_save.msglen);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < req_save.num; i++) {
 | 
			
		||||
        qemu_sglist_add(&req->sgl, req_save.sgl[i].base, req_save.sgl[i].len);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
out:
 | 
			
		||||
    if (req_save.msglen) {
 | 
			
		||||
        g_free(req_save.msg);
 | 
			
		||||
    }
 | 
			
		||||
    if (req_save.num) {
 | 
			
		||||
        g_free(req_save.sgl);
 | 
			
		||||
    }
 | 
			
		||||
    return req;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void channel_event_cb(EventNotifier *e)
 | 
			
		||||
{
 | 
			
		||||
    VMBusChannel *chan = container_of(e, VMBusChannel, notifier);
 | 
			
		||||
 
 | 
			
		||||
@@ -224,4 +224,7 @@ int vmbus_map_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
 | 
			
		||||
void vmbus_unmap_sgl(VMBusChanReq *req, DMADirection dir, struct iovec *iov,
 | 
			
		||||
                     unsigned iov_cnt, size_t accessed);
 | 
			
		||||
 | 
			
		||||
void vmbus_save_req(QEMUFile *f, VMBusChanReq *req);
 | 
			
		||||
void *vmbus_load_req(QEMUFile *f, VMBusDevice *dev, uint32_t size);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user