Bug 119356

Summary: [acpi]: i386 ACPI wakeup not work due resource exhaustion
Product: Base System Reporter: Dan Lukes <dan>
Component: kernAssignee: freebsd-acpi (Nobody) <acpi>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 6.3-PRERELEASE   
Hardware: Any   
OS: Any   
Attachments:
Description Flags
file.diff none

Description Dan Lukes 2008-01-05 11:50:01 UTC
	acpi module register acpi_alloc_wakeup_handler() routine to be run
during startup.

	The routine shall alloc one page of physical memory in the 
address range of 0-9FFFFh (to be avaiable in CPU's real mode)

	Unfortunately, the routine is called to late during initialization
sequence, so all potential pages may be allocated already

	The routine is registered with SI_SUB_KMEM/SI_ORDER_ANY priority, 
but it's part of loadable modules. All modules initialization routines 
are deferred until preload_linker(), so the effective priority of
acpi_alloc_wakeup_handler() is worse than SI_SUB_KLD despite of declared priority.

	On my system, there are 158 pages in the range 0-9FFFFh. After VM 
initialization 155 of them are free. 
kmeminit() eat 70 of them, 38 pages disapear during several invocations of
malloc_init(), the scmeminit() grab latest 47 pages. 

	After scmeminit() all pages in the range 0-9FFFh are on PQ_NONE
queue and are not avaiable for further allocation.

	It's long time before the acpi's acpi_alloc_wakeup_handler() invoked.

	At the time of invocation, no required pages are avaiable so
acpi_alloc_wakeup_handler() fail. As a result, no machinde-dependent wake-up
routine can be installed. It broke the system wakeup.

	The problem occur on i386 architecture only.

Fix: The best fix is to rewrite system initialization scheduler within
mi_startup() 

	The routines shall be invoked according declared priority despite
they are compiled-in or part of preloaded module.

	Unfortunately it require reengineering of preload_linker()
and other linker related code.

	I can't do it.

	Worse, but still good, we can rewrite the physical memory management
to save the 0-9FFFFh pages as long as possible. Currently they are exhausted
despite other high-address pages are still avaiable.

	Unfortunately I have insuficient knowledge of memory allocator, so
I can't supply patch this way.

	I can supply the hack. Yes, it is hack, but IMHO acceptable hack. The
acpi_alloc_wakeup_handler() needs to be moved out of module into statically
compiled code. The routine in the compiled-in code will be invoked according 
declared priority. 

	Routine on it's original place initialise three static variables
acpi_waketag/acpi_wakemap/acpi_wakeaddr which is used by other ACPI's routines.

	Moved routine declare the same variables as global, so they are
avaiable to acpi module as well. Variables declared inside of ACPI module 
needs to be changed to external.

	No other modification needed.

	The hack has disadvantage. At the time of moved
acpi_alloc_wakeup_handler() invocation the system doesn't know the ACPI module
is preloaded or not. So page may be allocated even acpi not present.

	We can try to determine the ACPI will be loaded later or we can create
the hook invoked after the module initialisation which free the page if acpi
not present. 

	I give up on it. It's hack. The one wasted page is the price for it.

	Without a fix the wake won't work correctly.

	I decide to move the routine into sys/i386/i386/vm_machdep.c

	There are may be better place.
Comment 1 Remko Lodder freebsd_committer freebsd_triage 2008-01-07 08:24:04 UTC
Responsible Changed
From-To: freebsd-i386->freebsd-acpi

Reassign to acpi team
Comment 2 Dan Lukes 2008-02-11 15:34:46 UTC
See also kern/120515
Comment 3 John Baldwin freebsd_committer freebsd_triage 2010-06-02 14:08:50 UTC
Can you verify that this issue is fixed in 7.2 or a newer release?

-- 
John Baldwin
Comment 4 Andriy Gapon freebsd_committer freebsd_triage 2010-12-05 14:51:06 UTC
State Changed
From-To: open->feedback

Feedback has been requested a while ago. 
Submitter, please clarify the status.
Comment 5 Jaakko Heinonen freebsd_committer freebsd_triage 2011-11-27 11:25:18 UTC
State Changed
From-To: feedback->closed

Feedback timeout.