From: Venkatesh Pallipadi <venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
To: Dominik Brodowski
<linux-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>
Cc: "Pallipadi,
Venkatesh"
<venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
"Brown, Len" <len.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Subject: Re: [PATCH 5/5] processor: jiffies-based bm_check, bugfixes
Date: Thu, 23 Dec 2004 13:41:18 -0800 [thread overview]
Message-ID: <20041223134118.A24497@unix-os.sc.intel.com> (raw)
In-Reply-To: <20041223201334.GA19292-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>; from linux-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org on Thu, Dec 23, 2004 at 12:13:34PM -0800
The patch below helps us maintain a proper bm_activity history. We monitor
the bm_activity every 10mS. Using the current 32 bit bm_activity we can store
the history of upto 320mS.
As Dominik pointed out, it has a disadvantage of adding some overhead, even
when CPU is not idle. But, the advantage is that it has a good bm_activity
history for 320 mS, which can be useful in future, to have more fancier C-state
policies.
Thanks,
Venki
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
--- linux-2.6.10-rc3-cst/drivers/acpi/processor_idle.c.org 2004-12-23 12:48:01.000000000 -0800
+++ linux-2.6.10-rc3-cst/drivers/acpi/processor_idle.c 2004-12-23 15:59:35.000000000 -0800
@@ -36,6 +36,9 @@
#include <linux/dmi.h>
#include <linux/moduleparam.h>
+#include <linux/workqueue.h>
+#include <linux/compiler.h>
+
#include <asm/io.h>
#include <asm/uaccess.h>
@@ -108,6 +111,121 @@ ticks_elapsed (
}
+static void do_bm_check_timer(void *data);
+static DECLARE_MUTEX (bm_check_sem);
+static DECLARE_WORK (bm_check_work, do_bm_check_timer, NULL);
+
+#define BM_CHECK_START 1
+#define BM_CHECK_STOP 2
+
+#define BM_CHECK_RATE ((HZ < 100) ? (1) : (HZ/100))
+
+u32
+acpi_get_bm_status (u32 clear_status)
+{
+ u32 bm_status = 0;
+
+ down(&bm_check_sem);
+ /*
+ * Check for bus mastering activity
+ */
+ acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,
+ &bm_status, ACPI_MTX_DO_NOT_LOCK);
+ if (bm_status && clear_status) {
+ /* Clear BM status bit */
+ acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,
+ 1, ACPI_MTX_DO_NOT_LOCK);
+ }
+
+ /*
+ * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
+ * the true state of bus mastering activity; forcing us to
+ * manually check the BMIDEA bit of each IDE channel.
+ */
+ else if (errata.piix4.bmisx) {
+ if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
+ || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
+ bm_status++;
+ }
+
+ up(&bm_check_sem);
+ return (bm_status);
+}
+
+void
+acpi_bm_activity_update (unsigned long cpu, unsigned long num_bits)
+{
+ struct acpi_processor *pr = NULL;
+
+ pr = processors[cpu];
+ if (!pr)
+ return;
+
+ if (unlikely(num_bits > 32))
+ num_bits = 32;
+
+ /*
+ * Check BM Activity
+ * -----------------
+ * Check for bus mastering activity (if required), record, and check
+ * for demotion.
+ */
+ if (pr->flags.bm_check) {
+ u32 status;
+ int i;
+ status = acpi_get_bm_status(1);
+ for (i = 0; i < num_bits; i++) {
+ pr->power.bm_activity <<= 1;
+ pr->power.bm_activity |= (status & 0x1);
+ }
+ }
+}
+
+static void
+do_bm_check_timer(void *data)
+{
+ static unsigned long last_jiffies;
+ unsigned long this_jiffies;
+ unsigned long i, num_bits;
+
+ /*
+ * Number of bits in the history that we are going to update.
+ * We want one bit per 10mS. So, if we are not called late,
+ * update that many bits in history.
+ */
+ this_jiffies = jiffies;
+ num_bits = (this_jiffies/BM_CHECK_RATE) - (last_jiffies/BM_CHECK_RATE);
+
+ /*
+ * It should be enough if we do this check on one CPU.
+ * Do it only on current CPU for now.
+ */
+ acpi_bm_activity_update(smp_processor_id(), num_bits);
+
+ last_jiffies = this_jiffies;
+ schedule_delayed_work(&bm_check_work, BM_CHECK_RATE);
+}
+
+static void
+setup_periodic_bm_status_check(int opt)
+{
+ static int bm_status_check_count;
+
+ if (opt == BM_CHECK_START)
+ bm_status_check_count++;
+ else if (opt == BM_CHECK_STOP)
+ bm_status_check_count--;
+
+ if (bm_status_check_count == 1) {
+ INIT_WORK(&bm_check_work, do_bm_check_timer, NULL);
+ schedule_work(&bm_check_work);
+ } else if (bm_status_check_count == 0) {
+ cancel_delayed_work(&bm_check_work);
+ }
+ return;
+}
+
+
static void
acpi_processor_power_activate (
struct acpi_processor *pr,
@@ -188,27 +306,9 @@ static void acpi_processor_idle (void)
* for demotion.
*/
if (pr->flags.bm_check) {
- u32 bm_status = 0;
+ unsigned long bm_activity;
- pr->power.bm_activity <<= 1;
-
- acpi_get_register(ACPI_BITREG_BUS_MASTER_STATUS,
- &bm_status, ACPI_MTX_DO_NOT_LOCK);
- if (bm_status) {
- pr->power.bm_activity++;
- acpi_set_register(ACPI_BITREG_BUS_MASTER_STATUS,
- 1, ACPI_MTX_DO_NOT_LOCK);
- }
- /*
- * PIIX4 Erratum #18: Note that BM_STS doesn't always reflect
- * the true state of bus mastering activity; forcing us to
- * manually check the BMIDEA bit of each IDE channel.
- */
- else if (errata.piix4.bmisx) {
- if ((inb_p(errata.piix4.bmisx + 0x02) & 0x01)
- || (inb_p(errata.piix4.bmisx + 0x0A) & 0x01))
- pr->power.bm_activity++;
- }
+ bm_activity = pr->power.bm_activity | acpi_get_bm_status(0);
/*
* Apply bus mastering demotion policy. Automatically demote
* to avoid a faulty transition. Note that the processor
@@ -216,12 +316,12 @@ static void acpi_processor_idle (void)
* funciton) but should upon the next.
*
* TBD: A better policy might be to fallback to the demotion
- * state (use it for this quantum only) istead of
+ * state (use it for this quantum only) instead of
* demoting -- and rely on duration as our sole demotion
* qualification. This may, however, introduce DMA
* issues (e.g. floppy DMA transfer overrun/underrun).
*/
- if (pr->power.bm_activity & cx->demotion.threshold.bm) {
+ if (bm_activity & cx->demotion.threshold.bm) {
local_irq_enable();
next_state = cx->demotion.state;
goto end;
@@ -420,7 +520,7 @@ acpi_processor_set_power_policy (
cx->demotion.threshold.ticks = cx->latency_ticks;
cx->demotion.threshold.count = 1;
if (cx->type == ACPI_STATE_C3)
- cx->demotion.threshold.bm = 0x0F;
+ cx->demotion.threshold.bm = 0x07;
}
/* from C3 we always demote to C2, even if there are multiple
@@ -443,7 +543,7 @@ acpi_processor_set_power_policy (
else
cx->promotion.threshold.count = 10;
if (higher->type == ACPI_STATE_C3)
- cx->demotion.threshold.bm = 0x0F;
+ cx->demotion.threshold.bm = 0x07;
}
higher = cx;
@@ -710,6 +810,7 @@ static void acpi_processor_power_verify_
cx->valid = 1;
cx->latency_ticks = US_TO_PM_TIMER_TICKS(cx->latency);
pr->flags.bm_check = 1;
+ setup_periodic_bm_status_check(BM_CHECK_START);
return_VOID;
}
@@ -985,5 +1086,8 @@ int acpi_processor_power_exit(struct acp
synchronize_kernel();
}
+ if (pr->flags.bm_check == 1)
+ setup_periodic_bm_status_check(BM_CHECK_STOP);
+
return_VALUE(0);
}
-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://productguide.itmanagersjournal.com/
next prev parent reply other threads:[~2004-12-23 21:41 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-12-23 18:31 [PATCH 5/5] processor: jiffies-based bm_check, bugfixes Pallipadi, Venkatesh
[not found] ` <88056F38E9E48644A0F562A38C64FB6003A46B1D-exJ48ZlmiLpQxe9IK+vIArfspsVTdybXVpNB7YpNyf8@public.gmane.org>
2004-12-23 20:13 ` Dominik Brodowski
[not found] ` <20041223201334.GA19292-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>
2004-12-23 21:41 ` Venkatesh Pallipadi [this message]
[not found] ` <20041223134118.A24497-39QZ/XbsZ5/mO6KZMuUCQVaTQe2KTcn/@public.gmane.org>
2004-12-24 9:45 ` Dominik Brodowski
-- strict thread matches above, loose matches on Subject: below --
2004-12-23 14:08 Dominik Brodowski
[not found] ` <20041223140849.GE7973-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org>
2004-12-23 20:11 ` Len Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20041223134118.A24497@unix-os.sc.intel.com \
--to=venkatesh.pallipadi-ral2jqcrhueavxtiumwx3w@public.gmane.org \
--cc=acpi-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=len.brown-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=linux-X3ehHDuj6sIIGcDfoQAp7BvVK+yQ3ZXh@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox