Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 11 Dec 2018 02:54:36 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r341810 - in head/sys: kern x86/x86
Message-ID:  <201812110254.wBB2sa1P047791@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Tue Dec 11 02:54:36 2018
New Revision: 341810
URL: https://svnweb.freebsd.org/changeset/base/341810

Log:
  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

Modified:
  head/sys/kern/kern_thread.c
  head/sys/x86/x86/mp_x86.c

Modified: head/sys/kern/kern_thread.c
==============================================================================
--- head/sys/kern/kern_thread.c	Tue Dec 11 02:48:49 2018	(r341809)
+++ head/sys/kern/kern_thread.c	Tue Dec 11 02:54:36 2018	(r341810)
@@ -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();
 

Modified: head/sys/x86/x86/mp_x86.c
==============================================================================
--- head/sys/x86/x86/mp_x86.c	Tue Dec 11 02:48:49 2018	(r341809)
+++ head/sys/x86/x86/mp_x86.c	Tue Dec 11 02:54:36 2018	(r341810)
@@ -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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201812110254.wBB2sa1P047791>