]> xenbits.xensource.com Git - people/vhanquez/xen.git/commitdiff
blkif.h: Define and document the request number/size/segments extension
authorJustin T. Gibbs <justing@spectralogic.com>
Thu, 23 Feb 2012 10:03:07 +0000 (10:03 +0000)
committerJustin T. Gibbs <justing@spectralogic.com>
Thu, 23 Feb 2012 10:03:07 +0000 (10:03 +0000)
Note: As of __XEN_INTERFACE_VERSION__ 0x00040201 the definition of
      BLKIF_MAX_SEGMENTS_PER_REQUEST has changed.  Drivers must be
      updated to, at minimum, use BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK,
      before being recompiled with a __XEN_INTERFACE_VERSION greater
      than or equal to this value.

This extension first appeared in the FreeBSD Operating System.

Signed-off-by: Justin T. Gibbs <justing@spectralogic.com>
Committed-by: Keir Fraser <keir@xen.org>
xen/include/public/io/blkif.h
xen/include/public/xen-compat.h

index d71c7f1699641a8818b39cc4ee1ca7a19ac89f41..4f1fc8669934551c3899aab723d6d3b24d1f3138 100644 (file)
  *      The maximum supported size of the request ring buffer in units of
  *      machine pages.  The value must be a power of 2.
  *
+ * max-requests         <uint32_t>
+ *      Default Value:  BLKIF_MAX_RING_REQUESTS(PAGE_SIZE)
+ *      Maximum Value:  BLKIF_MAX_RING_REQUESTS(PAGE_SIZE * max-ring-pages)
+ *
+ *      The maximum number of concurrent, logical requests that will be
+ *      issued by the backend.
+ *
+ *      Note: A logical request may span multiple ring entries.
+ *
+ * max-request-segments
+ *      Values:         <uint8_t>
+ *      Default Value:  BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK
+ *      Maximum Value:  BLKIF_MAX_SEGMENTS_PER_REQUEST
+ *
+ *      The maximum value of blkif_request.nr_segments supported by
+ *      the backend.
+ *
+ * max-request-size
+ *      Values:         <uint32_t>
+ *      Default Value:  BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK * PAGE_SIZE
+ *      Maximum Value:  BLKIF_MAX_SEGMENTS_PER_REQUEST * PAGE_SIZE
+ *
+ *      The maximum amount of data, in bytes, that can be referenced by a
+ *      request type that accesses frontend memory (currently BLKIF_OP_READ,
+ *      BLKIF_OP_WRITE, or BLKIF_OP_WRITE_BARRIER).
+ *
  *------------------------- Backend Device Properties -------------------------
  *
  * discard-aligment
  *      The size of the frontend allocated request ring buffer in units of
  *      machine pages.  The value must be a power of 2.
  *
+ * max-requests
+ *      Values:         <uint32_t>
+ *      Default Value:  BLKIF_MAX_RING_REQUESTS(PAGE_SIZE)
+ *      Maximum Value:  BLKIF_MAX_RING_REQUESTS(PAGE_SIZE * max-ring-pages)
+ *
+ *      The maximum number of concurrent, logical requests that will be
+ *      issued by the frontend.
+ *
+ *      Note: A logical request may span multiple ring entries.
+ *
+ * max-request-segments
+ *      Values:         <uint8_t>
+ *      Default Value:  BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK
+ *      Maximum Value:  MIN(255, backend/max-request-segments)
+ *
+ *      The maximum value the frontend will set in the
+ *      blkif_request.nr_segments field.
+ *
+ * max-request-size
+ *      Values:         <uint32_t>
+ *      Default Value:  BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK * PAGE_SIZE
+ *      Maximum Value:  max-request-segments * PAGE_SIZE
+ *
+ *      The maximum amount of data, in bytes, that can be referenced by
+ *      a request type that accesses frontend memory (currently BLKIF_OP_READ,
+ *      BLKIF_OP_WRITE, or BLKIF_OP_WRITE_BARRIER).
+ *
  *------------------------- Virtual Device Properties -------------------------
  *
  * device-type
 #define BLKIF_OP_DISCARD           5
 
 /*
- * Maximum scatter/gather segments per request.
+ * Maximum scatter/gather segments associated with a request header block.
  * This is carefully chosen so that sizeof(blkif_ring_t) <= PAGE_SIZE.
  * NB. This could be 12 if the ring indexes weren't stored in the same page.
  */
-#define BLKIF_MAX_SEGMENTS_PER_REQUEST 11
+#define BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK  11
+
+/*
+ * Maximum scatter/gather segments associated with a segment block.
+ */
+#define BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK 14
+
+#if __XEN_INTERFACE_VERSION__ >= 0x00040201
+/*
+ * Maximum scatter/gather segments per request (header + segment blocks).
+ */
+#define BLKIF_MAX_SEGMENTS_PER_REQUEST 255
+#else
+/*
+ * Maximum scatter/gather segments per request (header block only).
+ */
+#define BLKIF_MAX_SEGMENTS_PER_REQUEST BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK
+#endif
 
 /*
  * NB. first_sect and last_sect in blkif_request_segment, as well as
@@ -422,9 +492,25 @@ struct blkif_request_segment {
     /* @last_sect: last sector in frame to transfer (inclusive).     */
     uint8_t     first_sect, last_sect;
 };
+typedef struct blkif_request_segment blkif_request_segment_t;
 
 /*
  * Starting ring element for any I/O request.
+ *
+ * One or more segment blocks can be inserted into the request ring
+ * just after a blkif_request_t, allowing requests to operate on
+ * up to BLKIF_MAX_SEGMENTS_PER_REQUEST.
+ *
+ * BLKIF_SEGS_TO_BLOCKS() can be used on blkif_requst.nr_segments
+ * to determine the number of contiguous ring entries associated
+ * with this request.
+ *
+ * Note:  Due to the way Xen request rings operate, the producer and
+ *        consumer indices of the ring must be incremented by the
+ *        BLKIF_SEGS_TO_BLOCKS() value of the associated request.
+ *        (e.g. a response to a 3 ring entry request must also consume
+ *        3 entries in the ring, even though only the first ring entry
+ *        in the response has any data.)
  */
 struct blkif_request {
     uint8_t        operation;    /* BLKIF_OP_???                         */
@@ -432,10 +518,21 @@ struct blkif_request {
     blkif_vdev_t   handle;       /* only for read/write requests         */
     uint64_t       id;           /* private guest value, echoed in resp  */
     blkif_sector_t sector_number;/* start sector idx on disk (r/w only)  */
-    struct blkif_request_segment seg[BLKIF_MAX_SEGMENTS_PER_REQUEST];
+    blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK];
 };
 typedef struct blkif_request blkif_request_t;
 
+/*
+ * A segment block is a ring request structure that contains only
+ * segment data.
+ *
+ * sizeof(struct blkif_segment_block) <= sizeof(struct blkif_request)
+ */
+struct blkif_segment_block {
+    blkif_request_segment_t seg[BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK];
+};
+typedef struct blkif_segment_block blkif_segment_block_t;
+
 /*
  * Cast to this structure when blkif_request.operation == BLKIF_OP_DISCARD
  * sizeof(struct blkif_request_discard) <= sizeof(struct blkif_request)
@@ -473,6 +570,21 @@ typedef struct blkif_response blkif_response_t;
  */
 DEFINE_RING_TYPES(blkif, struct blkif_request, struct blkif_response);
 
+/*
+ * Index to, and treat as a segment block, an entry in the ring.
+ */
+#define BLKRING_GET_SEG_BLOCK(_r, _idx)                                 \
+    (((blkif_segment_block_t *)RING_GET_REQUEST(_r, _idx))->seg)
+
+/*
+ * The number of ring request blocks required to handle an I/O
+ * request containing _segs segments.
+ */
+#define BLKIF_SEGS_TO_BLOCKS(_segs)                                     \
+    ((((_segs - BLKIF_MAX_SEGMENTS_PER_HEADER_BLOCK)                    \
+     + (BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK - 1))                      \
+    / BLKIF_MAX_SEGMENTS_PER_SEGMENT_BLOCK) + /*header_block*/1)
+
 #define VDISK_CDROM        0x1
 #define VDISK_REMOVABLE    0x2
 #define VDISK_READONLY     0x4
index d8c55bfc8f631c9888ff459ff80ad7730d9c6e48..d982e5ebd8b0fe26c2b8ef1b8a6b2b03982cfbe9 100644 (file)
@@ -27,7 +27,7 @@
 #ifndef __XEN_PUBLIC_XEN_COMPAT_H__
 #define __XEN_PUBLIC_XEN_COMPAT_H__
 
-#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040200
+#define __XEN_LATEST_INTERFACE_VERSION__ 0x00040201
 
 #if defined(__XEN__) || defined(__XEN_TOOLS__)
 /* Xen is built with matching headers and implements the latest interface. */