Jan Beulich
2012-Dec-04 10:10 UTC
Ping: [PATCH] vscsiif: allow larger segments-per-request values
Does silence here imply agreement? Jan>>> On 27.11.12 at 12:37, Jan Beulich wrote: > At least certain tape devices require fixed size blocks to be operated > upon, i.e. breaking up of I/O requests is not permitted. Consequently > we need an interface extension that (leaving aside implementation > limitations) doesn''t impose a limit on the number of segments that can > be associated with an individual request. > > This, in turn, excludes the blkif extension FreeBSD folks implemented, > as that still imposes an upper limit (the actual I/O request still > specifies the full number of segments - as an 8-bit quantity -, and > subsequent ring slots get used to carry the excess segment > descriptors). > > The alternative therefore is to allow the frontend to pre-set segment > descriptors _before_ actually issuing the I/O request. I/O will then > be done by the backend for the accumulated set of segments. > > To properly associate segment preset operations with the main request, > the rqid-s between them should match (originally I had hoped to use > this to avoid producing individual responses for the pre-set > operations, but that turned out to violate the underlying shared ring > implementation). > > Negotiation of the maximum number of segments a particular backend > implementation supports happens through a new "segs-per-req" xenstore > node. > > Signed-off-by: Jan Beulich <jbeulich@suse.com> > --- > As I have no plans to backport this to the 2.6.18 tree, I''m attaching > for reference the full kernel side patch we''re intending to use. > > --- a/xen/include/public/io/vscsiif.h > +++ b/xen/include/public/io/vscsiif.h > @@ -34,6 +34,7 @@ > #define VSCSIIF_ACT_SCSI_CDB 1 /* SCSI CDB command */ > #define VSCSIIF_ACT_SCSI_ABORT 2 /* SCSI Device(Lun) Abort*/ > #define VSCSIIF_ACT_SCSI_RESET 3 /* SCSI Device(Lun) Reset*/ > +#define VSCSIIF_ACT_SCSI_SG_PRESET 4 /* Preset SG elements */ > > /* > * Maximum scatter/gather segments per request. > @@ -50,6 +51,12 @@ > #define VSCSIIF_MAX_COMMAND_SIZE 16 > #define VSCSIIF_SENSE_BUFFERSIZE 96 > > +struct scsiif_request_segment { > + grant_ref_t gref; > + uint16_t offset; > + uint16_t length; > +}; > +typedef struct scsiif_request_segment vscsiif_segment_t; > > struct vscsiif_request { > uint16_t rqid; /* private guest value, echoed in resp */ > @@ -66,18 +73,26 @@ struct vscsiif_request { > DMA_NONE(3) requests */ > uint8_t nr_segments; /* Number of pieces of scatter-gather > */ > > - struct scsiif_request_segment { > - grant_ref_t gref; > - uint16_t offset; > - uint16_t length; > - } seg[VSCSIIF_SG_TABLESIZE]; > + vscsiif_segment_t seg[VSCSIIF_SG_TABLESIZE]; > uint32_t reserved[3]; > }; > typedef struct vscsiif_request vscsiif_request_t; > > +#define VSCSIIF_SG_LIST_SIZE ((sizeof(vscsiif_request_t) - 4) \ > + / sizeof(vscsiif_segment_t)) > + > +struct vscsiif_sg_list { > + /* First two fields must match struct vscsiif_request! */ > + uint16_t rqid; /* private guest value, must match main req */ > + uint8_t act; /* VSCSIIF_ACT_SCSI_SG_PRESET */ > + uint8_t nr_segments; /* Number of pieces of scatter-gather */ > + vscsiif_segment_t seg[VSCSIIF_SG_LIST_SIZE]; > +}; > +typedef struct vscsiif_sg_list vscsiif_sg_list_t; > + > struct vscsiif_response { > uint16_t rqid; > - uint8_t padding; > + uint8_t act; /* valid only when backend supports > SG_PRESET */ > uint8_t sense_len; > uint8_t sense_buffer[VSCSIIF_SENSE_BUFFERSIZE]; > int32_t rslt; > > >