socsvn commit: r257501 - soc2013/zcore/head/usr.sbin/bhyve

zcore at FreeBSD.org zcore at FreeBSD.org
Thu Sep 19 16:27:34 UTC 2013


Author: zcore
Date: Thu Sep 19 16:27:34 2013
New Revision: 257501
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=257501

Log:
  remove max iovcnt limitation

Modified:
  soc2013/zcore/head/usr.sbin/bhyve/block_if.h
  soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c

Modified: soc2013/zcore/head/usr.sbin/bhyve/block_if.h
==============================================================================
--- soc2013/zcore/head/usr.sbin/bhyve/block_if.h	Thu Sep 19 14:41:10 2013	(r257500)
+++ soc2013/zcore/head/usr.sbin/bhyve/block_if.h	Thu Sep 19 16:27:34 2013	(r257501)
@@ -32,9 +32,7 @@
 #include <sys/uio.h>
 #include <sys/unistd.h>
 
-#include "ahci.h"
-
-#define BLOCKIF_IOV_MAX		AHCI_SG_ENTRIES /* XXX */
+#define BLOCKIF_IOV_MAX		32	/* XXX */
 
 struct blockif_req {
 	struct iovec	br_iov[BLOCKIF_IOV_MAX];

Modified: soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c
==============================================================================
--- soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Thu Sep 19 14:41:10 2013	(r257500)
+++ soc2013/zcore/head/usr.sbin/bhyve/pci_ahci.c	Thu Sep 19 16:27:34 2013	(r257501)
@@ -105,6 +105,7 @@
 	uint8_t *cfis;
 	uint32_t len;
 	int slot;
+	int prdtl;
 };
 
 struct ahci_port {
@@ -371,9 +372,9 @@
 }
 
 static void
-handle_dma(struct ahci_port *p, int slot, uint8_t *cfis)
+handle_dma(struct ahci_port *p, int slot, uint8_t *cfis, int seek)
 {
-	int i, err, ncq = 0, readop = 1;
+	int i, err, iovcnt, ncq = 0, readop = 1;
 	uint64_t lba;
 	uint32_t len;
 	struct ahci_ioreq *aior;
@@ -382,6 +383,7 @@
 	struct ahci_prdt_entry *prdt = (struct ahci_prdt_entry *)(cfis + 0x80);
 	struct ahci_cmd_hdr *hdr = p->cmd_lst + slot * AHCI_CL_SIZE;
 
+	prdt += seek;
 	if (cfis[2] == ATA_WRITE_DMA || cfis[2] == ATA_WRITE_DMA48 ||
 			cfis[2] == ATA_WRITE_FPDMA_QUEUED)
 		readop = 0;
@@ -429,12 +431,18 @@
 	aior->len = len;
 	breq = &aior->io_req;
 	breq->br_offset = lba;
-	breq->br_iovcnt = hdr->prdtl;
+	iovcnt = hdr->prdtl - seek;
+	if (iovcnt > BLOCKIF_IOV_MAX) {
+		aior->prdtl = iovcnt - BLOCKIF_IOV_MAX;
+		iovcnt = BLOCKIF_IOV_MAX;
+	} else
+		aior->prdtl = 0;
+	breq->br_iovcnt = iovcnt;
 
 	/*
 	 * Build up the iovec based on the prdt
 	 */
-	for (i = 0; i < hdr->prdtl; i++) {
+	for (i = 0; i < iovcnt; i++) {
 		breq->br_iov[i].iov_base = paddr_guest2host(ahci_ctx(sc),
 				prdt->dba, prdt->dbc + 1);
 		breq->br_iov[i].iov_len = prdt->dbc + 1;
@@ -446,7 +454,7 @@
 		err = blockif_write(p->bctx, breq);
 	assert(err == 0);
 
-	if (ncq)
+	if (!aior->prdtl && ncq)
 		p->ci &= ~(1 << slot);
 }
 
@@ -821,9 +829,9 @@
 }
 
 static void
-atapi_read(struct ahci_port *p, int slot, uint8_t *cfis)
+atapi_read(struct ahci_port *p, int slot, uint8_t *cfis, int seek)
 {
-	int i, err;
+	int i, err, iovcnt;
 	uint64_t lba;
 	uint32_t len;
 	struct ahci_ioreq *aior;
@@ -833,6 +841,7 @@
 	struct ahci_prdt_entry *prdt = (struct ahci_prdt_entry *)(cfis + 0x80);
 	struct ahci_cmd_hdr *hdr = p->cmd_lst + slot * AHCI_CL_SIZE;
 
+	prdt += seek;
 	lba = be32dec(acmd + 2);
 	if (acmd[0] == READ_10)
 		len = be16dec(acmd + 7);
@@ -856,7 +865,13 @@
 	aior->len = len;
 	breq = &aior->io_req;
 	breq->br_offset = lba;
-	breq->br_iovcnt = hdr->prdtl;
+	iovcnt = hdr->prdtl - seek;
+	if (iovcnt > BLOCKIF_IOV_MAX) {
+		aior->prdtl = iovcnt - BLOCKIF_IOV_MAX;
+		iovcnt = BLOCKIF_IOV_MAX;
+	} else
+		aior->prdtl = 0;
+	breq->br_iovcnt = iovcnt;
 
 	/*
 	 * Build up the iovec based on the prdt
@@ -949,7 +964,7 @@
 		break;
 	case READ_10:
 	case READ_12:
-		atapi_read(p, slot, cfis);
+		atapi_read(p, slot, cfis, 0);
 		break;
 	case REQUEST_SENSE:
 		atapi_request_sense(p, slot, cfis);
@@ -1021,7 +1036,7 @@
 	case ATA_WRITE_DMA48:
 	case ATA_READ_FPDMA_QUEUED:
 	case ATA_WRITE_FPDMA_QUEUED:
-		handle_dma(p, slot, cfis);
+		handle_dma(p, slot, cfis, 0);
 		break;
 	case ATA_FLUSHCACHE:
 	case ATA_FLUSHCACHE48:
@@ -1130,20 +1145,34 @@
 	struct ahci_ioreq *aior;
 	uint32_t tfd;
 	struct ahci_cmd_hdr *hdr;
-	int ncq = 0;
+	int pending, slot, ncq = 0;
+	uint8_t *cfis;
 
 	DPRINTF("%s %d\n", __func__, err);
 
 	aior = br->br_param;
 	p = aior->io_pr;
+	cfis = aior->cfis;
+	slot = aior->slot;
+	pending = aior->prdtl;
 	sc = p->pr_sc;
-	hdr = p->cmd_lst + aior->slot * AHCI_CL_SIZE;
-	if (aior->cfis[2] == ATA_WRITE_FPDMA_QUEUED ||
-			aior->cfis[2] == ATA_READ_FPDMA_QUEUED)
+	hdr = p->cmd_lst + slot * AHCI_CL_SIZE;
+	if (cfis[2] == ATA_WRITE_FPDMA_QUEUED ||
+			cfis[2] == ATA_READ_FPDMA_QUEUED)
 		ncq = 1;
 
 	pthread_mutex_lock(&sc->mtx);
 
+	/*
+	 * Move the blockif request back to the free list
+	 */
+	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
+
+	if (pending && !err) {
+		handle_dma(p, slot, cfis, hdr->prdtl - pending);
+		goto out;
+	}
+
 	if (!err) {
 		tfd = ATA_S_READY | ATA_S_DSC;
 		if (ncq)
@@ -1154,20 +1183,15 @@
 		tfd = (ATA_E_ABORT << 8) | ATA_S_READY | ATA_S_ERROR;
 		hdr->prdbc = 0;
 		if (ncq)
-			p->serr |= (1 << aior->slot);
+			p->serr |= (1 << slot);
 	}
 
 	if (ncq) {
-		p->sact &= ~(1 << aior->slot);
-		ahci_write_fis_sdb(p, aior->slot, tfd);
+		p->sact &= ~(1 << slot);
+		ahci_write_fis_sdb(p, slot, tfd);
 	} else
-		ahci_write_fis_d2h(p, aior->slot, aior->cfis, tfd);
-
-	/*
-	 * Move the blockif request back to the free list
-	 */
-	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
-
+		ahci_write_fis_d2h(p, slot, cfis, tfd);
+out:
 	pthread_mutex_unlock(&sc->mtx);
 	DPRINTF("%s exit\n", __func__);
 }
@@ -1181,16 +1205,30 @@
 	struct pci_ahci_softc *sc;
 	struct ahci_ioreq *aior;
 	struct ahci_cmd_hdr *hdr;
+	int pending, slot;
 
 	DPRINTF("%s %d\n", __func__, err);
 
 	aior = br->br_param;
 	p = aior->io_pr;
+	cfis = aior->cfis;
+	slot = aior->slot;
+	pending = aior->prdtl;
 	sc = p->pr_sc;
 	hdr = p->cmd_lst + aior->slot * AHCI_CL_SIZE;
 
 	pthread_mutex_lock(&sc->mtx);
 
+	/*
+	 * Move the blockif request back to the free list
+	 */
+	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
+
+	if (pending && !err) {
+		atapi_read(p, slot, cfis, hdr->prdtl - pending);
+		goto out;
+	}
+
 	if (!err) {
 		tfd = ATA_S_READY | ATA_S_DSC;
 		hdr->prdbc = aior->len;
@@ -1201,18 +1239,12 @@
 		hdr->prdbc = 0;
 	}
 
-	cfis = aior->cfis;
 	cfis[4] = (cfis[4] & ~7) | ATA_I_CMD | ATA_I_IN;
-	ahci_write_fis_d2h(p, aior->slot, cfis, tfd);
-
-	/*
-	 * Move the blockif request back to the free list
-	 */
-	STAILQ_INSERT_TAIL(&p->iofhd, aior, io_list);
+	ahci_write_fis_d2h(p, slot, cfis, tfd);
 
+out:
 	pthread_mutex_unlock(&sc->mtx);
 	DPRINTF("%s exit\n", __func__);
-
 }
 
 static void


More information about the svn-soc-all mailing list