Date: Sun, 08 Jul 2012 13:22:49 +0300 From: Andriy Gapon <avg@FreeBSD.org> To: "freebsd-acpi@freebsd.org" <freebsd-acpi@FreeBSD.org> Cc: Vitaly Magerya <vmagerya@gmail.com>, John Baldwin <jhb@FreeBSD.org>, Giovanni Trematerra <gianni@FreeBSD.org> Subject: improve cx_lowest logic Message-ID: <4FF95F79.30309@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
I would like to propose the following change for review and testing: http://people.freebsd.org/~avg/acpi_cpu_cx_lowest.diff The idea is to separate effective cx_lowest (the limit that the idling code should not currently exceed) from user-set cx_lowest limit/target. Specifically, this addresses dynamic C-state changes by ACPI platform. Currently if a user sets cx_lowest to, say, C3, then available C-states change so that C2 is the deepest available C-state and cx_lowest gets overridden to C2 and all memory of C3 setting is lost. Also, there is a problem with asynchronous nature of userland notification about power profile change and kernel notifications of _CST changes for each CPU in SMP system. That required work-arounds like one in r209213 which also introduced quite a bit of confusion about how per-CPU cpu_cx_lowest, global cpu_cx_lowest and dynamic C-state changes interact with each other. To this day I can not unwind the complete logic behind the following lines: if (sc->cpu_cx_lowest < cpu_cx_lowest) acpi_cpu_set_cx_lowest(sc, min(cpu_cx_lowest, sc->cpu_cx_count - 1)); So to avoid the problems described above I decided to split the cx_lowest limit into the persistent user-set limit, cpu_cx_lowest_lim, and dynamic effective limit. The logic to set cpu_cx_lowest based on cpu_cx_lowest_lim and cpu_cx_count is moved to acpi_cpu_set_cx_lowest(). Note that per-CPU cpu_cx_lowest_lim does not "interact" with global cpu_cx_lowest_lim. Whichever is set later (via sysctl) just overrides the other. With such a change it no longer makes sense to limit allowed cx_lowest sysctl values to currently available C-state levels. Indeed, if a user knows that his system may provide C6 under some circumstance, but currently only C1 is available, then there is no reason to disallow setting cx_lowest sysctl (cpu_cx_lowest_lim) to C6. So values up to MAX_CX_STATES are allowed. After this change cpu_cx_count _global_ variable became unused (write-only) and was removed. Additionally, I introduced magic value of "Cmax" for cx_lowest sysctls to mean that there should not be any limit on C-state depth. The change is partially based on submission from Vitaly: http://article.gmane.org/gmane.os.freebsd.devel.acpi/6892 -- Andriy Gapon
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4FF95F79.30309>