phys_footprint_not_include_iokit_memory

I have created a demo app to help me research xnu memory theory.

I found when I create many opengl texture (about 1000+), the value of phys_footprint is just 24M, but the value of internal+compressed is 687M, and the value in xcode debug memory info is also 680M, I get the value of phys_footrpint from task_info interface


In xnu kernel source code, I have found the definition of phys_footprint:


phys_footprint
Physical footprint: This is the sum of:
+ (internal - alternate_accounting)
+ (internal_compressed - alternate_accounting_compressed)
+ iokit_mapped
+ purgeable_nonvolatile
+ purgeable_nonvolatile_compressed
+ page_table


so the value of phys_footprint must be larger than internal+compressed, but actually is not


I have found than IOMemoryDescriptor in XNU source code will direct call pmap_enter_options, and not bill the memory value to phys_footprint, there are some piece code of pmap_enter_options:


if (pmap != kernel_pmap) {
  pmap_ledger_credit(pmap, task_ledgers.phys_mem, PAGE_SIZE);

  if (is_internal) {

  pmap_ledger_credit(pmap, task_ledgers.internal, PAGE_SIZE);
  if (is_altacct) {
  /*
  * If this page is internal and
  * in an IOKit region, credit
  * the task's total count of
  * dirty, internal IOKit pages.
  * It should *not* count towards
  * the task's total physical
  * memory footprint, because
  * this entire region was
  * already billed to the task
  * at the time the mapping was
  * created.
  *
  * Put another way, this is
  * internal++ and
  * alternate_accounting++, so
  * net effect on phys_footprint
  * is 0. That means: don't
  * touch phys_footprint here.
  */
  pmap_ledger_credit(pmap, task_ledgers.alternate_accounting, PAGE_SIZE);
  } else {
  pmap_ledger_credit(pmap, task_ledgers.phys_footprint, PAGE_SIZE);
  }
  }
}


when other call vm_map_enter, vm_map_enter will call :


vm_map_iokit_mapped_region(vm_map_t map, vm_size_t bytes)
{
pmap_t pmap = vm_map_pmap(map);

ledger_credit(pmap->ledger, task_ledgers.iokit_mapped, bytes);
ledger_credit(pmap->ledger, task_ledgers.phys_footprint, bytes);
}


vm_map_iokit_mapped_region will bill the value to phys_footprint, but when IOKit module direct call pmap_enter_options, the memory are not billed to phys_footprint, I think there maybe some bug in phys_footprint statistics, This bug may affect jetsam kill app algorithm