PERFORCE change 167760 for review

Alexander Motin mav at FreeBSD.org
Mon Aug 24 23:04:24 UTC 2009


http://perforce.freebsd.org/chv.cgi?CH=167760

Change 167760 by mav at mav_mavbook on 2009/08/24 23:03:57

	Implement AHCI Command Completion Coalescing (CCC) feature support.
	
	CCC reduces number of context switches on systems with many parallel
	requests, but it can decrease disk performance on some workloads
	due to additional command latency.

Affected files ...

.. //depot/projects/scottl-camlock/src/share/man/man4/ahci.4#6 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#52 edit
.. //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#19 edit

Differences ...

==== //depot/projects/scottl-camlock/src/share/man/man4/ahci.4#6 (text+ko) ====

@@ -60,6 +60,13 @@
 .It 2
 multiple MSI vectors used, if supported;
 .El
+.It Va hint.ahci.X.ccc
+controls Command Completion Coalescing (CCC) usage by the specified controller.
+Non-zero value enables CCC and defines maximum time (in ms), request can wait
+for interrupt, if there are some more requests present on controller queue.
+CCC reduces number of context switches on systems with many parallel requests,
+but it can decrease disk performance on some workloads due to additional
+command latency.
 .It Va hint.ahcich.X.pm_level
 controls SATA interface Power Management for specified channel,
 allowing some power to be saved at the cost of additional command

==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.c#52 (text+ko) ====

@@ -125,6 +125,8 @@
 	u_int32_t version, caps, caps2;
 
 	ctlr->dev = dev;
+	resource_int_value(device_get_name(dev),
+	    device_get_unit(dev), "ccc", &ctlr->ccc);
 	/* if we have a memory BAR(5) we are likely on an AHCI part */
 	ctlr->r_rid = PCIR_BAR(5);
 	if (!(ctlr->r_mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
@@ -272,6 +274,21 @@
 	ATA_OUTL(ctlr->r_mem, AHCI_GHC, AHCI_GHC_AE);
 	/* Clear interrupts */
 	ATA_OUTL(ctlr->r_mem, AHCI_IS, ATA_INL(ctlr->r_mem, AHCI_IS));
+	/* Configure CCC */
+	if (ctlr->ccc) {
+		ATA_OUTL(ctlr->r_mem, AHCI_CCCP, ATA_INL(ctlr->r_mem, AHCI_PI));
+		ATA_OUTL(ctlr->r_mem, AHCI_CCCC,
+		    (ctlr->ccc << AHCI_CCCC_TV_SHIFT) |
+		    (4 << AHCI_CCCC_CC_SHIFT) |
+		    AHCI_CCCC_EN);
+		ctlr->cccv = (ATA_INL(ctlr->r_mem, AHCI_CCCC) &
+		    AHCI_CCCC_INT_MASK) >> AHCI_CCCC_INT_SHIFT;
+		if (bootverbose) {
+			device_printf(dev,
+			    "CCC with %dms/4cmd enabled on vector %d\n",
+			    ctlr->ccc, ctlr->cccv);
+		}
+	}
 	/* Enable AHCI interrupts */
 	ATA_OUTL(ctlr->r_mem, AHCI_GHC,
 	    ATA_INL(ctlr->r_mem, AHCI_GHC) | AHCI_GHC_IE);
@@ -332,7 +349,8 @@
 	for (i = 0; i < ctlr->numirqs; i++) {
 		ctlr->irqs[i].ctlr = ctlr;
 		ctlr->irqs[i].r_irq_rid = i + (msi ? 1 : 0);
-		if (ctlr->numirqs == 1 || i >= ctlr->channels)
+		if (ctlr->numirqs == 1 || i >= ctlr->channels ||
+		    (ctlr->ccc && i == ctlr->cccv))
 			ctlr->irqs[i].mode = AHCI_IRQ_MODE_ALL;
 		else if (i == ctlr->numirqs - 1)
 			ctlr->irqs[i].mode = AHCI_IRQ_MODE_AFTER;
@@ -367,9 +385,11 @@
 	int unit;
 
 	is = ATA_INL(ctlr->r_mem, AHCI_IS);
-	if (irq->mode == AHCI_IRQ_MODE_ALL)
+	if (irq->mode == AHCI_IRQ_MODE_ALL) {
+		if (ctlr->ccc)
+			is = ctlr->ichannels;
 		unit = 0;
-	else	/* AHCI_IRQ_MODE_AFTER */
+	} else	/* AHCI_IRQ_MODE_AFTER */
 		unit = irq->r_irq_rid - 1;
 	for (; unit < ctlr->channels; unit++) {
 		if ((is & (1 << unit)) != 0 &&
@@ -1585,6 +1605,7 @@
 ahci_reset(device_t dev)
 {
 	struct ahci_channel *ch = device_get_softc(dev);
+	struct ahci_controller *ctlr = device_get_softc(device_get_parent(dev));
 	int i;
 
 	if (bootverbose)
@@ -1631,8 +1652,8 @@
 	     (AHCI_P_IX_CPD | AHCI_P_IX_TFE | AHCI_P_IX_HBF |
 	      AHCI_P_IX_HBD | AHCI_P_IX_IF | AHCI_P_IX_OF |
 	      ((ch->pm_level == 0) ? AHCI_P_IX_PRC | AHCI_P_IX_PC : 0) |
-	      AHCI_P_IX_DP | AHCI_P_IX_UF | AHCI_P_IX_SDB |
-	      AHCI_P_IX_DS | AHCI_P_IX_PS | AHCI_P_IX_DHR));
+	      AHCI_P_IX_DP | AHCI_P_IX_UF | (ctlr->ccc ? 0 : AHCI_P_IX_SDB) |
+	      AHCI_P_IX_DS | AHCI_P_IX_PS | (ctlr->ccc ? 0 : AHCI_P_IX_DHR)));
 	if (bootverbose)
 		device_printf(dev, "AHCI reset done: device found\n");
 	/* Tell the XPT about the event */

==== //depot/projects/scottl-camlock/src/sys/dev/ahci/ahci.h#19 (text+ko) ====

@@ -176,6 +176,16 @@
 #define AHCI_PI                     0x0c
 #define AHCI_VS                     0x10
 
+#define AHCI_CCCC                   0x14
+#define		AHCI_CCCC_TV_MASK	0xffff0000
+#define		AHCI_CCCC_TV_SHIFT	16
+#define		AHCI_CCCC_CC_MASK	0x0000ff00
+#define		AHCI_CCCC_CC_SHIFT	8
+#define		AHCI_CCCC_INT_MASK	0x000000f8
+#define		AHCI_CCCC_INT_SHIFT	3
+#define		AHCI_CCCC_EN		0x00000001
+#define AHCI_CCCP                   0x18
+
 #define AHCI_CAP2                   0x24
 #define		AHCI_CAP2_BOH	0x00000001
 #define		AHCI_CAP2_NVMP	0x00000002
@@ -381,6 +391,8 @@
 	int			numirqs;
 	int			channels;
 	int			ichannels;
+	int			ccc;		/* CCC timeout */
+	int			cccv;		/* CCC vector */
 	struct {
 		void			(*function)(void *);
 		void			*argument;


More information about the p4-projects mailing list