page fault in sched_pin()

Julian Elischer julian at
Sat Sep 11 03:41:17 PDT 2004

Don Lewis wrote:
> I just cvsup'ed a few hours ago and I'm getting a page fault in
> sched_pin() early in the boot process.  It looks like a NULL pointer
> dereference.  I'm using SCHED_4BSD+PREEMPTION.
> It looks like the problem is that proc0_init() (which calls schedinit())
> needs to be called before kmeminit(), so that the thread0->td_sched is
> initialized before it is dereferenced in sched_pin().
> The SYSINIT for kmeminit() is SI_SUB_KMEM, which is defined as
> 0x1800000, while the SYSINIT for proc0_init() is SI_SUB_INTRINSIC, which
> is defined as 0x2200000.
> An alternative would be to make sched_pin() a no-op this early in the
> boot process.

Both are ok, but the answer we will do is to store teh pinned value directly
in the thread structure as it was originally.. that will be the "quick fix" that 
we are committing now, effectively puting things back as they were before.

I am not sure why this appeared to work on my system. My only thought is that
I wasn't booting off the kernel I thught I was booting off. There was a big
rush to get it in before scott changed the name..

Ultimatly there are a number of fixes,
The first one, that Peter suggested abou a month ago on reviewing some code,
is to allocate the td_sched structure along with the td structure, and use non 
indirect methods to access it. This requires that thread0 and ksegrp0 and proc0 
be actually declared in sched_4bsd.c and sched_ule.c so that the size of the
whole structure can be known at compile time.
(thus getting rid of the td->td_sched pointer completely).

The second would be to do as Seigo Tanimura suggested and make a separate
SYSINIT section for this stuff evenearlier than the kmeminit() SYSINIT.

The third is to decide that this value is not scheduler specific and
remove it from the scheduler inteface and make it part of the standard
proc interface (which is sort of what we are doing now to fix this).
The "correct" version of this would put the pin in the thread structure
but define the pinning actors in smp.h instead of sched.h as they would
no longer be part of the sched framework but instead part of the SMP
framework. (or in proc.h).  I have been planing on using peter's sugestion
all along as it makes all references to the td_sched structure faster
throughout the entire scheduler, but I didn't want o do it to start
with as it would hav emade the diff HUGE.

The belt  and suspenders answer is to do both what we are doing, AND to do what
peter suggested later.. so the patch that Scott just committed will get things 
fixed again, but A later set of patches will change the way that the td_sched
structure is allocated and accessed everywhere which willl actually be quicker,
AND the definition if the pinning operation will go into proc.h or smp.h
so as to not sugest that they are part of the scheduler framework.

Seigo's solution might also hold water as there might be an argument for
having a place in which all static setup should be done. before we start
fooling with kernel vm.

Having the pin functions do nothing early on is feasible but not good
as it would require some sort of test that would slow down operations
after we have booted.

> Copyright (c) 1992-2004 The FreeBSD Project.
> Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
>         The Regents of the University of California. All rights reserved.
> FreeBSD 6.0-CURRENT #241: Sat Sep 11 02:23:16 PDT 2004
>     dl at
> WARNING: WITNESS option enabled, expect reduced performance.
> kernel trap 12 with interrupts disabled
> Fatal trap 12: page fault while in kernel mode
> cpuid = 0; apic id = 00
> fault virtual address   = 0x30
> fault code              = supervisor write, page not present
> instruction pointer     = 0x8:0xc0620c47
> stack pointer           = 0x10:0xc0c21cc0
> frame pointer           = 0x10:0xc0c21cc0
> code segment            = base 0x0, limit 0xfffff, type 0x1b
>                         = DPL 0, pres 1, def32 1, gran 1
> processor eflags        = resume, IOPL = 0
> current process         = 0 ()
> [thread 0]
> Stopped at      sched_pin+0xf:  incl    0x30(%eax)
> db> tr
> sched_pin(c0c21cdc,c07a0edc,c1047828,bfeff000,c103a000) at sched_pin+0xf
> pmap_zero_page(c1047828,bfeff000,c103a000,c0c21cf4,c075f724) at pmap_zero_page+0x35
> pmap_growkernel(d6247000) at pmap_growkernel+0xf4
> vm_map_findspace(c103a000,bfeff000,14000000,c08d3c3c) at vm_map_findspace+0x118
> vm_map_find(c103a000,0,0,0,c08d3c3c,14000000,1,7,7,0) at vm_map_find+0x41
> kmem_suballoc(c103a000,c08d3c3c,c08d3c40,14000000,14000) at kmem_suballoc+0x36
> kmeminit(0,c1ec00,c1e000,0,c0440b85) at kmeminit+0xe5
> mi_startup() at mi_startup+0x96
> begin() at begin+0x2c
> db> 
> _______________________________________________
> freebsd-current at mailing list
> To unsubscribe, send any mail to "freebsd-current-unsubscribe at"

More information about the freebsd-current mailing list