From owner-p4-projects@FreeBSD.ORG Mon Aug 24 23:04:24 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DADEB1065695; Mon, 24 Aug 2009 23:04:23 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9F10E106568B for ; Mon, 24 Aug 2009 23:04:23 +0000 (UTC) (envelope-from mav@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 8DC788FC18 for ; Mon, 24 Aug 2009 23:04:23 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n7ON4Nqj041340 for ; Mon, 24 Aug 2009 23:04:23 GMT (envelope-from mav@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n7ON4NXT041338 for perforce@freebsd.org; Mon, 24 Aug 2009 23:04:23 GMT (envelope-from mav@freebsd.org) Date: Mon, 24 Aug 2009 23:04:23 GMT Message-Id: <200908242304.n7ON4NXT041338@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mav@freebsd.org using -f From: Alexander Motin To: Perforce Change Reviews Cc: Subject: PERFORCE change 167760 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Aug 2009 23:04:24 -0000 http://perforce.freebsd.org/chv.cgi?CH=167760 Change 167760 by mav@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;