Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 16 Dec 2008 16:04:41 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r186182 - head/sys/dev/ata
Message-ID:  <200812161604.mBGG4fBd041647@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Tue Dec 16 16:04:40 2008
New Revision: 186182
URL: http://svn.freebsd.org/changeset/base/186182

Log:
  Call ata_legacy() only once on attach and save it's result. Scanning PCI
  configuration registers (which are not going to change) on every interrupt
  looks expensive, especially when interrupt is shared. Profiling shows me 3%
  of time spent by atapci0 on pure network load due to IRQ sharing with em0.

Modified:
  head/sys/dev/ata/ata-pci.c
  head/sys/dev/ata/ata-pci.h

Modified: head/sys/dev/ata/ata-pci.c
==============================================================================
--- head/sys/dev/ata/ata-pci.c	Tue Dec 16 15:05:52 2008	(r186181)
+++ head/sys/dev/ata/ata-pci.c	Tue Dec 16 16:04:40 2008	(r186182)
@@ -92,7 +92,8 @@ ata_pci_attach(device_t dev)
     int unit;
 
     /* do chipset specific setups only needed once */
-    if (ata_legacy(dev) || pci_read_config(dev, PCIR_BAR(2), 4) & IOMASK)
+    ctlr->legacy = ata_legacy(dev);
+    if (ctlr->legacy || pci_read_config(dev, PCIR_BAR(2), 4) & IOMASK)
 	ctlr->channels = 2;
     else
 	ctlr->channels = 1;
@@ -120,7 +121,7 @@ ata_pci_attach(device_t dev)
 
     /* attach all channels on this controller */
     for (unit = 0; unit < ctlr->channels; unit++) {
-	if ((unit == 0 || unit == 1) && ata_legacy(dev)) {
+	if ((unit == 0 || unit == 1) && ctlr->legacy) {
 	    device_add_child(dev, "ata", unit);
 	    continue;
 	}
@@ -192,7 +193,7 @@ ata_pci_alloc_resource(device_t dev, dev
     if (type == SYS_RES_IOPORT) {
 	switch (*rid) {
 	case ATA_IOADDR_RID:
-	    if (ata_legacy(dev)) {
+	    if (controller->legacy) {
 		start = (unit ? ATA_SECONDARY : ATA_PRIMARY);
 		count = ATA_IOSIZE;
 		end = start + count - 1;
@@ -204,7 +205,7 @@ ata_pci_alloc_resource(device_t dev, dev
 	    break;
 
 	case ATA_CTLADDR_RID:
-	    if (ata_legacy(dev)) {
+	    if (controller->legacy) {
 		start = (unit ? ATA_SECONDARY : ATA_PRIMARY) + ATA_CTLOFFSET;
 		count = ATA_CTLIOSIZE;
 		end = start + count - 1;
@@ -217,7 +218,7 @@ ata_pci_alloc_resource(device_t dev, dev
 	}
     }
     if (type == SYS_RES_IRQ && *rid == ATA_IRQ_RID) {
-	if (ata_legacy(dev)) {
+	if (controller->legacy) {
 	    int irq = (unit == 0 ? 14 : 15);
 	    
 	    res = BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
@@ -233,6 +234,7 @@ int
 ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
 			 struct resource *r)
 {
+    struct ata_pci_controller *controller = device_get_softc(dev);
     int unit = ((struct ata_channel *)device_get_softc(child))->unit;
 
     if (type == SYS_RES_IOPORT) {
@@ -256,7 +258,7 @@ ata_pci_release_resource(device_t dev, d
 	if (rid != ATA_IRQ_RID)
 	    return ENOENT;
 
-	if (ata_legacy(dev)) {
+	if (controller->legacy) {
 	    return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
 					SYS_RES_IRQ, rid, r);
 	}
@@ -271,7 +273,9 @@ ata_pci_setup_intr(device_t dev, device_
 		   int flags, driver_filter_t *filter, driver_intr_t *function, 
 		   void *argument, void **cookiep)
 {
-    if (ata_legacy(dev)) {
+    struct ata_pci_controller *controller = device_get_softc(dev);
+
+    if (controller->legacy) {
 	return BUS_SETUP_INTR(device_get_parent(dev), child, irq,
 			      flags, filter, function, argument, cookiep);
     }
@@ -294,7 +298,9 @@ int
 ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
 		      void *cookie)
 {
-    if (ata_legacy(dev)) {
+    struct ata_pci_controller *controller = device_get_softc(dev);
+
+    if (controller->legacy) {
 	return BUS_TEARDOWN_INTR(device_get_parent(dev), child, irq, cookie);
     }
     else {
@@ -352,7 +358,7 @@ ata_pci_allocate(device_t dev)
 	ch->r_io[i].offset = i;
     }
     ch->r_io[ATA_CONTROL].res = ctlio;
-    ch->r_io[ATA_CONTROL].offset = ata_legacy(device_get_parent(dev)) ? 0 : 2;
+    ch->r_io[ATA_CONTROL].offset = ctlr->legacy ? 0 : 2;
     ch->r_io[ATA_IDX_ADDR].res = io;
     ata_default_registers(dev);
     if (ctlr->r_res1) {
@@ -369,9 +375,11 @@ ata_pci_allocate(device_t dev)
 int
 ata_pci_status(device_t dev)
 {
+    struct ata_pci_controller *controller =
+	device_get_softc(device_get_parent(dev));
     struct ata_channel *ch = device_get_softc(dev);
 
-    if ((dumping || !ata_legacy(device_get_parent(dev))) &&
+    if ((dumping || !controller->legacy) &&
 	((ch->flags & ATA_ALWAYS_DMASTAT) ||
 	 (ch->dma.flags & ATA_DMA_ACTIVE))) {
 	int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
@@ -652,7 +660,7 @@ ata_setup_interrupt(device_t dev, void *
     struct ata_pci_controller *ctlr = device_get_softc(dev);
     int rid = ATA_IRQ_RID;
 
-    if (!ata_legacy(dev)) {
+    if (!ctlr->legacy) {
 	if (!(ctlr->r_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
 						   RF_SHAREABLE | RF_ACTIVE))) {
 	    device_printf(dev, "unable to map interrupt\n");

Modified: head/sys/dev/ata/ata-pci.h
==============================================================================
--- head/sys/dev/ata/ata-pci.h	Tue Dec 16 15:05:52 2008	(r186181)
+++ head/sys/dev/ata/ata-pci.h	Tue Dec 16 16:04:40 2008	(r186182)
@@ -48,6 +48,7 @@ struct ata_pci_controller {
     struct resource     *r_irq;
     void                *handle;
     struct ata_chip_id  *chip;
+    int			legacy;
     int                 channels;
     int                 (*chipinit)(device_t);
     int                 (*suspend)(device_t);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812161604.mBGG4fBd041647>