#!/usr/sbin/dtrace -s #pragma D option flowindent /* See Mauro et. al p. 490--491 for the flow to this function. Note that we filter only page-outs of anon mappings; change the predicate to get only file-backed mappings. */ fbt::swap_putapage:entry / args[0]->v_path == 0 && args[0]->v_data == (void*)0xbaddcafebaddcafe / { printf("Anon swap_putpage: vnode %p page %p offset %p", arg0, arg1, *args[2]); printf("\tembed %d mapping %p pagenum %p flags %x", args[1]->p_embed, args[1]->p_mapping, args[1]->p_pagenum, args[4] /* 0x8400 i.e. B_ASYNC | B_FREE is the comment combination */ ); self->flag = 1; } fbt::swap_putapage:return { self->flag = 0; } /* Called in pvn_getdirty, through hat_pageunload, for pages removed from async requests queue by sw_getreq() ; see http://src.illumos.org/source/s?refs=swap_putapage&project=illumos-gate */ fbt::hati_pageunload:entry /self->flag/ { printf("page_unload: embed %d mapping %p pagenum %p", args[0]->p_embed, args[0]->p_mapping, args[0]->p_pagenum ); /* Now to print the name of the process and the virtual address in it where the page(s) being swapped-out belonged */ /* p_mapping may be NULL or hment rather than htable, unless p_embed is 1. See Mauro p. 635 for details. Since there's no if-then-else in D, we need to use the ternary operator ? : to only derefernce p_mapping when p_embed is set. */ printf(" vaddr %p proc %s", (args[0]->p_embed) ? ((htable_t*)(args[0]->p_mapping))->ht_vaddr : (uintptr_t)0xbadadd , /* Note: the types must match across : in the ternary! */ (args[0]->p_embed) ? ((htable_t*)(args[0]->p_mapping))->ht_hat->hat_as->a_proc->p_user.u_comm : "n/a" ) } fbt::hati_pageunload:return /self->flag/ {} fbt::page_add:entry /self->flag/ { printf("page_add: embed %d mapping %p pagenum %p", args[1]->p_embed, args[1]->p_mapping, args[1]->p_pagenum ); } fbt::page_add:return /self->flag/ {} /* Catch-all for stack display: fbt::: /self->flag/ {} */