riscv64: Move pcb out of kstack into a new UMA zone
Similar to arm64, riscv's pcb embeds a copy of the floating point registers and is too large to store directly in struct mdthread as is done on amd64. Instead, use a separate UMA zone for pcbs. riscv's floating point state is not as large as arm64's, so its pcb is also somewhat smaller and a single 4k page can hold 6 pcbs. Reviewed by: kib, jrtc27 Sponsored by: AFRL, DARPA Pull Request: https://ron-dev.freebsd.org/FreeBSD/src/pulls/23
This commit is contained in:
@@ -48,12 +48,10 @@ bool unwind_frame(struct thread *, struct unwind_state *);
|
||||
|
||||
#ifdef _SYS_PROC_H_
|
||||
|
||||
#include <machine/pcb.h>
|
||||
|
||||
/* Get the current kernel thread stack usage. */
|
||||
#define GET_STACK_USAGE(total, used) do { \
|
||||
struct thread *td = curthread; \
|
||||
(total) = ptoa(td->td_kstack_pages) - sizeof(struct pcb); \
|
||||
(total) = ptoa(td->td_kstack_pages); \
|
||||
(used) = td->td_kstack + (total) - (char *)&td; \
|
||||
} while (0)
|
||||
|
||||
@@ -61,7 +59,7 @@ static __inline bool
|
||||
kstack_contains(struct thread *td, vm_offset_t va, size_t len)
|
||||
{
|
||||
return (va >= (vm_offset_t)td->td_kstack && va + len >= va &&
|
||||
va + len <= (vm_offset_t)td_kstack_top(td) - sizeof(struct pcb));
|
||||
va + len <= (vm_offset_t)td_kstack_top(td));
|
||||
}
|
||||
#endif /* _SYS_PROC_H_ */
|
||||
|
||||
|
||||
@@ -63,7 +63,6 @@ ASSYM(PMAP_MAPDEV_EARLY_SIZE, PMAP_MAPDEV_EARLY_SIZE);
|
||||
ASSYM(PM_SATP, offsetof(struct pmap, pm_satp));
|
||||
|
||||
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
|
||||
ASSYM(PCB_SIZE, sizeof(struct pcb));
|
||||
ASSYM(PCB_RA, offsetof(struct pcb, pcb_ra));
|
||||
ASSYM(PCB_SP, offsetof(struct pcb, pcb_sp));
|
||||
ASSYM(PCB_GP, offsetof(struct pcb, pcb_gp));
|
||||
|
||||
@@ -241,8 +241,8 @@ va:
|
||||
/* Clear frame pointer */
|
||||
mv s0, zero
|
||||
|
||||
/* Allocate space for thread0 PCB and riscv_bootparams */
|
||||
addi sp, sp, -(PCB_SIZE + RISCV_BOOTPARAMS_SIZE) & ~STACKALIGNBYTES
|
||||
/* Allocate space for riscv_bootparams */
|
||||
addi sp, sp, -RISCV_BOOTPARAMS_SIZE & ~STACKALIGNBYTES
|
||||
|
||||
/* Clear BSS */
|
||||
la t0, _C_LABEL(__bss_start)
|
||||
|
||||
@@ -105,6 +105,7 @@
|
||||
struct pcpu __pcpu[MAXCPU];
|
||||
|
||||
static struct trapframe proc0_tf;
|
||||
static struct pcb pcb0;
|
||||
|
||||
int early_boot = 1;
|
||||
int cold = 1;
|
||||
@@ -296,7 +297,7 @@ init_proc0(void *kstack)
|
||||
proc_linkup0(&proc0, &thread0);
|
||||
thread0.td_kstack = kstack;
|
||||
thread0.td_kstack_pages = KSTACK_PAGES;
|
||||
thread0.td_pcb = (struct pcb *)td_kstack_top(&thread0) - 1;
|
||||
thread0.td_pcb = &pcb0;
|
||||
thread0.td_pcb->pcb_fpflags = 0;
|
||||
thread0.td_frame = &proc0_tf;
|
||||
pcpup->pc_curpcb = thread0.td_pcb;
|
||||
|
||||
@@ -32,8 +32,8 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/sf_buf.h>
|
||||
@@ -58,23 +58,23 @@
|
||||
#define TP_OFFSET 16 /* sizeof(struct tcb) */
|
||||
#endif
|
||||
|
||||
static uma_zone_t pcb_zone;
|
||||
|
||||
void
|
||||
cpu_thread_new_kstack(struct thread *td)
|
||||
{
|
||||
td->td_pcb = (struct pcb *)td_kstack_top(td) - 1;
|
||||
|
||||
/*
|
||||
* td->td_frame + TF_SIZE will be the saved kernel stack pointer whilst
|
||||
* in userspace, so keep it aligned so it's also aligned when we
|
||||
* subtract TF_SIZE in the trap handler (and here for the initial stack
|
||||
* pointer). This also keeps the struct kernframe just afterwards
|
||||
* aligned no matter what's in it or struct pcb.
|
||||
* aligned no matter what's in it.
|
||||
*
|
||||
* NB: TF_SIZE not sizeof(struct trapframe) as we need the rounded
|
||||
* value to match the trap handler.
|
||||
*/
|
||||
td->td_frame = (struct trapframe *)(STACKALIGN(
|
||||
(char *)td->td_pcb - sizeof(struct kernframe)) - TF_SIZE);
|
||||
td_kstack_top(td) - sizeof(struct kernframe)) - TF_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -227,11 +227,13 @@ cpu_thread_exit(struct thread *td)
|
||||
void
|
||||
cpu_thread_alloc(struct thread *td)
|
||||
{
|
||||
td->td_pcb = uma_zalloc(pcb_zone, M_WAITOK);
|
||||
}
|
||||
|
||||
void
|
||||
cpu_thread_free(struct thread *td)
|
||||
{
|
||||
uma_zfree(pcb_zone, td->td_pcb);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -285,3 +287,11 @@ cpu_sync_core(void)
|
||||
{
|
||||
fence_i();
|
||||
}
|
||||
|
||||
static void
|
||||
pcbinit(void *dummy __unused)
|
||||
{
|
||||
pcb_zone = uma_zcreate("pcb", sizeof(struct pcb), NULL, NULL, NULL,
|
||||
NULL, UMA_ALIGNOF(struct pcb), 0);
|
||||
}
|
||||
SYSINIT(pcbinit, SI_SUB_INTRINSIC, SI_ORDER_ANY, pcbinit, NULL);
|
||||
|
||||
Reference in New Issue
Block a user