mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-05 00:33:55 -06:00
This update brings dataplane to virtio-scsi (NOT
yet 100% thread-safe, though, which makes it really, really experimental. It also brings asynchronous cancellation to the SCSI subsystem and implements it in virtio-scsi. This is a pretty important feature. Almost all the work here was done by Fam Zheng. I also included the virtio refcount fixes from Gonglei, because they had a small conflict with virtio-scsi dataplane. This pull request is using the new subkey 4E6B09D7. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQEcBAABAgAGBQJUKpR2AAoJEBRUblpOawnXNLAH/RBeF66ZqWc29dl78JKEbv0+ C5pL61GhlI5vFIjSbPU3/iaZQifw3E4NLvX3SCN5ImsLzBw4r3qerapP2Ut96K/j 5CYdWTF1oqE32oCefvlWhJulHmE1vxGN53BvOz3HHxoehdF1/tJ0wUoZyfztGTOF tiW85VMewi6CKm47/ns5tSNfGMVzWHqnUg67z/mwN6ZmPFU1dXBlgmiIv8Znahrn B1AOAeMjWaKvOS+tiYNVG6k0GENWGoiypxiTR3ZXLQKxOYdkh/X0ARULqLMonASX YsT772nzO9KZDIsdLj9QZZmM7vxs7UhW0MgQlvcSWP9vfZa5SeuRSgoXorPDj3Q= =54T3 -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging This update brings dataplane to virtio-scsi (NOT yet 100% thread-safe, though, which makes it really, really experimental. It also brings asynchronous cancellation to the SCSI subsystem and implements it in virtio-scsi. This is a pretty important feature. Almost all the work here was done by Fam Zheng. I also included the virtio refcount fixes from Gonglei, because they had a small conflict with virtio-scsi dataplane. This pull request is using the new subkey 4E6B09D7. # gpg: Signature made Tue 30 Sep 2014 12:31:02 BST using RSA key ID 4E6B09D7 # gpg: Good signature from "Paolo Bonzini <pbonzini@redhat.com>" # gpg: aka "Paolo Bonzini <bonzini@gnu.org>" * remotes/bonzini/tags/for-upstream: (39 commits) block/iscsi: handle failure on malloc of the allocationmap util: introduce bitmap_try_new virtio-scsi: Handle TMF request cancellation asynchronously scsi: Introduce scsi_req_cancel_async scsi: Introduce scsi_req_cancel_complete scsi: Drop SCSIReqOps.cancel_io scsi: Unify request unref in scsi_req_cancel scsi-generic: Handle canceled request in scsi_command_complete scsi: Drop scsi_req_abort virtio-scsi: Process ".iothread" property virtio-scsi: Call bdrv_io_plug/bdrv_io_unplug in cmd request handling virtio-scsi: Batched prepare for cmd reqs virtio-scsi: Two stages processing of cmd request virtio-scsi: Add migration state notifier for dataplane code virtio-scsi: Hook up with dataplane virtio-scsi-dataplane: Code to run virtio-scsi on iothread virtio-scsi: Add VirtIOSCSIVring in VirtIOSCSIReq virtio-scsi: Add 'iothread' property to virtio-scsi virtio: add a wrapper for virtio-backend initialization virtio-9p: fix virtio-9p child refcount in transports ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
1831e15060
17 changed files with 765 additions and 304 deletions
|
@ -5,6 +5,7 @@
|
|||
#include "block/block.h"
|
||||
#include "hw/block/block.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
#include "qemu/notify.h"
|
||||
|
||||
#define MAX_SCSI_DEVS 255
|
||||
|
||||
|
@ -50,17 +51,25 @@ struct SCSIRequest {
|
|||
uint32_t tag;
|
||||
uint32_t lun;
|
||||
uint32_t status;
|
||||
void *hba_private;
|
||||
size_t resid;
|
||||
SCSICommand cmd;
|
||||
NotifierList cancel_notifiers;
|
||||
|
||||
/* Note:
|
||||
* - fields before sense are initialized by scsi_req_alloc;
|
||||
* - sense[] is uninitialized;
|
||||
* - fields after sense are memset to 0 by scsi_req_alloc.
|
||||
* */
|
||||
|
||||
uint8_t sense[SCSI_SENSE_BUF_SIZE];
|
||||
uint32_t sense_len;
|
||||
bool enqueued;
|
||||
bool io_canceled;
|
||||
bool retry;
|
||||
bool dma_started;
|
||||
BlockDriverAIOCB *aiocb;
|
||||
QEMUSGList *sg;
|
||||
bool dma_started;
|
||||
uint8_t sense[SCSI_SENSE_BUF_SIZE];
|
||||
uint32_t sense_len;
|
||||
bool enqueued;
|
||||
bool io_canceled;
|
||||
bool retry;
|
||||
void *hba_private;
|
||||
QTAILQ_ENTRY(SCSIRequest) next;
|
||||
};
|
||||
|
||||
|
@ -123,7 +132,6 @@ struct SCSIReqOps {
|
|||
int32_t (*send_command)(SCSIRequest *req, uint8_t *buf);
|
||||
void (*read_data)(SCSIRequest *req);
|
||||
void (*write_data)(SCSIRequest *req);
|
||||
void (*cancel_io)(SCSIRequest *req);
|
||||
uint8_t *(*get_buf)(SCSIRequest *req);
|
||||
|
||||
void (*save_request)(QEMUFile *f, SCSIRequest *req);
|
||||
|
@ -258,8 +266,9 @@ void scsi_req_data(SCSIRequest *req, int len);
|
|||
void scsi_req_complete(SCSIRequest *req, int status);
|
||||
uint8_t *scsi_req_get_buf(SCSIRequest *req);
|
||||
int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len);
|
||||
void scsi_req_abort(SCSIRequest *req, int status);
|
||||
void scsi_req_cancel_complete(SCSIRequest *req);
|
||||
void scsi_req_cancel(SCSIRequest *req);
|
||||
void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier);
|
||||
void scsi_req_retry(SCSIRequest *req);
|
||||
void scsi_device_purge_requests(SCSIDevice *sdev, SCSISense sense);
|
||||
void scsi_device_set_ua(SCSIDevice *sdev, SCSISense sense);
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
#include "hw/virtio/virtio.h"
|
||||
#include "hw/pci/pci.h"
|
||||
#include "hw/scsi/scsi.h"
|
||||
#include "sysemu/iothread.h"
|
||||
#include "hw/virtio/dataplane/vring.h"
|
||||
|
||||
#define TYPE_VIRTIO_SCSI_COMMON "virtio-scsi-common"
|
||||
#define VIRTIO_SCSI_COMMON(obj) \
|
||||
|
@ -151,8 +153,18 @@ struct VirtIOSCSIConf {
|
|||
uint32_t cmd_per_lun;
|
||||
char *vhostfd;
|
||||
char *wwpn;
|
||||
IOThread *iothread;
|
||||
};
|
||||
|
||||
struct VirtIOSCSI;
|
||||
|
||||
typedef struct {
|
||||
struct VirtIOSCSI *parent;
|
||||
Vring vring;
|
||||
EventNotifier host_notifier;
|
||||
EventNotifier guest_notifier;
|
||||
} VirtIOSCSIVring;
|
||||
|
||||
typedef struct VirtIOSCSICommon {
|
||||
VirtIODevice parent_obj;
|
||||
VirtIOSCSIConf conf;
|
||||
|
@ -164,14 +176,74 @@ typedef struct VirtIOSCSICommon {
|
|||
VirtQueue **cmd_vqs;
|
||||
} VirtIOSCSICommon;
|
||||
|
||||
typedef struct {
|
||||
typedef struct VirtIOSCSI {
|
||||
VirtIOSCSICommon parent_obj;
|
||||
|
||||
SCSIBus bus;
|
||||
int resetting;
|
||||
bool events_dropped;
|
||||
|
||||
/* Fields for dataplane below */
|
||||
AioContext *ctx; /* one iothread per virtio-scsi-pci for now */
|
||||
|
||||
/* Vring is used instead of vq in dataplane code, because of the underlying
|
||||
* memory layer thread safety */
|
||||
VirtIOSCSIVring *ctrl_vring;
|
||||
VirtIOSCSIVring *event_vring;
|
||||
VirtIOSCSIVring **cmd_vrings;
|
||||
bool dataplane_started;
|
||||
bool dataplane_starting;
|
||||
bool dataplane_stopping;
|
||||
bool dataplane_disabled;
|
||||
Notifier migration_state_notifier;
|
||||
} VirtIOSCSI;
|
||||
|
||||
typedef struct VirtIOSCSIReq {
|
||||
VirtIOSCSI *dev;
|
||||
VirtQueue *vq;
|
||||
QEMUSGList qsgl;
|
||||
QEMUIOVector resp_iov;
|
||||
|
||||
/* Note:
|
||||
* - fields before elem are initialized by virtio_scsi_init_req;
|
||||
* - elem is uninitialized at the time of allocation.
|
||||
* - fields after elem are zeroed by virtio_scsi_init_req.
|
||||
* */
|
||||
|
||||
VirtQueueElement elem;
|
||||
/* Set by dataplane code. */
|
||||
VirtIOSCSIVring *vring;
|
||||
|
||||
union {
|
||||
/* Used for two-stage request submission */
|
||||
QTAILQ_ENTRY(VirtIOSCSIReq) next;
|
||||
|
||||
/* Used for cancellation of request during TMFs */
|
||||
int remaining;
|
||||
};
|
||||
|
||||
SCSIRequest *sreq;
|
||||
size_t resp_size;
|
||||
enum SCSIXferMode mode;
|
||||
union {
|
||||
VirtIOSCSICmdResp cmd;
|
||||
VirtIOSCSICtrlTMFResp tmf;
|
||||
VirtIOSCSICtrlANResp an;
|
||||
VirtIOSCSIEvent event;
|
||||
} resp;
|
||||
union {
|
||||
struct {
|
||||
VirtIOSCSICmdReq cmd;
|
||||
uint8_t cdb[];
|
||||
} QEMU_PACKED;
|
||||
VirtIOSCSICtrlTMFReq tmf;
|
||||
VirtIOSCSICtrlANReq an;
|
||||
} req;
|
||||
} VirtIOSCSIReq;
|
||||
|
||||
QEMU_BUILD_BUG_ON(offsetof(VirtIOSCSIReq, req.cdb) !=
|
||||
offsetof(VirtIOSCSIReq, req.cmd) + sizeof(VirtIOSCSICmdReq));
|
||||
|
||||
#define DEFINE_VIRTIO_SCSI_PROPERTIES(_state, _conf_field) \
|
||||
DEFINE_PROP_UINT32("num_queues", _state, _conf_field.num_queues, 1), \
|
||||
DEFINE_PROP_UINT32("max_sectors", _state, _conf_field.max_sectors, 0xFFFF),\
|
||||
|
@ -192,5 +264,19 @@ void virtio_scsi_common_realize(DeviceState *dev, Error **errp,
|
|||
HandleOutput cmd);
|
||||
|
||||
void virtio_scsi_common_unrealize(DeviceState *dev, Error **errp);
|
||||
void virtio_scsi_handle_ctrl_req(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
bool virtio_scsi_handle_cmd_req_prepare(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
void virtio_scsi_handle_cmd_req_submit(VirtIOSCSI *s, VirtIOSCSIReq *req);
|
||||
VirtIOSCSIReq *virtio_scsi_init_req(VirtIOSCSI *s, VirtQueue *vq);
|
||||
void virtio_scsi_free_req(VirtIOSCSIReq *req);
|
||||
void virtio_scsi_push_event(VirtIOSCSI *s, SCSIDevice *dev,
|
||||
uint32_t event, uint32_t reason);
|
||||
|
||||
void virtio_scsi_set_iothread(VirtIOSCSI *s, IOThread *iothread);
|
||||
void virtio_scsi_dataplane_start(VirtIOSCSI *s);
|
||||
void virtio_scsi_dataplane_stop(VirtIOSCSI *s);
|
||||
void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req);
|
||||
VirtIOSCSIReq *virtio_scsi_pop_req_vring(VirtIOSCSI *s,
|
||||
VirtIOSCSIVring *vring);
|
||||
|
||||
#endif /* _QEMU_VIRTIO_SCSI_H */
|
||||
|
|
|
@ -161,6 +161,9 @@ typedef struct VirtioDeviceClass {
|
|||
int (*load)(VirtIODevice *vdev, QEMUFile *f, int version_id);
|
||||
} VirtioDeviceClass;
|
||||
|
||||
void virtio_instance_init_common(Object *proxy_obj, void *data,
|
||||
size_t vdev_size, const char *vdev_name);
|
||||
|
||||
void virtio_init(VirtIODevice *vdev, const char *name,
|
||||
uint16_t device_id, size_t config_size);
|
||||
void virtio_cleanup(VirtIODevice *vdev);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue