Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 Feb 2019 11:37:45 +0200
From:      Konstantin Belousov <kostikbel@gmail.com>
To:        Austin Shafer <amshafer64@gmail.com>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: vm_page_t's do not appear initialized
Message-ID:  <20190219093745.GM2420@kib.kiev.ua>
In-Reply-To: <86lg2cz4pn.fsf@triplebuff.com>
References:  <86lg2cz4pn.fsf@triplebuff.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, Feb 19, 2019 at 01:12:52AM -0500, Austin Shafer wrote:
> Hi freebsd-hackers,
> 
> While trying to write a DRM buffer page fault handler, I've run into an
> issue where vm_page_t structs appear to be uninitialized and contain
> random data. Most of These "random" fields in the structures remain the
> same after rebooting, which makes me think that I have missed something
> and am misinterpreting the fields. After a little over a week reading
> through source code and trying different things, I wanted to see
> if anyone had any insight that could help me learn whats going on.
> 
> Thanks in advance!
> 
> (For context, here is the project this is from)
> https://github.com/aritger/eglstreams-kms-example/issues/7
> 
> 
> I have more verbose examples below, but some quick examples of what I'm
> seeing are:
>  - vm_page_t->phys_addr does not match expected
>  - vm_page_t->flags has values not in the PG_* macros
>    - same for busy_lock and other entries
>  - kgdb can't read memory at vm_page_t->object
>  - etc...
> 
> It looks like vm_page_init_page was not called on these vm_page_t's I am
> interacting with, but I can't seem to figure out why that would not be
> the case? I've also booted into single user mode so I can look at things
> before any graphics drivers can mess with them, but the pages still look
> the same. While writing the fault handler I've been using the i915kms
> driver's handler as a reference, and I've included page structs from an
> intel laptop as an example of what I expected to see.
> 
> _____________________________________________________________________
> Here is an example of a vm_page_t I get for the start of device memory
> on an NVIDIA 1070:
> _____________________________________________________________________
> 
> # uname -a
> FreeBSD wolfgang 12.0-RELEASE FreeBSD 12.0-RELEASE #5 r343025M: Sun Feb 10 14:29:01 EST 2019
> ashafer@wolfgang:/usr/obj/usr/src/amd64.amd64/sys/GENERIC  amd64
> ----------------
> pciconf -lbv:
> ...
> vgapci0@pci0:1:0:0:     class=0x030000 card=0x33011462 chip=0x1b8110de rev=0xa1 hdr=0x00
>     vendor     = 'NVIDIA Corporation'
>     device     = 'GP104 [GeForce GTX 1070]'
>     class      = display
>     subclass   = VGA
>     bar   [10] = type Memory, range 32, base 0xee000000, size 16777216, enabled
>     bar   [14] = type Prefetchable Memory, range 64, base 0xd0000000, size 268435456, enabled
>     bar   [1c] = type Prefetchable Memory, range 64, base 0xe0000000, size 33554432, enabled
>     bar   [24] = type I/O Port, range 32, base 0xe000, size 128, enabled
> ...
> ----------------
> 
> /* get the page corresponding device mem */
> vm_page_t page = PHYS_TO_VM_PAGE(0xd0000000) <--- page == 0xfffff802266a5980
> 
> ----------------
> (kgdb) p/x *(vm_page_t)0xfffff802266a5980
> $1 = {plinks = {q = {tqe_next = 0x2c43b579e62bf7ae, tqe_prev = 0xb47eac47a195af64}, s = {ss = {
>         sle_next = 0x2c43b579e62bf7ae}, pv = 0xb47eac47a195af64}, memguard = {
>       p = 0x2c43b579e62bf7ae, v = 0xb47eac47a195af64}}, listq = {
>     tqe_next = 0x6d4683b13bdc1486, tqe_prev = 0x3666c2179bcddb1d}, 
>   object = 0xff2e12d8cc36710b, pindex = 0xb5bd170e69b840a2, phys_addr = 0xaad51419a796c44d, 
>   md = {pv_list = {tqh_first = 0x38d208abcf6951ec, tqh_last = 0x850ca846e9f2d9f3}, 
>     pv_gen = 0xf277ff0c, pat_mode = 0x564e1542}, wire_count = 0xc810bbe0, 
>   busy_lock = 0x4ee4b98f, hold_count = 0xbcda, flags = 0x3f53, aflags = 0x37, oflags = 0x66, 
>   queue = 0xa, psind = 0xc1, segind = 0x23, order = 0xb7, pool = 0x12, act_count = 0x9c, 
>   valid = 0x22, dirty = 0x71}
> ----------------
> just in case this is related... I think vm_phys_segs drives which pages get
> initialized during system boot?
> ----------------
> (kgdb) p/x vm_phys_segs 
> $2 = {{start = 0x10000, end = 0x6f000, first_page = 0xfffff80443776000, domain = 0x0, 
>     free_queues = 0xffffffff82057670}, {start = 0x70000, end = 0x87000, 
>     first_page = 0xfffff80443778700, domain = 0x0, free_queues = 0xffffffff82057670}, {
>     start = 0x100000, end = 0x1000000, first_page = 0xfffff8044377c180, domain = 0x0, 
>     free_queues = 0xffffffff82057670}, {start = 0x1000000, end = 0x2c6b000, 
>     first_page = 0xfffff804437dd980, domain = 0x0, free_queues = 0xffffffff82057400}, {
>     start = 0x2c73000, end = 0x2cab000, first_page = 0xfffff80443896838, domain = 0x0, 
>     free_queues = 0xffffffff82057400}, {start = 0x2e00000, end = 0x96c80000, 
>     first_page = 0xfffff804438a0980, domain = 0x0, free_queues = 0xffffffff82057400}, {
>     start = 0x98083000, end = 0x9c68f000, first_page = 0xfffff80447538eb8, domain = 0x0, 
>     free_queues = 0xffffffff82057400}, {start = 0x9cfff000, end = 0x9d000000, 
>     first_page = 0xfffff8044773d918, domain = 0x0, free_queues = 0xffffffff82057400}, {
>     start = 0x100000000, end = 0x44360f000, first_page = 0xfffff80449f75980, domain = 0x0, 
>     free_queues = 0xffffffff82057400}, {start = 0x100000000, end = 0x44360f000, 
>     first_page = 0xfffff80449f75980, domain = 0x0, free_queues = 0xffffffff82057400}, {
>     start = 0x0, end = 0x0, first_page = 0x0, domain = 0x0, 
>     free_queues = 0x0} <repeats 53 times>}
> 
> _____________________________________________________________________
> EXPECTED: This is what the vm_page_t for device memory on a intel laptop
> (Different computer, this looks like what I should be getting)
> _____________________________________________________________________
> pciconf -lbv:
> ...
> vgapci0@pci0:0:2:0:     class=0x030000 card=0xfa121179 chip=0x04168086 rev=0x06 hdr=0x00
>     vendor     = 'Intel Corporation'
>     device     = '4th Gen Core Processor Integrated Graphics Controller'
>     class      = display
>     subclass   = VGA
>     bar   [10] = type Memory, range 64, base 0xb0000000, size 4194304, enabled
>     bar   [18] = type Prefetchable Memory, range 64, base 0xa0000000, size 268435456, enabled
>     bar   [20] = type I/O Port, range 32, base 0x4000, size 64, enabled
> ...
> ----------------
> vm_page_t page = PHYS_TO_VM_PAGE(0xa0000000) <--- page == 
> ----------------
> (kgdb) p/x *(vm_page_t)0xfffff80447875980
> $1 = {plinks = {q = {tqe_next = 0x0, tqe_prev = 0x0}, s = {ss = {sle_next = 0x0}, pv = 0x0}, 
>     memguard = {p = 0x0, v = 0x0}}, listq = {tqe_next = 0x0, tqe_prev = 0x0}, object = 0x0, 
>   pindex = 0x0, phys_addr = 0xa0000000, md = {pv_list = {tqh_first = 0x0, 
>       tqh_last = 0xfffff804478759b8}, pv_gen = 0x0, pat_mode = 0x1}, wire_count = 0x1, 
>   busy_lock = 0x1, hold_count = 0x0, flags = 0x4, aflags = 0x0, oflags = 0x0, queue = 0xff, 
>   psind = 0x0, segind = 0x0, order = 0x0, pool = 0x0, act_count = 0x0, valid = 0x0, 
>   dirty = 0x0}
> 
> _____________________________________________________________________
> 
> Again I'm not really sure what I'm running into. I've had to try to
> learn the FreeBSD vm system while working on this, so I'm sorry if I
> missed anything obvious to those who have more experience. I'm more than
> happy to provide any information or test anything and I'd appreciate any
> pointers to what can explain this.
> 
> Thank you so much for your time!
>       Austin Shafer
I do not know exactly what are you doing, but problems with
PHYS_TO_VM_PAGE() on the framebuffers pages usually indicate incorrect
(or missed) usage of the vm_phys_fictitious_reg_range() KPI.




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