Viewing: page.py
"""
Constants and routines for manipulating kernel page struct.
Copyright 2014-2017 Cray Inc. All Rights Reserved
"""
from pykdump.API import *
import crashlib.cid
import crashlib.cid.machdep_table
import crashlib.cid.page_flags
import crashlib.cid.phys_mem_map
# --------------------------------------------------------------------------
page_struct_size = getSizeOf('struct page')
# --------------------------------------------------------------------------
# Create a function for determining whether a page is controlled by the
# buddy allocator. Note that earlier kernels (< 3.0) have a page flag, while
# later kernels use the _mapcount field.
if hasattr(crashlib.cid.pgflags, 'PG_buddy'):
def is_buddy_page(page):
return page.flags & crashlib.cid.pgflags.PG_buddy.mask;
else:
def is_buddy_page(page):
# Early implementations used -2, later use -128
return page._mapcount.counter == -128 or page._mapcount.counter == -2
if hasattr(crashlib.cid.pgflags, 'PG_compound'):
def is_compound_page_head(page):
return (page.flags & (crashlib.cid.pgflags.PG_reclaim.mask |
crashlib.cid.pgflags.PG_compound.mask)
) == crashlib.cid.pgflags.PG_compound
def is_compound_page_tail(page):
return (page.flags & (crashlib.cid.pgflags.PG_reclaim.mask |
crashlib.cid.pgflags.PG_compound.mask)
) == (crashlib.cid.pgflags.PG_reclaim.mask |
crashlib.cid.pgflags.PG_compound.mask)
def is_compound_page(page):
return page.flags & crashlib.cid.pgflags.PG_compound.mask
elif hasattr(crashlib.cid.pgflags, 'PG_tail'):
# PG_head and PG_tail defined
def is_compound_page_head(page):
return page.flags & (crashlib.cid.pgflags.PG_head.mask)
def is_compound_page_tail(page):
return page.flags & (crashlib.cid.pgflags.PG_tail.mask)
def is_compound_page(page):
return is_compound_page_head(page) or is_compound_page_tail(page)
else:
# Only PG_head is defined
def is_compound_page_head(page):
return page.flags & (crashlib.cid.pgflags.PG_head.mask)
def is_compound_page_tail(page):
return page.compound_head & 1
def is_compound_page(page):
return is_compound_page_head(page) or is_compound_page_tail(page)
# --------------------------------------------------------------------------
# Find the page order of a buddy page
def buddy_order(page):
"""Retrieve the order of a page in the buddy allocator"""
return page.private
# --------------------------------------------------------------------------
# Create a function to determine the page order of a compound page
if member_offset('struct page', 'compound_order') > -1:
def compound_order(page):
"""Retrieve the page order for a compound page."""
# A compound page is a series of contiguous pages, thus there are
# at least two page structs. The second page struct (first tail page)
# contains the page order; the head page uses the space for a
# different purpose.
return page[1].compound_order
else:
def compound_order(page):
"""Retrieve the page order for a compound page."""
# A compound page is a series of contiguous pages, thus there are
# at least two page structs. The second page struct (first tail page)
# contains the page order stored in the lru.prev field; the head page
# uses the space for a different purpose.
return page[1].lru.prev
# --------------------------------------------------------------------------
def pfn(page):
"""Returns the pfn for the supplied page struct or page struct address."""
vmemmap_vaddr = crashlib.cid.mdtbl.vmemmap_vaddr
return (page - vmemmap_vaddr) / page_struct_size
# --------------------------------------------------------------------------