svn commit: r307137 - in stable/10/sys/dev/hyperv: include netvsc storvsc vmbus

Sepherosa Ziehau sephe at FreeBSD.org
Wed Oct 12 09:27:41 UTC 2016


Author: sephe
Date: Wed Oct 12 09:27:39 2016
New Revision: 307137
URL: https://svnweb.freebsd.org/changeset/base/307137

Log:
  MFC 303603-303605,303764
  
  303603
      hyperv/vmbus: Remove the artificial entry limit of SG and PRP list.
  
      Just make sure that the total channel packet size does not exceed 1/2
      data size of the TX bufring.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7359
  
  303604
      hyperv/storvsc: Set maxio to 128KB.
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7360
  
  303605
      hyperv/storvsc: Stringent PRP list assertions
  
      Sponsored by:   Microsoft
      Differential Revision:  https://reviews.freebsd.org/D7361
  
  303764
      hyperv/vmbus: Only make sure the TX bufring will not be closed.
  
      KVP can write data, whose size is > 1/2 TX bufring size.
  
      Sponsored by:   Microsoft OSTC
      Differential Revision:  https://reviews.freebsd.org/D7414

Modified:
  stable/10/sys/dev/hyperv/include/vmbus.h
  stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
  stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
  stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
  stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h
  stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/dev/hyperv/include/vmbus.h
==============================================================================
--- stable/10/sys/dev/hyperv/include/vmbus.h	Wed Oct 12 09:17:41 2016	(r307136)
+++ stable/10/sys/dev/hyperv/include/vmbus.h	Wed Oct 12 09:27:39 2016	(r307137)
@@ -103,9 +103,6 @@ struct vmbus_chanpkt_rxbuf {
 	struct vmbus_rxbuf_desc cp_rxbuf[];
 } __packed;
 
-#define VMBUS_CHAN_SGLIST_MAX		32
-#define VMBUS_CHAN_PRPLIST_MAX		32
-
 struct vmbus_channel;
 struct hyperv_guid;
 

Modified: stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h	Wed Oct 12 09:17:41 2016	(r307136)
+++ stable/10/sys/dev/hyperv/netvsc/hv_net_vsc.h	Wed Oct 12 09:27:39 2016	(r307137)
@@ -1088,6 +1088,7 @@ struct vmbus_channel;
 typedef void (*pfn_on_send_rx_completion)(struct vmbus_channel *, void *);
 
 #define NETVSC_DEVICE_RING_BUFFER_SIZE	(128 * PAGE_SIZE)
+#define NETVSC_PACKET_MAXPAGE		32
 
 #define NETVSC_VLAN_PRIO_MASK		0xe000
 #define NETVSC_VLAN_PRIO_SHIFT		13
@@ -1137,7 +1138,7 @@ typedef struct netvsc_packet_ {
 	uint32_t	tot_data_buf_len;
 	void		*data;
 	uint32_t	gpa_cnt;
-	struct vmbus_gpa gpa[VMBUS_CHAN_SGLIST_MAX];
+	struct vmbus_gpa gpa[NETVSC_PACKET_MAXPAGE];
 } netvsc_packet;
 
 typedef struct {

Modified: stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Wed Oct 12 09:17:41 2016	(r307136)
+++ stable/10/sys/dev/hyperv/netvsc/hv_netvsc_drv_freebsd.c	Wed Oct 12 09:27:39 2016	(r307137)
@@ -154,7 +154,7 @@ __FBSDID("$FreeBSD$");
 #define HN_TX_DATA_MAXSIZE		IP_MAXPACKET
 #define HN_TX_DATA_SEGSIZE		PAGE_SIZE
 #define HN_TX_DATA_SEGCNT_MAX		\
-    (VMBUS_CHAN_SGLIST_MAX - HV_RF_NUM_TX_RESERVED_PAGE_BUFS)
+    (NETVSC_PACKET_MAXPAGE - HV_RF_NUM_TX_RESERVED_PAGE_BUFS)
 
 #define HN_DIRECT_TX_SIZE_DEF		128
 

Modified: stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c
==============================================================================
--- stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c	Wed Oct 12 09:17:41 2016	(r307136)
+++ stable/10/sys/dev/hyperv/storvsc/hv_storvsc_drv_freebsd.c	Wed Oct 12 09:27:39 2016	(r307137)
@@ -88,10 +88,25 @@ __FBSDID("$FreeBSD$");
 
 #define VSTOR_PKT_SIZE	(sizeof(struct vstor_packet) - vmscsi_size_delta)
 
-#define STORVSC_DATA_SEGCNT_MAX		VMBUS_CHAN_PRPLIST_MAX
+/*
+ * 33 segments are needed to allow 128KB maxio, in case the data
+ * in the first page is _not_ PAGE_SIZE aligned, e.g.
+ *
+ *     |<----------- 128KB ----------->|
+ *     |                               |
+ *  0  2K 4K    8K   16K   124K  128K  130K
+ *  |  |  |     |     |       |     |  |
+ *  +--+--+-----+-----+.......+-----+--+--+
+ *  |  |  |     |     |       |     |  |  | DATA
+ *  |  |  |     |     |       |     |  |  |
+ *  +--+--+-----+-----+.......------+--+--+
+ *     |  |                         |  |
+ *     | 1|            31           | 1| ...... # of segments
+ */
+#define STORVSC_DATA_SEGCNT_MAX		33
 #define STORVSC_DATA_SEGSZ_MAX		PAGE_SIZE
 #define STORVSC_DATA_SIZE_MAX		\
-	(STORVSC_DATA_SEGCNT_MAX * STORVSC_DATA_SEGSZ_MAX)
+	((STORVSC_DATA_SEGCNT_MAX - 1) * STORVSC_DATA_SEGSZ_MAX)
 
 struct storvsc_softc;
 
@@ -1388,6 +1403,7 @@ storvsc_action(struct cam_sim *sim, unio
 		cpi->hba_misc = PIM_NOBUSRESET;
 		if (hv_storvsc_use_pim_unmapped)
 			cpi->hba_misc |= PIM_UNMAPPED;
+		cpi->maxio = STORVSC_DATA_SIZE_MAX;
 		cpi->hba_eng_cnt = 0;
 		cpi->max_target = STORVSC_MAX_TARGETS;
 		cpi->max_lun = sc->hs_drv_props->drv_max_luns_per_target;
@@ -1761,13 +1777,28 @@ storvsc_xferbuf_prepare(void *arg, bus_d
 	prplist->gpa_range.gpa_ofs = segs[0].ds_addr & PAGE_MASK;
 
 	for (i = 0; i < nsegs; i++) {
-		prplist->gpa_page[i] = atop(segs[i].ds_addr);
 #ifdef INVARIANTS
-		if (i != 0 && i != nsegs - 1) {
-			KASSERT((segs[i].ds_addr & PAGE_MASK) == 0 &&
-			    segs[i].ds_len == PAGE_SIZE, ("not a full page"));
+		if (nsegs > 1) {
+			if (i == 0) {
+				KASSERT((segs[i].ds_addr & PAGE_MASK) +
+				    segs[i].ds_len == PAGE_SIZE,
+				    ("invalid 1st page, ofs 0x%jx, len %zu",
+				     (uintmax_t)segs[i].ds_addr,
+				     segs[i].ds_len));
+			} else if (i == nsegs - 1) {
+				KASSERT((segs[i].ds_addr & PAGE_MASK) == 0,
+				    ("invalid last page, ofs 0x%jx",
+				     (uintmax_t)segs[i].ds_addr));
+			} else {
+				KASSERT((segs[i].ds_addr & PAGE_MASK) == 0 &&
+				    segs[i].ds_len == PAGE_SIZE,
+				    ("not a full page, ofs 0x%jx, len %zu",
+				     (uintmax_t)segs[i].ds_addr,
+				     segs[i].ds_len));
+			}
 		}
 #endif
+		prplist->gpa_page[i] = atop(segs[i].ds_addr);
 	}
 	reqp->prp_cnt = nsegs;
 }

Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h	Wed Oct 12 09:17:41 2016	(r307136)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_brvar.h	Wed Oct 12 09:27:39 2016	(r307137)
@@ -71,6 +71,17 @@ struct vmbus_txbr {
 struct sysctl_ctx_list;
 struct sysctl_oid;
 
+static __inline int
+vmbus_txbr_maxpktsz(const struct vmbus_txbr *tbr)
+{
+	/*
+	 * - 64 bits for the trailing start index (- sizeof(uint64_t)).
+	 * - The rindex and windex can't be same (- 1).  See
+	 *   the comment near vmbus_bufring.br_{r,w}index.
+	 */
+	return (tbr->txbr_dsize - sizeof(uint64_t) - 1);
+}
+
 void		vmbus_br_sysctl_create(struct sysctl_ctx_list *ctx,
 		    struct sysctl_oid *br_tree, struct vmbus_br *br,
 		    const char *name);

Modified: stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c
==============================================================================
--- stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c	Wed Oct 12 09:17:41 2016	(r307136)
+++ stable/10/sys/dev/hyperv/vmbus/vmbus_chan.c	Wed Oct 12 09:27:39 2016	(r307137)
@@ -610,6 +610,8 @@ vmbus_chan_send(struct vmbus_channel *ch
 	hlen = sizeof(pkt);
 	pktlen = hlen + dlen;
 	pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);
+	KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr),
+	    ("invalid packet size %d", pad_pktlen));
 
 	pkt.cp_hdr.cph_type = type;
 	pkt.cp_hdr.cph_flags = flags;
@@ -640,12 +642,11 @@ vmbus_chan_send_sglist(struct vmbus_chan
 	boolean_t send_evt;
 	uint64_t pad = 0;
 
-	KASSERT(sglen < VMBUS_CHAN_SGLIST_MAX,
-	    ("invalid sglist len %d", sglen));
-
 	hlen = __offsetof(struct vmbus_chanpkt_sglist, cp_gpa[sglen]);
 	pktlen = hlen + dlen;
 	pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);
+	KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr),
+	    ("invalid packet size %d", pad_pktlen));
 
 	pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA;
 	pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC;
@@ -681,13 +682,12 @@ vmbus_chan_send_prplist(struct vmbus_cha
 	boolean_t send_evt;
 	uint64_t pad = 0;
 
-	KASSERT(prp_cnt < VMBUS_CHAN_PRPLIST_MAX,
-	    ("invalid prplist entry count %d", prp_cnt));
-
 	hlen = __offsetof(struct vmbus_chanpkt_prplist,
 	    cp_range[0].gpa_page[prp_cnt]);
 	pktlen = hlen + dlen;
 	pad_pktlen = VMBUS_CHANPKT_TOTLEN(pktlen);
+	KASSERT(pad_pktlen <= vmbus_txbr_maxpktsz(&chan->ch_txbr),
+	    ("invalid packet size %d", pad_pktlen));
 
 	pkt.cp_hdr.cph_type = VMBUS_CHANPKT_TYPE_GPA;
 	pkt.cp_hdr.cph_flags = VMBUS_CHANPKT_FLAG_RC;


More information about the svn-src-all mailing list