Free bootstacks after AP startup.

Bootstacks are unused after APs executed sched_throw() in
init_secondary_tail() and started executing on proper idle thread
stack.  Add sysinit that detects that the idle thread for each CPU was
scheduled at least once, and free corresponding bootstack.

Slight addition of the code (~200 bytes) is compensated by the saving,
because even on typical small modern desktop CPU we leak 128K of
memory otherwise (4 pages x 8 threads).

Reviewed by:	jhb
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D18486
This commit is contained in:
Konstantin Belousov 2018-12-11 02:54:36 +00:00
parent eba8ab0e3e
commit 94dd54b9a2
2 changed files with 18 additions and 4 deletions

View File

@ -197,7 +197,7 @@ thread_ctor(void *mem, int size, void *arg, int flags)
td = (struct thread *)mem;
td->td_state = TDS_INACTIVE;
td->td_oncpu = NOCPU;
td->td_lastcpu = td->td_oncpu = NOCPU;
td->td_tid = tid_alloc();

View File

@ -1071,9 +1071,23 @@ init_secondary_tail(void)
/* NOTREACHED */
}
/*******************************************************************
* local functions and data
*/
static void
smp_after_idle_runnable(void *arg __unused)
{
struct thread *idle_td;
int cpu;
for (cpu = 1; cpu < mp_ncpus; cpu++) {
idle_td = pcpu_find(cpu)->pc_idlethread;
while (idle_td->td_lastcpu == NOCPU &&
idle_td->td_oncpu == NOCPU)
cpu_spinwait();
kmem_free((vm_offset_t)bootstacks[cpu], kstack_pages *
PAGE_SIZE);
}
}
SYSINIT(smp_after_idle_runnable, SI_SUB_SMP, SI_ORDER_ANY,
smp_after_idle_runnable, NULL);
/*
* We tell the I/O APIC code about all the CPUs we want to receive