From owner-freebsd-acpi@FreeBSD.ORG Tue Nov 15 17:00:02 2005 Return-Path: X-Original-To: acpi@freebsd.org Delivered-To: freebsd-acpi@FreeBSD.ORG Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 8FC4916A41F; Tue, 15 Nov 2005 17:00:02 +0000 (GMT) (envelope-from ume@mahoroba.org) Received: from ameno.mahoroba.org (gw4.mahoroba.org [218.45.22.175]) by mx1.FreeBSD.org (Postfix) with ESMTP id 9C55243D58; Tue, 15 Nov 2005 16:59:58 +0000 (GMT) (envelope-from ume@mahoroba.org) Received: from kasuga.mahoroba.org (IDENT:wyqfoZEgbd8ITSypHsM3LhgFThd1jXMM1HN/KC94lseEFAvpX27afsQyyet4H3fO@kasuga-iwi.mahoroba.org [IPv6:3ffe:501:185b:8010:212:f0ff:fe52:6ac]) (user=ume mech=CRAM-MD5 bits=0) by ameno.mahoroba.org (8.13.4/8.13.4) with ESMTP/inet6 id jAFGxmno002369 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 16 Nov 2005 01:59:52 +0900 (JST) (envelope-from ume@mahoroba.org) Date: Wed, 16 Nov 2005 01:59:47 +0900 Message-ID: From: Hajimu UMEMOTO To: Pierre-Luc Drouin In-Reply-To: <4378CC14.2020109@pldrouin.net> References: <4377775B.3080606@pldrouin.net> <20051114105854.GA1041@galgenberg.net> <4378CC14.2020109@pldrouin.net> User-Agent: xcite1.38> Wanderlust/2.14.0 (Africa) SEMI/1.14.6 (Maruoka) FLIM/1.14.7 (=?ISO-8859-4?Q?Sanj=F2?=) APEL/10.6 Emacs/22.0.50 (i386-unknown-freebsd6.0) MULE/5.0 (SAKAKI) X-Operating-System: FreeBSD 6.0-STABLE X-PGP-Key: http://www.imasy.or.jp/~ume/publickey.asc X-PGP-Fingerprint: 1F00 0B9E 2164 70FC 6DC5 BF5F 04E9 F086 BF90 71FE Organization: Internet Mutual Aid Society, YOKOHAMA MIME-Version: 1.0 (generated by SEMI 1.14.6 - "Maruoka") Content-Type: text/plain; charset=US-ASCII X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-2.0.2 (ameno.mahoroba.org [IPv6:3ffe:501:185b:8010::1]); Wed, 16 Nov 2005 01:59:53 +0900 (JST) X-Virus-Scanned: by amavisd-new X-Virus-Status: Clean X-Spam-Status: No, score=-2.6 required=5.0 tests=AWL,BAYES_00 autolearn=ham version=3.1.0 X-Spam-Checker-Version: SpamAssassin 3.1.0 (2005-09-13) on ameno.mahoroba.org Cc: acpi@freebsd.org, freebsd-stable@freebsd.org Subject: Re: Performance problem since updating from 6.0-RELEASE to 6.0-STABLE last friday X-BeenThere: freebsd-acpi@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: ACPI and power management development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Nov 2005 17:00:02 -0000 Hi, >>>>> On Mon, 14 Nov 2005 12:40:36 -0500 >>>>> Pierre-Luc Drouin said: pldrouin> Yep, smart battery is definately the problem. The performance of my pldrouin> laptop is back to normal when I remove the xfce4-battery-plugin. pldrouin> acpiconf -i loop reproduces the problem for me too. So it looks like pldrouin> there is something wrong in smart battery. The cmbat has similar issue on some laptops. So, acpi_cmbat.c uses cache for retrieval to reduce its influence, and its expiration time is set by hw.acpi.battery.info_expire. However, acpi_smbat.c doesn't use cache. So, I made a patch. Since I don't have a laptop which has smbat, I cannot test it by myself. Please test it and let me know the result. Index: sys/dev/acpica/acpi_smbat.c diff -u -p sys/dev/acpica/acpi_smbat.c.orig sys/dev/acpica/acpi_smbat.c --- sys/dev/acpica/acpi_smbat.c.orig Sun Nov 6 08:55:56 2005 +++ sys/dev/acpica/acpi_smbat.c Tue Nov 15 16:41:00 2005 @@ -44,11 +44,18 @@ __FBSDID("$FreeBSD: src/sys/dev/acpica/a struct acpi_smbat_softc { uint8_t sb_base_addr; device_t ec_dev; + + struct acpi_bif bif; + struct acpi_bst bst; + struct timespec bif_lastupdated; + struct timespec bst_lastupdated; }; static int acpi_smbat_probe(device_t dev); static int acpi_smbat_attach(device_t dev); static int acpi_smbat_shutdown(device_t dev); +static int acpi_smbat_info_expired(struct timespec *lastupdated); +static void acpi_smbat_info_updated(struct timespec *lastupdated); static int acpi_smbat_get_bif(device_t dev, struct acpi_bif *bif); static int acpi_smbat_get_bst(device_t dev, struct acpi_bst *bst); @@ -114,6 +121,9 @@ acpi_smbat_attach(device_t dev) return (ENXIO); } + timespecclear(&sc->bif_lastupdated); + timespecclear(&sc->bst_lastupdated); + if (acpi_battery_register(dev) != 0) { device_printf(dev, "cannot register battery\n"); return (ENXIO); @@ -132,6 +142,34 @@ acpi_smbat_shutdown(device_t dev) } static int +acpi_smbat_info_expired(struct timespec *lastupdated) +{ + struct timespec curtime; + + ACPI_SERIAL_ASSERT(smbat); + + if (lastupdated == NULL) + return (TRUE); + if (!timespecisset(lastupdated)) + return (TRUE); + + getnanotime(&curtime); + timespecsub(&curtime, lastupdated); + return (curtime.tv_sec < 0 || + curtime.tv_sec > acpi_battery_get_info_expire()); +} + +static void +acpi_smbat_info_updated(struct timespec *lastupdated) +{ + + ACPI_SERIAL_ASSERT(smbat); + + if (lastupdated != NULL) + getnanotime(lastupdated); +} + +static int acpi_smbus_read_2(struct acpi_smbat_softc *sc, uint8_t addr, uint8_t cmd, uint16_t *ptr) { @@ -284,6 +322,11 @@ acpi_smbat_get_bst(device_t dev, struct error = ENXIO; sc = device_get_softc(dev); + if (!acpi_smbat_info_expired(&sc->bst_lastupdated)) { + error = 0; + goto out; + } + if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_BATTERY_MODE, &val)) goto out; if (val & SMBATT_BM_CAPACITY_MODE) { @@ -299,7 +342,7 @@ acpi_smbat_get_bst(device_t dev, struct goto out; if (val & SMBATT_BS_DISCHARGING) { - bst->state |= ACPI_BATT_STAT_DISCHARG; + sc->bst.state |= ACPI_BATT_STAT_DISCHARG; /* * If the rate is negative, it is discharging. Otherwise, @@ -308,27 +351,31 @@ acpi_smbat_get_bst(device_t dev, struct if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_AT_RATE, &val)) goto out; if (val < 0) - bst->rate = (-val) * factor; + sc->bst.rate = (-val) * factor; else - bst->rate = -1; + sc->bst.rate = -1; } else { - bst->state |= ACPI_BATT_STAT_CHARGING; - bst->rate = -1; + sc->bst.state |= ACPI_BATT_STAT_CHARGING; + sc->bst.rate = -1; } if (val & SMBATT_BS_REMAINING_CAPACITY_ALARM) - bst->state |= ACPI_BATT_STAT_CRITICAL; + sc->bst.state |= ACPI_BATT_STAT_CRITICAL; if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_REMAINING_CAPACITY, &val)) goto out; - bst->cap = val * factor; + sc->bst.cap = val * factor; if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_VOLTAGE, &val)) goto out; - bst->volt = val; + sc->bst.volt = val; + + acpi_smbat_info_updated(&sc->bst_lastupdated); + error = 0; out: + memcpy(bst, &sc->bst, sizeof(sc->bst)); ACPI_SERIAL_END(smbat); return (error); } @@ -348,55 +395,63 @@ acpi_smbat_get_bif(device_t dev, struct error = ENXIO; sc = device_get_softc(dev); + if (!acpi_smbat_info_expired(&sc->bif_lastupdated)) { + error = 0; + goto out; + } + if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_BATTERY_MODE, &val)) goto out; if (val & SMBATT_BM_CAPACITY_MODE) { factor = 10; - bif->units = ACPI_BIF_UNITS_MW; + sc->bif.units = ACPI_BIF_UNITS_MW; } else { factor = 1; - bif->units = ACPI_BIF_UNITS_MA; + sc->bif.units = ACPI_BIF_UNITS_MA; } if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_DESIGN_CAPACITY, &val)) goto out; - bif->dcap = val * factor; + sc->bif.dcap = val * factor; if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_FULL_CHARGE_CAPACITY, &val)) goto out; - bif->lfcap = val * factor; - bif->btech = 1; /* secondary (rechargeable) */ + sc->bif.lfcap = val * factor; + sc->bif.btech = 1; /* secondary (rechargeable) */ if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_DESIGN_VOLTAGE, &val)) goto out; - bif->dvol = val; + sc->bif.dvol = val; - bif->wcap = bif->dcap / 10; - bif->lcap = bif->dcap / 10; + sc->bif.wcap = sc->bif.dcap / 10; + sc->bif.lcap = sc->bif.dcap / 10; - bif->gra1 = factor; /* not supported */ - bif->gra2 = factor; /* not supported */ + sc->bif.gra1 = factor; /* not supported */ + sc->bif.gra2 = factor; /* not supported */ if (acpi_smbus_read_multi_1(sc, addr, SMBATT_CMD_DEVICE_NAME, - bif->model, sizeof(bif->model))) + sc->bif.model, sizeof(sc->bif.model))) goto out; if (acpi_smbus_read_2(sc, addr, SMBATT_CMD_SERIAL_NUMBER, &val)) goto out; - snprintf(bif->serial, sizeof(bif->serial), "0x%04x", val); + snprintf(sc->bif.serial, sizeof(sc->bif.serial), "0x%04x", val); if (acpi_smbus_read_multi_1(sc, addr, SMBATT_CMD_DEVICE_CHEMISTRY, - bif->type, sizeof(bif->type))) + sc->bif.type, sizeof(sc->bif.type))) goto out; if (acpi_smbus_read_multi_1(sc, addr, SMBATT_CMD_MANUFACTURER_DATA, - bif->oeminfo, sizeof(bif->oeminfo))) + sc->bif.oeminfo, sizeof(sc->bif.oeminfo))) goto out; + acpi_smbat_info_updated(&sc->bif_lastupdated); + /* XXX check if device was replugged during read? */ error = 0; out: + memcpy(bif, &sc->bif, sizeof(sc->bif)); ACPI_SERIAL_END(smbat); return (error); } Sincerely, -- Hajimu UMEMOTO @ Internet Mutual Aid Society Yokohama, Japan ume@mahoroba.org ume@{,jp.}FreeBSD.org http://www.imasy.org/~ume/